Template<typename t>classlockfreestack{Private: structNode {std::shared_ptr<T>data; Node*Next; Node (TConst&value): Data (std::make_shared<T>(value)) {} }; Std::atomic<Node*>Head; Std::atomic<size_t>Threadsinpopcount; Std::atomic<Node*>Tobedeletedchainhead; Static voidDeletenodes (node*nodes) { while(Nodes! =nullptr) {AutoConstNext = nodes->Next; Deletenodes; Nodes=Next; } } voidTryreclaim (node*oldhead) { //If only this thread is in the pop. if(Threadsinpopcount = =1) {Auto Tobedeletedlist=Tobedeletedchainhead.exchange (nullptr); //Now , if only this thread is in the pop. if(--threadsinpopcount = =0) {deletenodes (tobedeletedlist); } //If Some nodes to be deleted still waiting. Else if(Tobedeletedlist! =nullptr) {Pushlisttodelchain (tobedeletedlist); } DeleteOldhead; } Else{ //If more than one thread in the pop.Pushnodetodelchain (Oldhead); --Threadsinpopcount; } } voidPushlisttodelchain (node*nodes) {Auto last=nodes; while(AutoConstNext = last->next) { Last=Next; } pushlisttodelchain (nodes, last); } voidPushlisttodelchain (node* First, node*Last ) { Last->next =Tobedeletedchainhead; //Put current head of delete chain to the next of the last . //Then let's the first be the head. while(!tobedeletedchainhead.compare_exchange_weak (last->Next, first)); } voidPushnodetodelchain (node*node) {Pushlisttodelchain (node, node); } Public: voidPush (TConst&value) {AutoConstNewNode =NewNode (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); returnresult; } };
Lock-Free stack for managing memory using reference counting method I