Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Ужасно, как можно на такой элементарный вопрос написать столько текста.
Ну и
Ну и напоследок — как выделить младший бит числа (не знаю, зачем это может потребоваться, но вдруг пригодится)
define LowerBit(N) ((((N) — 1) ^ (N)) & (N)).
А то что у вас — это не младший бит, а младший единичный бит.
Ну и напоследок — как выделить младший бит числа (не знаю, зачем это может потребоваться, но вдруг пригодится)
define LowerBit(N) ((((N) — 1) ^ (N)) & (N)).
#define LowerBit(N) (-(N) & (N))Пока вы занимались всеми этими микрооптимизациями, вы пропустили критическую ошибку из-за которой потребитель будет периодически читать мусор из очереди. Всё дело в том, процессор волен (и будет) переставлять независимые операции как угодно, а про эту зависимость он без барьеров памяти никак не сможет узнать:
Также отметим, что мы сначала заносим очередной элемент в очередь, и только потом сообщаем об этом продвижением индекса, обратный порядок мог бы привести к весьма неприятным последствиям.
Так что правильное смещение индекса должно выглядеть как-то так: https://github.com/nin-jin/go.d/blob/lock-free/source/jin/go.d#L261
Данное поведение переменной можно реализовать при помощи следующей конструкции:
volatile int Counter = 0; Counter = (++Counter) % (Max+1);
и именно такой код мы можем видеть в множестве (то есть весьма часто) случаев. Что тут неправильного
например, ссылочная очередь
К вопросу о буферах (кольцевых)