ManagedSlice¶
ManagedSlice[T] is a single-owner, move-tracked, contiguous
allocation of T elements with an explicit length. It is the
managed-payload analog of ManagedRef[T] for arrays.
ManagedSlice is the recommended payload type when queueing
batched / array-shaped work that must outlive the producer's stack
frame and cannot be passed as ptr T because the consumer needs the
length too. Like ManagedRef, it integrates with the umbrella's
SMR (nebr) for deferred reclamation.
See also¶
- ManagedRef — single-element managed payload.
- Chronos — managed temporal payload.
- SMR / nebr — the reclamation backend.
managed_slice
¶
lockfree/managed_slice
Internal slot encoding for string and seq[U] payloads under
Path C (Queue[string, ...] / Queue[seq[U], ...]). Unified
encoding using the heap-box pattern.
NEVER user-facing¶
ManagedSlice[T] is the wire-format the queue stores in its slot
array. The user-facing API is string / seq[U]. ManagedSlice
MUST NOT leak into public docs, examples, or signatures.
Design pattern: heap-boxed payload pointer¶
The slot bits are a distinct uint pointer at a heap-allocated
box (alloc0Shared) that holds the V2 payload (NimStringV2 /
NimSeqV2[U]). Box layout deliberately mirrors a ptr object
with a single v field of the payload type so that under
arc/orc/atomicArc/refc the compiler-emitted destructor for v
runs the V2 frees() path automatically when =destroy is
called explicitly in disposeSlot.
Path C MM matrix¶
- arc / orc / atomicArc / refc — sink-assign payload into the
zero-initialised box on
wrap(compiler emits=sink);movethe payload out anddeallocSharedthe box onunwrap;=destroythe box payload +deallocSharedthe box ondisposeSlot(destructor walk). - none — strict bit-transport contract. The source binding
is NOT zeroed on
wrapand the destination is NOT destroyed ondisposeSlot. The user owns lifetime; we are a pointer-bit transport only.
ABI stability¶
sizeof(ManagedSlice[T]) == sizeof(uint) on every supported
platform — asserted at compile time in the static: block below.
ManagedSlice
¶
type ManagedSlice[T] = distinct uint
Slot encoding for a string (T = char) or seq[U]
(T = U) payload. Internal — see module doc-comment. Sized
and aligned identically to uint.
wrap inline ¶
proc wrap(s: sink string): ManagedSlice[char]
Pack a string into the slot encoding. Allocates a shared
heap box and transfers the payload in. The caller's binding is
consumed (sink).
Parameters
-
s(sink string)
Returns
ManagedSlice[char]
wrap inline ¶
proc wrap(s: sink seq[U]): ManagedSlice[U]
Pack a seq[U] into the slot encoding. Allocates a shared
heap box and transfers the payload in.
seq[ref U] and seq[seq[U]] are ACCEPTED. The box-pattern
transport handles inner-element lifecycle correctly via Nim's
compiler-emitted seq =destroy when the box is reconstructed at
pop or destroy-walk. The library's transport is the outer seq
value (boxed here); inner refs/seqs are the seq's lifecycle
problem. No supportsCopyMem(U) guard is applied here or in
path_c_admit.nim.
Parameters
-
s(sink seq[U])
Returns
ManagedSlice[U]
unwrap inline ¶
proc unwrap(ms: ManagedSlice[char]): string
Unpack a string from the slot encoding. Frees the heap box.
On arc/orc/atomicArc/refc the payload pointer is moved out (no refcount bump on the V2 payload); on mm:none the payload bits are copied out and the source bits are not zeroed.
Parameters
-
ms(ManagedSlice[char])
Returns
string
unwrapSeq inline ¶
proc unwrapSeq(ms: ManagedSlice[U]): seq[U]
Unpack a seq[U] from the slot encoding. Frees the heap box.
Distinctly named (unwrapSeq, not unwrap) so the seq path is
never shadowed by the non-generic unwrap(ManagedSlice[char])
(string/StringBox) overload. ManagedSlice[char] is the slot
encoding for BOTH string (T = char) and seq[char]
(U = char); they collapse to the same instantiation, so Nim
overload resolution would pick the non-generic string unwrap for
a seq[char] slot, applying the StringBox layout to a SeqBox.
The distinct name forces the SeqBox path explicitly. See
internal/path_c_wrap.nim.
Parameters
-
ms(ManagedSlice[U])
Returns
seq[U]
disposeSlot inline ¶
proc disposeSlot(ms: ManagedSlice[char])
Destroy-walk dispose for an unpopped string slot. Safe on the
nil slot (0).
Non-generic (string / StringBox) overload. disposeSeqSlot is
the distinctly-named SEQ counterpart so a seq[char] slot is
never routed here by overload resolution (StringBox vs SeqBox
layout). See internal/path_c_wrap.nim.
Parameters
-
ms(ManagedSlice[char])
disposeSeqSlot inline ¶
proc disposeSeqSlot(ms: ManagedSlice[U])
Destroy-walk dispose for an unpopped seq slot. Safe on the nil
slot (0).
Distinctly named (disposeSeqSlot, not disposeSlot) so the
seq path is never shadowed by the non-generic
disposeSlot(ManagedSlice[char]) (string/StringBox) overload.
ManagedSlice[char] is the slot encoding for BOTH string
and seq[char]; they collapse to the same instantiation, so Nim
overload resolution would pick the non-generic string
disposeSlot for a seq[char] slot, running the StringBox
destructor over a SeqBox. The distinct name forces the SeqBox path
explicitly. See internal/path_c_wrap.nim.
Parameters
-
ms(ManagedSlice[U])