Files
concurrency-in-action/source/listing_7.5.cpp
2018-10-18 00:40:34 -05:00

48 lines
1.1 KiB
C++

#include <atomic>
template <typename T>
class lock_free_stack {
private:
std::atomic<node*> to_be_deleted;
static void delete_nodes(node* nodes)
{
while (nodes) {
node* next = nodes->next;
delete nodes;
nodes = next;
}
}
void try_reclaim(node* old_head)
{
if (threads_in_pop == 1) {
node* nodes_to_delete = to_be_deleted.exchange(nullptr);
if (!--threads_in_pop) {
delete_nodes(nodes_to_delete);
}
else if (nodes_to_delete) {
chain_pending_nodes(nodes_to_delete);
}
delete old_head;
}
else {
chain_pending_node(old_head);
--threads_in_pop;
}
}
void chain_pending_nodes(node* nodes)
{
node* last = nodes;
while (node* const next = last->next) {
last = next;
}
chain_pending_nodes(nodes, last);
}
void chain_pending_nodes(node* first, node* last)
{
last->next = to_be_deleted;
while (!to_be_deleted.compare_exchange_weak(last->next, first))
;
}
void chain_pending_node(node* n) { chain_pending_nodes(n, n); }
};