feat(registry): named pid registry as a bimap
register/whereis/unregister plus the inverse lookup name_of. Erlang semantics: one name per pid, one pid per name, registering over a live binding errors; same-binding re-register is an idempotent Ok. Bimap = two HashMaps held in exact inverse under one Leaf RawMutex in RuntimeInner; the invariant is debug-asserted on every mutation. The inverse direction costs one extra String per binding and buys O(1) pid->name for supervisors/tracing/diagnostics. Cleanup is lazy: no finalize_actor hook, no Slot field (which would buy into the reset-in-three-places invariant). Liveness rides the generation-checked slot word - pids are never reused, so a stale binding is detectable, never misdirected - and bindings to dead actors behave as absent, pruned on contact by whereis/name_of/register/unregister. Liveness checks under the registry lock read only the atomic slot word, so the leaf rule holds trivially. send_by_name is deliberately absent: smarm has no per-pid mailbox, so there is nothing generic to send *to* - the registry yields a Pid, usable with monitor/link/request_stop and as routing for user channels. Tests: roundtrip both directions, idempotence, NameTaken on live holder, one-name-per-pid, NoProc, death-evaporates-binding (via lookup pruning and via register's own eviction path), unregister, cross-actor lookup wired into request_stop, and a 4-scheduler name-contention churn test.
This commit is contained in:
@@ -450,6 +450,10 @@ pub(crate) struct RuntimeInner {
|
||||
/// Preemption knobs, written into each scheduler thread's locals on startup.
|
||||
pub(crate) alloc_interval: u32,
|
||||
pub(crate) timeslice_cycles: u64,
|
||||
/// The name <-> pid registry (bidirectional). RawMutex Leaf: never held
|
||||
/// with any other lock; liveness checks under it read only the atomic
|
||||
/// slot word.
|
||||
pub(crate) registry: RawMutex<crate::registry::Registry>,
|
||||
/// Recycled stacks waiting to be reused by the next spawn.
|
||||
pub(crate) stack_pool: RawMutex<Vec<crate::stack::Stack>>,
|
||||
/// Maximum number of stacks to retain in the pool.
|
||||
@@ -482,6 +486,7 @@ impl RuntimeInner {
|
||||
sleeping: AtomicU32::new(0),
|
||||
alloc_interval,
|
||||
timeslice_cycles,
|
||||
registry: RawMutex::new(crate::registry::Registry::new()),
|
||||
stack_pool: RawMutex::new(Vec::new()),
|
||||
stack_pool_cap,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user