Я усердно искал (как в сети S [O | F | U], так и в другом месте) и считаю это необычным вопросом. Я работаю с платой разработки Atmel AT91SAM9263-EK (ядром ARM926EJ-S, набором инструкций ARMv5), работающим под управлением Debian Linux 2.6.28-4. Я пишу, используя (я считаю), драйвер tty, чтобы поговорить с RS-485 serial controller. Мне нужно, чтобы записи и чтения были атомарными. Несколько строк исходного кода (перечисленных ниже конца этого сообщения относительно исходного каталога установки ядра) либо подразумевают, либо неявно определяют это.Как проверить атомные записи?
Есть ли способ проверить, что запись/чтение этого устройства на самом деле является атомной операцией? Или, устройство/dev/ttyXX считается FIFO, и аргумент заканчивается там? Кажется недостаточным просто уповать на то, что код выполняет эту претензию, которую он делает - еще в феврале этого года freebsd был demonstrated to lack atomic writes for small lines. Да, я понимаю, что freebsd не совсем то же самое, что и Linux, но я хочу сказать, что это не помешает быть осторожным. Все, о чем я могу думать, это продолжать отправлять данные и искать перестановку - я надеялся на что-то более научное и, в идеале, детерминированное. К сожалению, я ничего точно не помню из своих параллельных классов программирования в дни колледжа. Я бы по достоинству оценил пощечину или толчок в правильном направлении. Заранее спасибо, если вы решите ответить.
С наилучшими пожеланиями,
Jayce
водителей/символ/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;
}
арка/рука/включить/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;
}
Кроме того, от человека записи (3) документация:
Попытка записи в канал или FIFO имеет несколько основных характеристик:
- Атомные/неаторальные: запись является атомарным, если вся сумма, записанная в одной операции, не чередуется с данными из любого другого процесса. Это полезно, когда несколько авторов отправляют данные одному читателю. Приложения должны знать, как большой запрос на запись можно ожидать атомарно. Этот максимум называется {PIPE_BUF}. В этом томе IEEE Std 1003.1-2001 не указано, являются ли запросы на запись более чем для {PIPE_BUF} байтов атомарными, но требует, чтобы записи из {PIPE_BUF} или меньше байтов были атомарными.
У вас может быть лучший ответ, если вы положите «Вопрос» наверху (сводка сортировок). –
Я сделал это изменение, спасибо за подсказку. -Jayce – user239719
Похоже, что вы действительно хотите, это тест на стресс для водителей, чтобы проверить правильность. Похоже, это было бы в целом полезно повсюду. – Omnifarious