gpt4 book ai didi

linux - 如何验证原子写入?

转载 作者:IT王子 更新时间:2023-10-29 01:19:39 27 4
gpt4 key购买 nike

我认真搜索(在 S[O|F|U] 网络和其他地方)并认为这是一个不常见的问题。我正在使用运行 Debian Linux 2.6.28-4 的 Atmel AT91SAM9263-EK 开发板(ARM926EJ-S 内核,ARMv5 指令集)。我正在使用(我相信)tty 驱动程序与 RS-485 serial controller 交谈.我需要确保写入和读取是原子的。几行源代码(在本文末尾相对于内核源安装目录列出)暗示或暗示了这一点。

有什么方法可以验证向/从这个设备写入/读取实际上是一个原子操作吗?或者,/dev/ttyXX 设备是否被视为 FIFO 并且争论到此结束?仅仅相信代码正在执行它所做的声明似乎还不够——就在今年 2 月,freebsd 是 demonstrated to lack atomic writes for small lines .是的,我意识到 freebsd 与 Linux 并不完全相同,但我的观点是仔细确定并没有什么坏处。我所能想到的就是继续发送数据并寻找排列——我希望得到一些更科学的东西,理想情况下,是确定性的。不幸的是,我完全不记得以前大学时代的并发编程课。我会非常感激在正确的方向上的一记耳光或插入。如果您选择回复,请提前致谢。

亲切的问候,

杰斯


drivers/char/tty_io.c:1087

void tty_write_message(struct tty_struct *tty, char *msg)
{
lock_kernel();
if (tty) {
mutex_lock(&tty->atomic_write_lock);
if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags))
tty->ops->write(tty, msg, strlen(msg));
tty_write_unlock(tty);
}
unlock_kernel();
return;
}


arch/arm/include/asm/bitops.h:37

static inline void ____atomic_set_bit(unsigned int bit, volatile unsigned long *p)
{
unsigned long flags;
unsigned long mask = 1UL << (bit & 31);

p += bit >> 5;

raw_local_irq_save(flags);
*p |= mask;
raw_local_irq_restore(flags);
}


驱动程序/串行/serial_core.c:2376

static int
uart_write(struct tty_struct *tty, const unsigned char *buf, int count)
{
struct uart_state *state = tty->driver_data;
struct uart_port *port;
struct circ_buf *circ;
unsigned long flags;
int c, ret = 0;

/*
* This means you called this function _after_ the port was
* closed. No cookie for you.
*/
if (!state || !state->info) {
WARN_ON(1);
return -EL3HLT;
}

port = state->port;
circ = &state->info->xmit;

if (!circ->buf)
return 0;

spin_lock_irqsave(&port->lock, flags);
while (1) {
c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
if (count < c)
c = count;
if (c <= 0)
break;
memcpy(circ->buf + circ->head, buf, c);
circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
buf += c;
count -= c;
ret += c;
}
spin_unlock_irqrestore(&port->lock, flags);

uart_start(tty);
return ret;
}

此外,来自 man write(3) 文档:

An attempt to write to a pipe or FIFO has several major characteristics:

  • Atomic/non-atomic: A write is atomic if the whole amount written in one operation is not interleaved with data from any other process. This is useful when there are multiple writers sending data to a single reader. Applications need to know how large a write request can be expected to be performed atomically. This maximum is called {PIPE_BUF}. This volume of IEEE Std 1003.1-2001 does not say whether write requests for more than {PIPE_BUF} bytes are atomic, but requires that writes of {PIPE_BUF} or fewer bytes shall be atomic.

最佳答案

我认为,从技术上讲,设备不是 FIFO,因此根本不清楚您引用的保证是否适用。

您是否担心一个进程中的部分写入和读取,或者您实际上是从不同的进程读取和/或写入同一设备?假设是后者,您最好实现某种代理进程。代理独占设备并执行所有读写操作,从而完全避免了多进程原子性问题。

简而言之,我建议不要尝试验证“从该设备读取/写入实际上是一个原子操作”。如果 linux 的更高版本(或完全不同的 o/s)无法按照您需要的方式实现原子性,这将很难自信地完成,并且您的应用程序会出现细微的故障。

关于linux - 如何验证原子写入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1970832/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com