2009-12-28 5 views
4

Я усердно искал (как в сети 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} или меньше байтов были атомарными.
+0

У вас может быть лучший ответ, если вы положите «Вопрос» наверху (сводка сортировок). –

+0

Я сделал это изменение, спасибо за подсказку. -Jayce – user239719

+0

Похоже, что вы действительно хотите, это тест на стресс для водителей, чтобы проверить правильность. Похоже, это было бы в целом полезно повсюду. – Omnifarious

ответ

3

Я думаю, что технически устройства не FIFOs, так что это не совсем понятно, что гарантии вы цитируете должны применяться.

Вы обеспокоены тем, что частично пишет и читает в процессе, или вы действительно читаете и/или записываете одно и то же устройство из разных процессов? Предполагая последнее, вам может быть лучше реализовать какой-либо прокси-процесс.Прокси владеет устройством исключительно и выполняет все чтения и записи, тем самым полностью исключая проблему многоточечной атомарности.

Короче говоря, я советую не пытаться проверить, что «чтение/запись с этого устройства на самом деле является атомной операцией». Это будет трудно сделать с уверенностью и оставить вас с приложением, которое подвержено тонким сбоям, если более поздняя версия Linux (или вообще o/s вообще) не сможет реализовать атомарность так, как вам нужно.

+0

+1. Попытка вывести гарантии API, прочитав исходный код или протестировав стресс-тесты против текущей версии, звучит как ошибка. –

+0

@Dale, Спасибо за ваш ответ. В ответ на ваш вопрос есть только один процесс чтения/записи, но мне нужно убедиться, что чтение/запись происходит без прерывания. Иными словами, прерывания, прерывания, все, что может мешать, приостанавливается на время операции записи или чтения. Я считаю, что сумма перевода тривиально мала, 16 бит или пару факторов, близких к 2. Я опасаюсь реализовать свой собственный процесс для арбитражных транзакций, потому что я буду добавлять что-то, у которого, вероятно, есть ошибки для чего-то, что может иметь ошибки. Еще раз спасибо за вашу помощь. – user239719

+0

@Jason Спасибо за ваш ответ. Что вы предлагаете в этом случае? – user239719

2

Думаю, PIPE_BUF это правильно. Теперь записи размером менее PIPE_BUF байтов не могут быть атомарными, но если они не являются ошибкой ОС. Полагаю, вы могли бы спросить здесь, есть ли у ОС известные ошибки. Но на самом деле, если у него есть такая ошибка, это просто нужно немедленно исправить.

Если вы хотите написать более, чем PIPE_BUF атомарно, я думаю, вам не повезло. Я не думаю, что есть какой-то способ помимо координации и сотрудничества приложений, чтобы убедиться, что записи больших размеров происходят атомарно.

Одно из решений этой проблемы - поставить свой собственный процесс перед устройством и убедиться, что все, кто хочет писать на устройство, свяжутся с процессом и отправляют ему данные. Тогда вы можете делать все, что имеет смысл для вашего приложения с точки зрения гарантии атомарности.

+0

@Omnifarious, спасибо за ваш ответ. Я проверил определение для PIPE_BUF, похоже, что я значительно ниже порога с моими структурами данных. Я согласен с вами в том, что я в основном задаю вопрос об известных ошибках. Я также удивляюсь тому, что я использую устройство. Мне легче доверять полноте кода для настольной дистрибуции, которую могут использовать миллионы людей, чем те же, на нестандартном оборудовании с крошечным настроенным ядром, используемым всего несколькими людьми. Еще раз спасибо за вашу помощь, я ценю это. – user239719

+0

Обратите внимание, что 'PIPE_BUF' существенно отличается между системами Unix. См. Здесь обзор наблюдаемых значений: http://ar.to/notes/posix#pipe-buf –

Смежные вопросы