Skip to content

Commit d6d5ee7

Browse files
author
Dylan Wolff
committed
CR: adding comments; reset --> new_execution; other small cleanups
1 parent 95b637b commit d6d5ee7

File tree

6 files changed

+23
-22
lines changed

6 files changed

+23
-22
lines changed

shuttle/src/runtime/execution.rs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::runtime::task::labels::Labels;
55
use crate::runtime::task::{ChildLabelFn, Task, TaskId, TaskName, TaskSignature, DEFAULT_INLINE_TASKS};
66
use crate::runtime::thread::continuation::PooledContinuation;
77
use crate::scheduler::{Schedule, Scheduler};
8-
use crate::sync::time::TimeModel;
8+
use crate::sync::time::{get_time_model, TimeModel};
99
use crate::sync::{ResourceSignature, ResourceType};
1010
use crate::thread::thread_fn;
1111
use crate::{Config, MaxSteps};
@@ -73,6 +73,15 @@ fn backtrace_enabled() -> bool {
7373
std::env::var("RUST_BACKTRACE").is_ok() || std::env::var("RUST_LIB_BACKTRACE").is_ok()
7474
}
7575

76+
/// While there are no runnable tasks and tasks are able to be woken by the time model, continually wakes tasks.
77+
/// The TimeModel's `wake_next` method is called in a loop in case there are stale wakers which do not actually
78+
/// result in a newly runnable task when woken. Requires access to the ExecutionState to obtain a reference to the
79+
/// time model.
80+
fn wake_sleepers_until_runnable() {
81+
let tm = get_time_model();
82+
while ExecutionState::num_runnable() == 0 && tm.borrow_mut().wake_next() {}
83+
}
84+
7685
impl Execution {
7786
/// Run a function to be tested, taking control of scheduling it and any tasks it might spawn.
7887
/// This function runs until `f` and all tasks spawned by `f` have terminated, or until the
@@ -103,7 +112,6 @@ impl Execution {
103112

104113
// Cleanup the state before it goes out of `EXECUTION_STATE` scope
105114
ExecutionState::cleanup();
106-
self.time_model.borrow_mut().reset();
107115
});
108116
}
109117

@@ -116,12 +124,7 @@ impl Execution {
116124
Finished,
117125
}
118126

119-
// While there are no runnable tasks and tasks are able to be woken by the time model, continue waking tasks
120-
while ExecutionState::num_runnable() == 0
121-
&& ExecutionState::with(|s| Rc::clone(&s.time_model))
122-
.borrow_mut()
123-
.wake_next()
124-
{}
127+
wake_sleepers_until_runnable();
125128

126129
let next_step = ExecutionState::with(|state| {
127130
if let Err(msg) = state.schedule() {
@@ -596,12 +599,7 @@ impl ExecutionState {
596599
/// is different from the currently running task, indicating that the current task should yield
597600
/// its execution.
598601
pub(crate) fn maybe_yield() -> bool {
599-
// While there are no runnable tasks and tasks are able to be woken by the time model, continue waking tasks
600-
while ExecutionState::num_runnable() == 0
601-
&& ExecutionState::with(|s| Rc::clone(&s.time_model))
602-
.borrow_mut()
603-
.wake_next()
604-
{}
602+
wake_sleepers_until_runnable();
605603

606604
Self::with(|state| {
607605
debug_assert!(

shuttle/src/runtime/runner.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ impl<S: Scheduler + 'static, T: TimeModel + 'static> Runner<S, T> {
111111
None => break,
112112
Some(s) => s,
113113
};
114+
self.time_model.borrow_mut().new_execution();
114115

115116
let execution = Execution::new(self.scheduler.clone(), schedule, self.time_model.clone());
116117
let f = Arc::clone(&f);

shuttle/src/runtime/thread/continuation.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#![allow(deprecated)]
66

77
use crate::runtime::execution::ExecutionState;
8+
use crate::sync::time::get_time_model;
89
use generator::{Generator, Gn};
910
use scoped_tls::scoped_thread_local;
1011
use std::cell::{Cell, RefCell};
@@ -262,7 +263,7 @@ pub(crate) fn switch() {
262263
let r = generator::yield_(ContinuationOutput::Yielded).unwrap();
263264
assert!(matches!(r, ContinuationInput::Resume));
264265
}
265-
ExecutionState::with(|s| Rc::clone(&s.time_model)).borrow_mut().step();
266+
get_time_model().borrow_mut().step()
266267
}
267268

268269
#[cfg(test)]

shuttle/src/sync/time/constant_stepped.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::{
44
task::Waker,
55
};
66

7-
use tracing::{debug, warn};
7+
use tracing::{trace, warn};
88

99
use crate::{current::TaskId, runtime::execution::ExecutionState};
1010

@@ -73,12 +73,12 @@ impl TimeModel for ConstantSteppedTimeModel {
7373
}
7474

7575
fn step(&mut self) {
76-
debug!("step");
7776
self.current_time_elapsed += self.current_step_size;
77+
trace!("time step to {:?}", self.current_time_elapsed);
7878
self.unblock_expired();
7979
}
8080

81-
fn reset(&mut self) {
81+
fn new_execution(&mut self) {
8282
self.current_step_size = self.distribution.sample();
8383
self.current_time_elapsed = std::time::Duration::from_secs(0);
8484
self.waiters.clear();

shuttle/src/sync/time/frozen.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ impl TimeModel for FrozenTimeModel {
100100

101101
fn step(&mut self) {}
102102

103-
fn reset(&mut self) {
104-
self.inner.reset();
103+
fn new_execution(&mut self) {
104+
self.inner.new_execution();
105105
self.expired.clear();
106106
self.triggers.clear();
107107
}

shuttle/src/sync/time/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub trait TimeModel: std::fmt::Debug {
5151
/// Called when all tasks are blocked to resolve timing based deadlocks (all unblocked tasks are sleeping).
5252
fn wake_next(&mut self) -> bool;
5353
/// Reset the TimeModel state for the next Shuttle iteration
54-
fn reset(&mut self);
54+
fn new_execution(&mut self);
5555
/// Callback after each scheduling step to allow the TimeModel to update itself
5656
fn step(&mut self);
5757
/// Used to create the TimeModel's Instant struct in functions like Instant::now()
@@ -71,7 +71,8 @@ pub trait TimeModel: std::fmt::Debug {
7171
fn as_any_mut(&mut self) -> &mut dyn std::any::Any;
7272
}
7373

74-
/// Provides a reference to the current TimeModel for this execution
74+
/// Provides a reference to the current TimeModel for this execution.
75+
/// Uses `Rc::clone` so that ExecutionState isn't already borrowed when running most TimeModel methods
7576
pub fn get_time_model() -> Rc<RefCell<dyn TimeModel>> {
7677
ExecutionState::with(|s| Rc::clone(&s.time_model))
7778
}

0 commit comments

Comments
 (0)