Lock free queue from Concurrency in Practice

109 Views Asked by At
  • In the push method why do we have old_tail->data.swap(new_data); #5 ? Where am i wrong?
  • Shouldn't it be p->data.swap(new_data) or p->data=new_data ?
  • Why are we swapping the new value with old_tail's data ?
void push(T new_value)
{
    std::shared_ptr<T> new_data(std::make_shared<T>(new_value));
    node* p=new node;                             #3
    node* const old_tail=tail.load();             #4
    old_tail->data.swap(new_data);                #5
    old_tail->next=p;                             #6
    tail.store(p);                                #7
}
  • Listing 7.14 A single-producer, single-consumer lock-free queue
template<typename T>
class lock_free_queue
{
private:
    struct node
    {
        std::shared_ptr<T> data;
        node* next;
        node():
            next(nullptr)
        {}
    };
    std::atomic<node*> head;
    std::atomic<node*> tail;
    node* pop_head()
    {
        node* const old_head=head.load();
        if(old_head==tail.load())         #1
        {
            return nullptr;
        }
        head.store(old_head->next);
        return old_head;
    }
public:
    lock_free_queue():
        head(new node),tail(head.load())
    {}
    lock_free_queue(const lock_free_queue& other)=delete;
    lock_free_queue& operator=(const lock_free_queue& other)=delete;
    ~lock_free_queue()
    {
        while(node* const old_head=head.load())
        {
            head.store(old_head->next);
            delete old_head;
        }
    }
    std::shared_ptr<T> pop()
    {
        node* old_head=pop_head();
        if(!old_head)
        {
            return std::shared_ptr<T>();
        }
        std::shared_ptr<T> const res(old_head->data);    #2
        delete old_head;
        return res;
    }
    void push(T new_value)
    {
        std::shared_ptr<T> new_data(std::make_shared<T>(new_value));
        node* p=new node;                             #3
        node* const old_tail=tail.load();             #4
        old_tail->data.swap(new_data);                #5
        old_tail->next=p;                             #6
        tail.store(p);                                #7
    }
};

0

There are 0 best solutions below