boostorg / lockfree

Boost.Lockfree
126 stars 86 forks source link

a new lock-free queue #79

Open inie0722 opened 2 years ago

inie0722 commented 2 years ago

In theory, it is a queue without waiting, which supports multi-threaded reading and writing. Of course, the disadvantage is that the order of entering the queue may not be strongly ordered.

template<typename T, size_t N>
class queue
{
private:
    ring_buffer<T, N> value_;

    ring_buffer<atomic<size_t>, N> readable_flag_{0};
    ring_buffer<atomic<size_t>, N> writable_flag_{0};

    atomic<size_t> writable_limit_;
    atomic<size_t> readable_limit_;
public:
    queue() = default;
    ~queue() = default;

    void push(const T & val)
    {
        size_t index = writable_limit_.fetch_add(1);

        while (writable_flag_[index] != index / max_size())
            ;

        value_[index] = val;
        readable_flag_[index] = (index / max_size()) + 1;
    }

    void pop(T&val)
    {
        size_t index = readable_limit_.fetch_add(1);

        while(readable_flag_[index] != (index / max_size()) + 1)
            ;

        val = value_[index];
        writable_flag_[index] = (index / max_size()) + 1;
    }

    size_t max_size() const
    {
        return N;
    }

    size_t size() const
    {
        size_t writable_limit = writable_limit_;
        size_t readable_limit = readable_limit_;

        return writable_limit > readable_limit ? writable_limit - readable_limit : 0;
    }
};
inie0722 commented 2 years ago

c language implementation mpmc_queue.h mpmc_queue.c