Expand description
phase-509 P9b – the executor’s lock (RFC-0108 “As built in P9b”). phase-509 P9b item 1 (RFC-0108 “As built in P9b”) – the executor’s lock.
RFC-0108 runs one executor per core with one worker thread per preemption
level. Every path that touches the executor’s state – a worker’s pass, and
every C / C++ FFI entry a callback or another thread calls – then has to be
serialised, and that is this lock: a port-provided, RECURSIVE,
PRIORITY-INHERITING mutex (nros_platform_mutex_rec_* on every port), which
the runner installs on the executor before a second thread can reach it.
An executor with no lock installed (every one-level image, every Rust
&mut user) takes the None arm: a guard is one predictable branch and
nothing else, so this seam changes no behaviour where it is not installed.
Why recursive: an owned pass (spin_once(&mut self)), and a pass whose
lock has no thread identity, hold the lock across each user callback, so a
callback that calls back into the executor (timer_cancel, *_release, a
parameter call) re-enters it on the same thread.
Item 2 – the callback window. A shared or band pass
(Executor::spin_once_shared, Executor::spin_band_once) whose lock
carries the port’s thread identity (ExecLock::with_thread_id) gives
the lock for each user callback and takes it back after (Window). The
entry stays marked running (its slot tag), so no other pass dispatches or
probes it and its release is deferred; a Running record names the
thread running it, so an entry operation from another thread is told apart
from one the callback makes itself: the entry accessors answer as for a
stale handle, and a timer cancel or reset is deferred to the callback’s
return.
Why priority-inheriting: a less urgent worker holding the lock for a bookkeeping step must run at the waiter’s priority, so a more urgent level’s blocking is bounded by ONE critical section (RFC-0108 B_i).
Interrupt handlers never take it: arrivals go through the scheduler’s lock-free ready word and the wake object, exactly as before.
Structs§
- Exec
Guard - Holds the executor’s lock for its own lifetime: taken at
ExecGuard::acquire, given at drop. With no lock installed it holds nothing. - Exec
Lock - The executor’s lock: the port’s recursive priority-inheriting mutex and
the two calls that take and give it. Installed once, before any second
thread can reach the executor (
super::Executor::set_exec_lock), and never changed while one can.
Type Aliases§
- Exec
Lock Fn - A port’s lock or unlock entry,
nros_platform_mutex_rec_lock’s shape:0on success, negative on failure. - Thread
IdFn - The calling thread’s identity, as the port names it (
k_current_get,pthread_self): equal on one thread, distinct across live threads.