preempt: pub maybe_preempt for shared counter across event sources

v0.2 will add stack-frame entries as a second preemption event source.
Both routes share ALLOC_COUNT so the timeslice check rate is the same
whether the actor is alloc-heavy, frame-heavy, or mixed.
This commit is contained in:
Claude
2026-05-22 05:15:12 +00:00
parent 0e9d9d7d5f
commit 6c48caecab

View File

@@ -1,8 +1,15 @@
//! Allocator-driven preemption. //! Preemption hooks.
//! //!
//! A `GlobalAlloc` wrapper counts allocations. Every `ALLOC_INTERVAL`-th //! Preemption is event-driven: every preemption event decrements a
//! allocation it reads RDTSC and, if the actor's timeslice has expired, //! thread-local counter (`ALLOC_COUNT`). When the counter hits zero, we
//! calls `switch_to_scheduler` to yield. //! read RDTSC and, if the actor's timeslice has expired, call
//! `switch_to_scheduler` to yield. Resetting the counter to `ALLOC_INTERVAL`
//! amortises the RDTSC across many cheap events.
//!
//! Events today are heap allocations (via `PreemptingAllocator`). v0.2 will
//! add stack-frame entries as a second event source — frames are stack
//! allocations, the counter naming still fits — sharing this same counter
//! so both routes behave consistently.
//! //!
//! All state is thread-local. The scheduler enables preemption on resume //! All state is thread-local. The scheduler enables preemption on resume
//! and disables it on the return path, so the scheduler can never preempt //! and disables it on the return path, so the scheduler can never preempt
@@ -72,8 +79,12 @@ unsafe impl GlobalAlloc for PreemptingAllocator {
} }
} }
/// Shared preemption check. Called by every preemption event source — the
/// heap allocator today, the stack-frame entry hook in v0.2. Decrements
/// `ALLOC_COUNT`; every `ALLOC_INTERVAL` calls reads the timeslice clock
/// and yields if expired.
#[inline(always)] #[inline(always)]
fn maybe_preempt() { pub fn maybe_preempt() {
ALLOC_COUNT.with(|c| { ALLOC_COUNT.with(|c| {
let n = c.get(); let n = c.get();
if n == 0 { if n == 0 {