class to create a lock-free, ABA-safe intrusive stack More...
#include <taskflow/core/freelist.hpp>
Public Member Functions | |
| AtomicIntrusiveStack () | |
| constructs an empty stack | |
| bool | empty () const |
| queries whether the stack is empty at the time of this call | |
| void | push (T node) |
| pushes a node onto the top of the stack | |
| T | pop () |
removes and returns the top node, or nullptr if the stack is empty | |
class to create a lock-free, ABA-safe intrusive stack
| T | pointer type of the node (e.g., Node*) |
| MemberPtr | pointer-to-member that identifies the intrusive link field within the node type (e.g., &Node::next) |
An intrusive stack embeds the link pointer directly inside each node rather than allocating separate list nodes. The caller selects which field serves as the link by supplying MemberPtr. While a node is held in the stack that field is exclusively owned by the stack and must not be accessed by the caller.
The field identified by MemberPtr must be of type T (a pointer to the same node type) so the stack can chain nodes through it:
All methods are safe to call concurrently from multiple threads. push and bulk_push are lock-free. pop is lock-free.
Each CAS operation pairs the pointer with a monotonically-incrementing version tag stored in a 128-bit TaggedPointer atomic. This requires CMPXCHG16B support on x86-64. A 64-bit tagged-pointer alternative for platforms without 128-bit CAS is available in the commented-out section at the bottom of this file.
|
inline |
constructs an empty stack
|
inline |
queries whether the stack is empty at the time of this call
The result is a snapshot and may be stale by the time the caller acts on it in a concurrent setting.
|
inline |
removes and returns the top node, or nullptr if the stack is empty
nullptr if the stack was emptyAtomically swaps the head to the next node in the chain. The popped node's link field is cleared to nullptr before it is returned, so the caller receives a clean node with no dangling stack pointer. Safe to call concurrently with other push, bulk_push, and pop calls.
|
inline |
pushes a node onto the top of the stack
| node | pointer to the node to push; must not be nullptr |
Sets the node's link field to the current head and atomically swaps the head to node. The version tag is incremented on every successful CAS to prevent ABA. Safe to call concurrently with other push, bulk_push, and pop calls.