Loading...
Searching...
No Matches
tf::TaggedHead64< PtrBits > Struct Template Reference

tagged free-list head packed into a single 64-bit word More...

#include <taskflow/utility/object_pool.hpp>

Public Types

using pointer_type = uintptr_t
 block address representation
 
using tag_type = uint16_t
 ABA version counter.
 

Public Member Functions

 TaggedHead64 ()=default
 constructs a null, zero-tagged head
 
 TaggedHead64 (pointer_type p, tag_type t) noexcept
 constructs a head with an explicit block address and version counter
 
pointer_type get_ptr () const noexcept
 returns the block address
 
tag_type get_tag () const noexcept
 returns the 16-bit ABA version counter
 

Public Attributes

uintptr_t bits {0}
 packed word: high TAG_BITS bits = version tag, low PTR_BITS bits = address
 

Static Public Attributes

static constexpr int PTR_BITS = PtrBits
 bits reserved for the block address
 
static constexpr int TAG_BITS = 64 - PtrBits
 bits reserved for the version counter
 
static constexpr pointer_type PTR_MASK
 mask isolating the address field
 

Detailed Description

template<int PtrBits = TF_POINTER_BITS>
struct tf::TaggedHead64< PtrBits >

tagged free-list head packed into a single 64-bit word

Template Parameters
PtrBitsnumber of low bits reserved for the block address; the remaining (64 - PtrBits) bits hold the ABA version counter. Must be at most 48 so that at least 16 tag bits are available. Defaults to TF_POINTER_BITS (48 on x86-64, AArch64, and RISC-V SV48). Override for non-standard VA layouts:
  • 39 for RISC-V SV39, giving 25 tag bits
  • Values above 48 (e.g. LA57's 57) are rejected by a static_assert — use TaggedHead128 in those cases
TaggedHead64 fits both the free-list head pointer and an ABA version counter into a single uintptr_t: the low PtrBits bits store the block address and the remaining high bits store the version counter. Because the entire state is one 64-bit word, std::atomic<TaggedHead64<>> is always lock-free on every 64-bit platform — including those without a native 128-bit CAS instruction (RISC-V, baseline ARMv8.0).

The default PtrBits of 48 assumes user-space virtual addresses occupy at most 48 bits, which holds for:

  • x86-64 with 4-level paging — bits 48–63 are zero in user space
  • AArch64 with 48-bit VA space — TTBR0 range
  • RISC-V SV39 / SV48 — provides even more headroom (25 / 16 free bits)

The resulting (64 - PtrBits) -bit version counter wraps at 2^(64-PtrBits). With the default of 48, the counter is 16 bits and wraps at 65 536. ABA would require a competing thread to complete exactly that many push/pop cycles on the same shard between another thread's load and its CAS — negligible probability in any task-parallel workload.

// default PtrBits (48) — correct for x86-64, AArch64, RISC-V SV48
// RISC-V SV39: only 39 address bits, 25 bits available for the tag
sharded fixed-size object allocator with a lock-free hot path
Definition object_pool.hpp:320
See also
TaggedHead128 for a variant with a full 64-bit version counter that may use a lock-based fallback on platforms without 128-bit CAS.

Constructor & Destructor Documentation

◆ TaggedHead64()

template<int PtrBits = TF_POINTER_BITS>
tf::TaggedHead64< PtrBits >::TaggedHead64 ( pointer_type p,
tag_type t )
inlinenoexcept

constructs a head with an explicit block address and version counter

Parameters
pblock address as uintptr_t; only the low PtrBits bits are stored
tABA version counter; only the low TAG_BITS bits are stored

Member Data Documentation

◆ PTR_MASK

template<int PtrBits = TF_POINTER_BITS>
pointer_type tf::TaggedHead64< PtrBits >::PTR_MASK
staticconstexpr
Initial value:
=
(pointer_type{1} << PTR_BITS) - 1
uintptr_t pointer_type
block address representation
Definition object_pool.hpp:121
static constexpr int PTR_BITS
bits reserved for the block address
Definition object_pool.hpp:124

mask isolating the address field


The documentation for this struct was generated from the following file: