RFC 016 Chunk 2c: approximate per-actor time-budget (reductions-like)
Accumulate on-CPU cycles per actor as ActorInfo.budget_cycles, behind the off-by-default budget-accounting feature (D6) — a reductions-style work metric for relative comparison across runs. - Approximate by design (per Mark): charge now - slice-start once at the yield point, reusing the timestamp reset_timeslice already sets, so one RDTSC per resume not two. Wake-slot resumes inherit the slice and so slightly over-attribute the chain's time to the woken actor — noise that averages out; we trade exactness for half the hot-path cost. - Field/ActorInfo member are unconditional (keeps the snapshot shape stable across the feature flag, D1); only the accumulation is gated, so default builds are byte-identical and pay nothing. Reads return 0 when off. Single-writer Relaxed like the other counters; reset in reset_counters (D7). Matrix: default + feature-on + rq-mpmc + rq-striped + release + trace all green; loom unaffected (feature off under --cfg loom).
This commit is contained in:
@@ -236,6 +236,7 @@ fn tree_from_nests_children_and_reroots_orphans() {
|
||||
mailbox_depth: 0,
|
||||
overruns: 0,
|
||||
messages_received: 0,
|
||||
budget_cycles: 0,
|
||||
};
|
||||
|
||||
let snap = RuntimeSnapshot {
|
||||
@@ -321,3 +322,33 @@ fn messages_received_counts_dequeues() {
|
||||
h.join().unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(feature = "budget-accounting")]
|
||||
#[test]
|
||||
fn budget_cycles_accumulate_when_enabled() {
|
||||
run(|| {
|
||||
let (ready_tx, ready_rx) = channel::<()>();
|
||||
let (gate_tx, gate_rx) = channel::<()>();
|
||||
let h = spawn(move || {
|
||||
// A little work so the consumed slice is non-trivial, then park.
|
||||
let mut acc = 0u64;
|
||||
for i in 0..10_000u64 {
|
||||
acc = acc.wrapping_add(i);
|
||||
smarm::check!();
|
||||
}
|
||||
std::hint::black_box(acc);
|
||||
ready_tx.send(()).unwrap();
|
||||
gate_rx.recv().unwrap();
|
||||
});
|
||||
ready_rx.recv().unwrap();
|
||||
// Once the worker has run and yielded (here, parked), its slice is
|
||||
// charged.
|
||||
let info = spin_until(h.pid(), |a| a.state == ActorState::Parked);
|
||||
assert!(
|
||||
info.budget_cycles > 0,
|
||||
"budget should accrue after the actor runs and yields"
|
||||
);
|
||||
gate_tx.send(()).unwrap();
|
||||
h.join().unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user