Let us consider the following one-reader/one-writer queue implemented with a linked list.
struct queue {
queue() {
tail = head = &reserved;
n = 0;
}
void push(item *it) {
tail->next = it;
tail = it;
n++;
}
item* pop() {
while (n == used);
++used;
head = head->next;
return head;
}
item reserved;
item *tail, *head;
int used = 0;
std::atomic <int> n;
}
Now I find that using volatile int n
could make my writer run faster, while I'm not sure whether it guarantees that head = head->next
can always read the correct value.
UPDATED: What if adding an atomic operation between tail->next
, n++
, i.e.,
void push(item *it) {
tail->next = it;
tail = it;
a.store(0, std::memory_order_release);
a.load(std::memory_order_acquire);
n++;
}
in which a
is never accessed by the reader? Will this guarantees the order of tail->next = it
and head = head->next
? (Still, it runs faster than using atomic n
)