Skip to content

Commit fa5654e

Browse files
committed
Make sure exited_threads arising from repeat loops are returned as ExplicitFork
1 parent 943d665 commit fa5654e

File tree

1 file changed

+26
-1
lines changed

1 file changed

+26
-1
lines changed

monitor/src/scheduler.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use anyhow::{Context, anyhow};
1+
use anyhow::{anyhow, Context};
22
use baa::{BitVecOps, BitVecValue};
33
use log::info;
44
use protocols::{
@@ -868,6 +868,31 @@ impl Scheduler {
868868
// This determines if we need to move threads to/from different queues
869869
match thread.transaction[next_stmt_id] {
870870
Stmt::Step => {
871+
// If the current statement itself is a `fork()`,
872+
// it means this thread started directly at the fork
873+
// (e.g. `exited_thread` from `handle_repeat_loops`, i.e.
874+
// the thread that exits the `repeat_loop`
875+
// with `loop_arg = Known(n)` set to some `n`).
876+
// We need to handle the fork (by returning `ExplicitFork` early)
877+
// before moving the current thread
878+
// to the `next` queue, but only if no other threads from the same
879+
// start cycle have already forked this cycle (to avoid duplicates)
880+
if matches!(thread.transaction[current_stmt_id], Stmt::Fork) {
881+
thread.has_forked = true;
882+
let already_forked =
883+
self.forked_start_cycles.contains(&thread.start_cycle);
884+
if !already_forked {
885+
self.forked_start_cycles.insert(thread.start_cycle);
886+
thread.current_stmt_id = next_stmt_id;
887+
return Ok(ThreadResult::ExplicitFork {
888+
parent: Box::new(thread),
889+
});
890+
}
891+
// If another thread from the same start cycle,
892+
// has already forked in this cycle,
893+
// we just fall through to the normal Step logic below
894+
}
895+
871896
info!(
872897
"Thread {} (transaction `{}`) called `step()`, moving to `next` queue",
873898
thread.global_thread_id(ctx),

0 commit comments

Comments
 (0)