码迷,mamicode.com
首页 > 其他好文 > 详细

使用引用计数方法管理内存的无锁栈 I

时间:2015-09-30 10:58:05      阅读:165      评论:0      收藏:0      [点我收藏+]

标签:

template<typename T>
class LockFreeStack
{
private:
    struct Node
    {
        std::shared_ptr<T> data;
        Node*              next;
        Node(T const& value):
            data(std::make_shared<T>(value))
        {}
    };
    
    std::atomic<Node*>  head;
    std::atomic<size_t> threadsInPopCount;
    std::atomic<Node*>  toBeDeletedChainHead;
    
    static void deleteNodes(Node* nodes)
    {
        while(nodes != nullptr){
            auto const next = nodes->next;
            delete nodes;
            nodes = next;
        }
    }
    
    void tryReclaim(Node* oldHead)
    {
        // If only this thread in the pop.
        if (threadsInPopCount == 1) {
            auto toBeDeletedList = toBeDeletedChainHead.exchange(nullptr);
            // Now, if only this thread in the pop.
            if (--threadsInPopCount == 0){
                deleteNodes(toBeDeletedList);
            }
            // If some nodes to be deleted still waiting.
            else if (toBeDeletedList != nullptr){
                pushListToDelChain(toBeDeletedList);
            }
            delete oldHead;
        }
        else{
            // If more than one thread in the pop.
            pushNodeToDelChain(oldHead);
            --threadsInPopCount;
        }
    }
    
    void pushListToDelChain(Node* nodes)
    {
        auto last = nodes;
        while (auto const next = last->next) {
            last = next;
        }
        pushListToDelChain(nodes, last);
    }
    
    void pushListToDelChain(Node* first, Node* last)
    {
        last->next = toBeDeletedChainHead;
        // Put current head of delete chain to the next of the last.
        // Then let the first be the head.
        while(!toBeDeletedChainHead.compare_exchange_weak(last->next, first));
    }
    
    void pushNodeToDelChain(Node* node)
    {
        pushListToDelChain(node, node);
    }
public:
    void push(T const& value)
    {
        auto const newNode = new Node(value);
        newNode->next = head.load();
        while (!head.compare_exchange_weak(newNode, newNode->next));
    }
    
    std::shared_ptr<T> pop()
    {
        ++threadsInPopCount;
        auto oldHead = head.load();
        while(oldHead
              && !head.compare_exchange_weak(oldHead, oldHead->next));
        
        std::shared_ptr<T> result;
        if (oldHead){
            result.swap(oldHead->data);
        }
        tryReclaim(oldHead);
        return result;
    }
    
};

 

使用引用计数方法管理内存的无锁栈 I

标签:

原文地址:http://www.cnblogs.com/wuOverflow/p/4848436.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!