examples: deterministic single-scheduler context-switch probe
A minimal Config::exact(1) program with two actors doing a fixed number of yield_now() calls. No I/O/timers/channels, so the instruction stream stays centered on the naked-asm switch. Frame-pointer-friendly. Intended for single-threaded inspection under a debugger (e.g. llmdbg).
This commit is contained in:
@@ -0,0 +1,47 @@
|
|||||||
|
//! A deliberately small, deterministic smarm program for inspecting the
|
||||||
|
//! naked-asm context switch under a debugger (llmdbg).
|
||||||
|
//!
|
||||||
|
//! Design goals that make it debugger-friendly:
|
||||||
|
//! - Exactly one scheduler thread (`Config::exact(1)`) so the whole run is
|
||||||
|
//! single-OS-threaded — llmdbg is single-threaded-debuggee only today.
|
||||||
|
//! - A known, small number of voluntary yields, so the number of
|
||||||
|
//! `switch_to_actor` / `switch_to_scheduler` transitions is predictable.
|
||||||
|
//! - Frame pointers preserved (see the [profile] note in how we build it),
|
||||||
|
//! so llmdbg's `finish()` and frame-pointer assumptions hold.
|
||||||
|
//! - No I/O, no timers, no channels — just the scheduler and the context
|
||||||
|
//! switch, to keep the instruction stream centered on the asm we care
|
||||||
|
//! about.
|
||||||
|
//!
|
||||||
|
//! Two actors each yield `N_YIELDS` times, printing a counter. Run normally
|
||||||
|
//! it just prints an interleaving. Run under llmdbg with breakpoints on
|
||||||
|
//! `smarm::context::switch_to_actor_asm` and
|
||||||
|
//! `smarm::context::switch_to_scheduler` to watch the stack pointer hand off
|
||||||
|
//! between the scheduler stack and each actor's mmap'd stack.
|
||||||
|
|
||||||
|
use smarm::{init, Config};
|
||||||
|
|
||||||
|
const N_YIELDS: usize = 3;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Single scheduler thread: one OS thread, cooperative only.
|
||||||
|
let rt = init(Config::exact(1));
|
||||||
|
rt.run(|| {
|
||||||
|
let a = smarm::spawn(|| {
|
||||||
|
for i in 0..N_YIELDS {
|
||||||
|
println!("actor A tick {i}");
|
||||||
|
smarm::yield_now();
|
||||||
|
}
|
||||||
|
println!("actor A done");
|
||||||
|
});
|
||||||
|
let b = smarm::spawn(|| {
|
||||||
|
for i in 0..N_YIELDS {
|
||||||
|
println!("actor B tick {i}");
|
||||||
|
smarm::yield_now();
|
||||||
|
}
|
||||||
|
println!("actor B done");
|
||||||
|
});
|
||||||
|
a.join().expect("A joined");
|
||||||
|
b.join().expect("B joined");
|
||||||
|
println!("root done");
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user