Preliminary. ThinkMeta ConcurrentTasks and this documentation are preliminary; everything is subject to change.

API reference / Collections

LockFreeStack class

The core's own lock-free stack: a head of top pointer and tag, changed as one 16-byte word.

On this page
Use
import ThinkMeta.ConcurrentTasks.Collections.ConcurrentStack;
Namespace
ThinkMeta::ConcurrentTasks::Collections::Detail
Platforms
Windows, Linux

Syntax

template <typename T> requires std::is_base_of_v<ListEntry, T> class LockFreeStack

Template parameters

Ttypename
No description yet.

Remarks

The tag counts every change in its upper 48 bits and the depth in its lower 16, so a head that was popped and pushed back (ABA) never passes for the one a thread read. Pop reads the top item's next before its exchange may fail, so an item must stay readable until no Pop that could have seen it on the stack is in flight any more; items of the core (task contexts, per-thread data) live as long as their scheduler, which settles it. Unlike the Windows SList, whose pop the kernel restarts when it faults on a freed item, a read of freed memory here is a crash. next is written by a pusher and read by a concurrent popper that may lose its race, so both go through an atomic reference (relaxed: a plain move on x86-64); the head is read with acquire and changed with a full barrier, which orders next around it.

Constructors

LockFreeStack

Constructs an empty stack.

Syntax

constexpr LockFreeStack() noexcept;

Remarks

Constant initialization: a global stack is ready before any code runs.

Methods

Push

Pushes an item on top.

Syntax

void Push(T* item) noexcept;

Parameters

itemT*
Not nullptr; its ListEntry::next is overwritten.

Pop

Removes and returns the top item.

Syntax

T* Pop() noexcept;

Return value

Type: T*

The top item, or nullptr if the stack is empty.

Remarks

Reads the top item's next before its exchange can fail: an item that leaves the stack must stay readable until every Pop that may have seen it on top has returned (see the class remarks). Lifetime is the user's matter; a freed item here is a crash.

Flush

Removes all items in one operation and returns them as a chain.

Syntax

T* Flush() noexcept;

Return value

Type: T*

The former top item, linked to the others through ListEntry::next; nullptr if the stack was empty.

Remarks

A Pop that lost its race may still read the next of an item in the chain: walk it with relaxed atomic loads (std::atomic_ref), as the stack itself does.

Size

Returns the number of items at the moment of the call.

Syntax

std::uint16_t Size() const noexcept;

Return value

Type: std::uint16_t

The item count, modulo 65536.

Generated from ThinkMeta.ConcurrentTasks.API @ da816bc (2026-11-06).