runtime: wake_slot default ON (RFC 005 accepted, finding 18); supervisor stops survivors sequentially so reverse-order teardown is guaranteed; deflake gen_server/channel tests; baseline.json regenerated slot-on; ROADMAP notes
This commit is contained in:
+9
-1
@@ -137,11 +137,19 @@ fn channel_ops_interleaved_with_monitor_churn_multi_thread() {
|
||||
for i in 0..32i64 {
|
||||
let tx = tx.clone();
|
||||
handles.push(spawn(move || {
|
||||
// Short-lived target whose death fires the monitor below.
|
||||
// Short-lived target whose death fires the monitor below. It
|
||||
// waits for `go` so the monitor is registered before it can
|
||||
// die — otherwise a fast target yields an immediate NoProc
|
||||
// Down instead of the finalize-sent Exit this test is about
|
||||
// (pre-existing ~8% flake at 4 threads, independent of the
|
||||
// wake slot).
|
||||
let (go_tx, go_rx) = channel::<()>();
|
||||
let t = spawn(move || {
|
||||
let _ = go_rx.recv();
|
||||
tx.send(i).unwrap();
|
||||
});
|
||||
let m = smarm::monitor(t.pid());
|
||||
go_tx.send(()).unwrap();
|
||||
t.join().unwrap();
|
||||
// Down delivery exercises send-from-finalize.
|
||||
let d = m.rx.recv().unwrap();
|
||||
|
||||
+14
-3
@@ -396,8 +396,11 @@ impl GenServer for Pool {
|
||||
}
|
||||
|
||||
// A worker spawned and watched from inside a handler delivers its Down to
|
||||
// handle_down. Down arms outrank the inbox, so the death is in the log by
|
||||
// the time the follow-up call is answered.
|
||||
// handle_down. Nothing orders the worker's death before the follow-up
|
||||
// call (the worker sits in the shared queue while call/reply wakes ride the
|
||||
// wake slot), so poll: the log must become exactly [Panic] within a bounded
|
||||
// number of yields. Down-outranks-inbox ordering is covered by
|
||||
// `watch_dead_pid_is_noproc_down`.
|
||||
#[test]
|
||||
fn worker_pool_down_reaches_handle_down() {
|
||||
let got = Arc::new(Mutex::new(Vec::new()));
|
||||
@@ -409,7 +412,15 @@ fn worker_pool_down_reaches_handle_down() {
|
||||
});
|
||||
server.cast(PoolCast::SpawnDoomedWorker).unwrap();
|
||||
let _ = server.call(()).unwrap(); // sync point: cast handled, worker live
|
||||
*got2.lock().unwrap() = server.call(()).unwrap();
|
||||
let mut log = Vec::new();
|
||||
for _ in 0..10_000 {
|
||||
log = server.call(()).unwrap();
|
||||
if !log.is_empty() {
|
||||
break;
|
||||
}
|
||||
smarm::yield_now();
|
||||
}
|
||||
*got2.lock().unwrap() = log;
|
||||
});
|
||||
assert_eq!(*got.lock().unwrap(), vec![DownReason::Panic]);
|
||||
}
|
||||
|
||||
+3
-2
@@ -80,10 +80,11 @@ fn slot_off_means_zero_slot_traffic() {
|
||||
assert_eq!(rt.stats().slot_hits(), 0);
|
||||
assert_eq!(rt.stats().slot_displacements(), 0);
|
||||
|
||||
// …and off by default (RFC 005: default off until the shootout accepts).
|
||||
// …and ON by default (RFC 005 accepted after the shootout — history.md
|
||||
// finding 17/18: ping-pong 12.5× at 20T, ~9% at 1T, 100% slot hits).
|
||||
let rt = init(Config::exact(1));
|
||||
rt.run(ping_pong(2, 100));
|
||||
assert_eq!(rt.stats().slot_hits(), 0, "wake_slot must default to OFF");
|
||||
assert!(rt.stats().slot_hits() > 0, "wake_slot must default to ON");
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user