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:
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user