bounded lock free mcsc queue read invalid value

27 Views Asked by At

multi threads call push(1), single thread call pop, why pop return true, but out value is 0?

  1. ingore queue size, push(1) times is less than queue SIZE
  2. already add memory fence, between store data and move prod_tail(x86 need or not?)
  3. 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?

0

There are 0 best solutions below