lockfree/smr/nebr/typestates/retire
Retire typestate for adding objects to limbo bags.
Must be pinned to retire objects.
- retire is sink-form: it consumes RetireReady[MT] and returns Retired[MT]. To retire multiple objects in the same pinned epoch, convert back with retireReadyFromRetired. The var-form wrappers in debra/convenience (retire, retireBatch) handle this for you.
- The pointer/destructor pair handed to retire(p, dtor) is captured into the limbo bag immediately. The destructor closure must remain valid until reclamation runs (Destructor is a nimcall proc, so a top-level proc or releaseDestructor[T]() result is fine).
- Retiring the same pointer twice from different threads (or the same thread across multiple pin cycles) double-frees on reclamation. The library does not deduplicate.
- debra + scope.retireOnCAS / scope.retireOnPublish (or retireReady(scope.state).retire(...)) - the recommended path.
- debra - eventual reclamation after epoch safety.
RetireContext
Section titled “RetireContext”RetireContext[MaxThreads; CC] = object of RootObj handle*: ThreadHandle[MaxThreads, CC] epoch*: uint64RetireReady
Section titled “RetireReady”RetireReady[MaxThreads; CC] = distinct RetireContext[MaxThreads, CC]Retired
Section titled “Retired”Retired[MaxThreads; CC] = distinct RetireContext[MaxThreads, CC]RetireContextState
Section titled “RetireContextState”RetireContextState = enum fsRetireReady, fsRetiredRetireContextStates
Section titled “RetireContextStates”RetireContextStates[MaxThreads; CC] = RetireReady[MaxThreads, CC] | Retired[MaxThreads, CC]Procedures & Functions
Section titled “Procedures & Functions”proc state[MaxThreads: static int; CC: static PinScopeCardinality = ccSingle]( f: RetireReady[MaxThreads, CC]): RetireContextStateRuntime state inspection for RetireReady. Returns the enum value for pattern matching in case expressions.
proc state[MaxThreads: static int; CC: static PinScopeCardinality = ccSingle]( f: Retired[MaxThreads, CC]): RetireContextStateRuntime state inspection for Retired. Returns the enum value for pattern matching in case expressions.
$
proc `$`[MaxThreads: static int; CC: static PinScopeCardinality = ccSingle]( s: RetireReady[MaxThreads, CC]): stringString representation for state ‘RetireReady’. Returns the bare state name (no fs prefix).
proc `$`[MaxThreads: static int; CC: static PinScopeCardinality = ccSingle]( s: Retired[MaxThreads, CC]): stringString representation for state ‘Retired’. Returns the bare state name (no fs prefix).
proc `$`(s: RetireContextState): string {.raises: [], tags: [], forbids: [].}String representation of RetireContextState enum. Strips the fs prefix for human-friendly output.
proc `=copy`[MaxThreads: static int; CC: static PinScopeCardinality = ccSingle]( dest: var RetireReady[MaxThreads, CC]; src: RetireReady[MaxThreads, CC]) {.error: "State \'RetireReady\' cannot be copied. Transitions consume the input state.".}proc `=copy`[MaxThreads: static int; CC: static PinScopeCardinality = ccSingle]( dest: var Retired[MaxThreads, CC]; src: Retired[MaxThreads, CC]) {.error: "State \'Retired\' cannot be copied. Transitions consume the input state.".}retireReady
Section titled “retireReady”proc retireReady[MaxThreads: static int; CC: static PinScopeCardinality]( p: Pinned[MaxThreads, CC]): RetireReady[MaxThreads, CC]Create retire context from pinned state.
retireReadyFromRetired
Section titled “retireReadyFromRetired”proc retireReadyFromRetired[MaxThreads: static int; CC: static PinScopeCardinality]( r: sink Retired[MaxThreads, CC]): RetireReady[MaxThreads, CC] {. notATransition.}Get back to RetireReady after retiring (for multiple retires).
pinnedFromRetired
Section titled “pinnedFromRetired”proc pinnedFromRetired[MaxThreads: static int; CC: static PinScopeCardinality]( r: sink Retired[MaxThreads, CC]): Pinned[MaxThreads, CC] {.notATransition.}Return a Pinned[MaxThreads, CC] reconstructed from a Retired[MaxThreads, CC] value, allowing the caller to keep working in the same pinned epoch (e.g. interleaving reads with further retires) instead of unpinning immediately after a retire.
Symmetric to retireReadyFromRetired: same underlying RetireContext[MaxThreads, CC], projected to the Pinned typestate via the EpochGuardContext[MaxThreads, CC] shape (handle + epoch). The slot's pinned flag is unchanged; this is a typestate rebrand, not a re-pin.
See also: retireReadyFromRetired, retire, debra.
retire
Section titled “retire”proc retire[MaxThreads: static int; CC: static PinScopeCardinality]( r: sink RetireReady[MaxThreads, CC]; p: pointer; destructor: Destructor): Retired[ MaxThreads, CC] {.raises: [], tags: [TypestateOp, RootEffect].}Retire a raw pointer for epoch-based reclamation.
The destructor will be called when the epoch becomes safe. Use for manually-managed memory (ptr types, alloc/dealloc, etc.)
handle
Section titled “handle”func handle[MaxThreads: static int; CC: static PinScopeCardinality]( r: RetireReady[MaxThreads, CC]): ThreadHandle[MaxThreads, CC] {. notATransition.}Macros
Section titled “Macros”macro match[MaxThreads: static int; CC: static PinScopeCardinality = ccSingle]( value: RetireContextStates[MaxThreads, CC]; arms: untyped): untypedSingle-target pattern match on states of typestate ‘RetireContext’; rewrites to block: let bind = move(value); body. Syntax is <StateName>(bind):, with exactly one arm.