Перемещение хвоста, когда Гонщик заполнен, ничего не дает. Продвижение головы, когда Гонщик набрал полный блок, пока хвост также не будет выдвинут вперед.
Или, по крайней мере, это цель. На самом деле программа обнаруживает нарушение инварианта вскоре после запуска. В частности, когда голова блокируется, а затем разблокируется при движении хвоста, Гонщик каким-то образом не видит изменений ни в положении головы, ни в положении хвоста.
Код: Выделить всё
#include
#include
#include
#include
template
struct Racer {
std::atomic head{0};
std::atomic tail{0};
std::atomic update_counter{0};
bool try_advance_tail() {
int h = head; // seq_cst load
int t = tail; // seq_cst load
int next = (t + 1) % Size;
if (next == h) return false; // full
tail = next; // seq_cst store
// Publish change and notify.
update_counter.fetch_add(1, std::memory_order_release);
update_counter.notify_one();
return true;
}
void try_advance_head() {
unsigned long long old_ctr = update_counter; // seq_cst load
int orig_h = head;
int orig_t = tail;
bool orig_empty = (orig_h == orig_t);
if (orig_empty) {
// Wait until counter changes, acquire on read.
update_counter.wait(old_ctr, std::memory_order_acquire);
}
unsigned long long new_ctr = update_counter; // seq_cst load
int new_h = head; // seq_cst
int new_t = tail; // seq_cst
bool new_empty = (new_h == new_t);
if (orig_empty && new_ctr != old_ctr && new_empty) {
std::cerr
Подробнее здесь: [url]https://stackoverflow.com/questions/79838618/misbehaving-circular-ring-buffer-using-stdatomic[/url]
Мобильная версия