src/run_queue.rs: the run queue extracted behind a compile-time-selected type alias; mutually-exclusive cargo features with compile_error! guards (zero or >1 selected). No runtime dispatch. All variants compile in every build so their unit tests always run; the feature only picks the alias. - rq-mutex (default): Mutex<VecDeque>, the control/baseline. - rq-mpmc: hand-rolled Vyukov bounded MPMC ring, per-cell sequence numbers, padded enqueue/dequeue counters. Strict FIFO, lock-free. - rq-striped: M Vyukov rings (M = thread_count rounded up to pow2), fetch-add ticket distribution, probe-from-home on push. Relaxed FIFO with stripe-bounded skew; Σcapacity ≈ 2×max_actors so the probe terminates. Capacity soundness: occupancy ≤ max_actors by the at-most-once-enqueued invariant + slab cap, rings sized ≥ that bound, so push is infallible; a full ring panics as a double-enqueue invariant violation rather than spin. Two contracts the extraction made explicit (documented + debug-asserted): - Queue ops require preemption disabled: a producer suspended between claiming a cell and publishing its sequence stalls every consumer behind it — livelock, since the suspended actor's own resume entry is behind the hole. Structurally guaranteed since the phase-2 with_runtime NoPreempt fix. - pop()==None is a snapshot, not a fence. Termination is counter-first: every queue entry's target stays Queued (hence live) until that entry is popped, so live==0 alone implies nothing actionable is or can be queued; argument rewritten at the schedule_loop site. SharedState and with_shared are deleted — nothing global is mutex-guarded on the run path under the ring variants. Validated: 22 suites green per variant (release for all three; debug with live asserts for all three), ring unit tests (FIFO, lap wraparound, 4p/4c exactly-once, skewed drain) in every build, both compile_error! guards verified to fire.
50 lines
815 B
TOML
50 lines
815 B
TOML
[package]
|
|
name = "smarm"
|
|
version = "0.4.0"
|
|
edition = "2021"
|
|
rust-version = "1.95"
|
|
|
|
[features]
|
|
default = ["rq-mutex"]
|
|
smarm-trace = []
|
|
# Run-queue selection: exactly one, compile-time (see src/run_queue.rs).
|
|
# Non-default variants need --no-default-features (features are additive).
|
|
rq-mutex = []
|
|
rq-mpmc = []
|
|
rq-striped = []
|
|
|
|
[dependencies]
|
|
libc = "0.2"
|
|
|
|
[dev-dependencies]
|
|
libc = "0.2"
|
|
tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros", "sync", "time"] }
|
|
|
|
[profile.dev]
|
|
panic = "unwind"
|
|
|
|
[profile.release]
|
|
panic = "unwind"
|
|
lto = "thin"
|
|
codegen-units = 1
|
|
|
|
[[bench]]
|
|
name = "primes"
|
|
harness = false
|
|
|
|
[[bench]]
|
|
name = "multi_scheduler"
|
|
harness = false
|
|
|
|
[[bench]]
|
|
name = "general"
|
|
harness = false
|
|
|
|
[[bench]]
|
|
name = "smarm_favored"
|
|
harness = false
|
|
|
|
[[bench]]
|
|
name = "tokio_favored"
|
|
harness = false
|