RFC 016 Chunk 2a: per-actor timeslice overrun counter

Tally overruns at the slice-expiry site in preempt.rs (the RFC 006
signal), surfaced as ActorInfo.overruns.

- Counter is a hot-region AtomicU64 on Slot, single-writer Relaxed
  load+store (no atomic RMW), read Relaxed by the snapshot (D5).
- Reached from the rare expiry branch via a stashed *const Slot in a
  preempt thread-local, set/cleared on the same resume/return boundary
  as CURRENT_STOP — one TLS load, no runtime lookup. Shared infra for
  the messages-received counter next.
- Reset in all three slot-lifecycle sites: Slot::vacant, reclaim_slot,
  install_actor (standing invariant, D7) — per-incarnation counts.
This commit is contained in:
smarm-agent
2026-06-19 07:18:03 +00:00
parent 7ef915c81e
commit 354eef9f88
4 changed files with 115 additions and 0 deletions
+8
View File
@@ -83,6 +83,10 @@ pub struct ActorInfo {
/// install / spawn_addr / gen_server). 0 for an actor that holds only a
/// private `channel()` receiver — those are invisible to the registry.
pub mailbox_depth: u32,
/// Timeslice overruns tallied for this incarnation (RFC 016 Chunk 2): how
/// many times the actor was preempted for exceeding its slice. Resets on
/// restart (per-incarnation, D7).
pub overruns: u64,
}
/// A whole-runtime snapshot. See the module docs for the D2 tearing model.
@@ -159,6 +163,9 @@ fn read_slot(slot: &Slot, idx: u32, mail: Option<&MailboxInfo>) -> Option<ActorI
let joiners = cold.waiters.len() as u32;
drop(cold);
// Counters are hot-region atomics, read lock-free (RFC 016 Chunk 2).
let overruns = slot.overruns();
// Names + depth belong to this incarnation only if the registry mailbox's
// pid matches the slab generation; a stale registry entry (dead prior
// occupant, not yet pruned) contributes nothing.
@@ -177,6 +184,7 @@ fn read_slot(slot: &Slot, idx: u32, mail: Option<&MailboxInfo>) -> Option<ActorI
links,
joiners,
mailbox_depth,
overruns,
})
}