Skip to content

Commit 2e1ffeb

Browse files
author
Dylan Wolff
committed
CR: adding comments; reset --> new_execution; other small cleanups
1 parent 8d2436f commit 2e1ffeb

File tree

6 files changed

+23
-21
lines changed

6 files changed

+23
-21
lines changed

shuttle/src/runtime/execution.rs

Lines changed: 12 additions & 13 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::{backtrace_enabled, Config, MaxSteps};
@@ -136,6 +136,15 @@ impl StepError {
136136
}
137137
}
138138

139+
/// While there are no runnable tasks and tasks are able to be woken by the time model, continually wakes tasks.
140+
/// The TimeModel's `wake_next` method is called in a loop in case there are stale wakers which do not actually
141+
/// result in a newly runnable task when woken. Requires access to the ExecutionState to obtain a reference to the
142+
/// time model.
143+
fn wake_sleepers_until_runnable() {
144+
let tm = get_time_model();
145+
while ExecutionState::num_runnable() == 0 && tm.borrow_mut().wake_next() {}
146+
}
147+
139148
impl Execution {
140149
/// Run a function to be tested, taking control of scheduling it and any tasks it might spawn.
141150
/// This function runs until `f` and all tasks spawned by `f` have terminated, or until the
@@ -254,12 +263,7 @@ impl Execution {
254263
#[inline]
255264
fn run_to_competion(&mut self, immediately_return_on_panic: bool) -> Result<(), StepError> {
256265
loop {
257-
// While there are no runnable tasks and tasks are able to be woken by the time model, continue waking tasks
258-
while ExecutionState::num_runnable() == 0
259-
&& ExecutionState::with(|s| Rc::clone(&s.time_model))
260-
.borrow_mut()
261-
.wake_next()
262-
{}
266+
wake_sleepers_until_runnable();
263267
let next_step: Option<Rc<RefCell<PooledContinuation>>> = ExecutionState::with(|state| {
264268
state.schedule()?;
265269
state.advance_to_next_task();
@@ -650,12 +654,7 @@ impl ExecutionState {
650654
/// is different from the currently running task, indicating that the current task should yield
651655
/// its execution.
652656
pub(crate) fn maybe_yield() -> bool {
653-
// While there are no runnable tasks and tasks are able to be woken by the time model, continue waking tasks
654-
while ExecutionState::num_runnable() == 0
655-
&& ExecutionState::with(|s| Rc::clone(&s.time_model))
656-
.borrow_mut()
657-
.wake_next()
658-
{}
657+
wake_sleepers_until_runnable();
659658

660659
Self::with(|state| {
661660
if std::thread::panicking() {

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)