multi threads call push(1), single thread call pop, why pop return true, but out value is 0?
- ingore queue size, push(1) times is less than queue SIZE
- already add memory fence, between store data and move prod_tail(x86 need or not?)
- memory fence replace with __sync_synchronize() or _mm_mfence() also don't work.
template <typename T, int SIZE = 1024>
class MPSCQueue {
public:
std::atomic<int64_t> prod_tail, prod_head;
int64_t cons_tail;
T data[SIZE] = {0};
public:
MPSCQueue() : prod_tail(0), prod_head(0), cons_tail(0) {}
void Push(T v) {
int64_t local_prod_head, local_prod_next;
// move prod_head
while (true) {
local_prod_head = prod_head.load();
local_prod_next = local_prod_head + 1;
if (prod_head.compare_exchange_weak(local_prod_head, local_prod_next))
break;
}
// store data
data[local_prod_head % SIZE] = v;
// memory fence
std::atomic_thread_fence(std::memory_order_seq_cst);
// move prod_tail
while (true) {
if (prod_tail.compare_exchange_weak(local_prod_head, local_prod_next))
break;
}
}
bool Pop(T &out) {
if (cons_tail >= prod_tail.load())
return false;
out = data[cons_tail % SIZE];
cons_tail += 1;
return true;
}
};
why? how to fix it?