Цитата(Rst7 @ Jun 18 2008, 15:02)

>> if ((U8)(buf.in + 1) != buf.out) buf.data [buf.in++] = c;
Да, такая конструкция работает. По причине атомарности добавления. А вот аналогиная передача - - работать не будет.
Это еще почему?! Еще как будет работать. По причине того что in++ делается уже после того как байт добавлен в очередь.
Предположим передатчик прервал фоновую задачу в любой момент выполнения
if ((U8)(buf.in + 1) != buf.out) buf.data [buf.in++] = c;
Если индекс "in" соответвует разрядности процессора, и будет записан в память одной командой ST тогда будем иметь только три возможные комбинации в обработчике прерывания:
buf.in == buf.out нет новых данных (ничего не отправлено)
buf.in == buf.out есть новые данные (ничего не отправлено, т.к. индексы говорят об отсутсвии данных)
buf.in != buf.out есть новые данные (берем сколько можно пока out != in)
Все комбинации безопасны.
Ранее чем изменится индекс in, передатчик не сможет определить, что байт был добавлен в буфер, соответвенно ничего лишнего или частично положенного не вытянет.
Для работоспособности этой конструкции необходимо
- чтобы данные шли всегда из одного и того же источника (задачи)
- забирались всегда одним и тем же адресатом (задачей)
(источник и адресат - могут быть разными задачами)
и достаточно атомарности обновления индекса (запись одной командой ST), т.е. индекс не может быть большей разрядности чем разрядность регистров процессора. Все остальное не важно.