feat(park): scheduler coordination layer — parkers, idle mask, wake protocol (RFC 018)
Schedulers get an IO-agnostic sleep/wake primitive of their own: one futex Parker per scheduler thread (permit semantics, std::thread::park shaped — closes the check-then-park race), an AtomicU64 idle mask with a set-bit → re-check → wait park protocol, wake_one (highest-bit LIFO, CAS-clear before unpark: exactly one wakeup per call by construction), wake_all for the terminal path, and the timekeeper role — at most one parked scheduler holds the timer deadline, with an atomic armed-deadline snapshot for the busy-path due-check and an insert-side re-arm wake. Deadlines travel as nanosecond timespecs end to end; the wake pipe's as_millis truncation is unrepresentable here. The Dekker publish/re-check shape is resolved by the same-location-RMW handshake (AcqRel), not SeqCst loads; loom verifies exactly this in four models (no-lost-wake, chain propagation, timekeeper handoff, termination), run with LOOM_MAX_PREEMPTIONS=3 — unbounded exploration is impractical for the looped models. Loom/non-Linux builds park on a Mutex+Condvar via sync_shim. Standalone until the runtime swap (next commit): nothing outside tests constructs a Coordinator yet, hence the temporary dead_code allow in lib.rs.
This commit is contained in:
@@ -32,6 +32,10 @@ pub mod introspect;
|
||||
#[cfg(feature = "observer")]
|
||||
pub mod observer;
|
||||
pub mod runtime;
|
||||
// TEMPORARY dead_code allow: park is standalone until the RFC 018 runtime
|
||||
// swap (next commit) wires it into schedule_loop/enqueue; the allow dies there.
|
||||
#[allow(dead_code)]
|
||||
pub(crate) mod park;
|
||||
pub(crate) mod raw_mutex;
|
||||
pub(crate) mod slot_state;
|
||||
pub(crate) mod sync_shim;
|
||||
|
||||
Reference in New Issue
Block a user