lenso_kernel/
deterministic.rs1use super::{
2 AbortHandle, Abortable, AssertUnwindSafe, Cell, DriverTask, Duration, Future, FutureExt,
3 LocalBoxFuture, LocalPool, LocalSpawnExt, LocalSpawner, LocalTask, Poll, Rc, RefCell,
4 RuntimeDriver, SpawnError, TaskOutcome, oneshot,
5};
6
7#[derive(Debug)]
8pub(super) struct DeterministicState {
9 pub(super) now: Cell<Duration>,
10 pub(super) shutdown_requested: Cell<bool>,
11 pub(super) jitter: Cell<Duration>,
12 pub(super) pool: RefCell<Option<LocalPool>>,
13 pub(super) spawner: LocalSpawner,
14 pub(super) timers: RefCell<Vec<(Duration, oneshot::Sender<()>)>>,
15}
16
17#[derive(Clone, Debug)]
19pub struct DeterministicDriver {
20 pub(super) state: Rc<DeterministicState>,
21}
22
23impl DeterministicDriver {
24 pub fn new() -> Self {
26 let pool = LocalPool::new();
27 let spawner = pool.spawner();
28 Self {
29 state: Rc::new(DeterministicState {
30 now: Cell::new(Duration::ZERO),
31 shutdown_requested: Cell::new(false),
32 jitter: Cell::new(Duration::ZERO),
33 pool: RefCell::new(Some(pool)),
34 spawner,
35 timers: RefCell::new(Vec::new()),
36 }),
37 }
38 }
39
40 pub fn run<F: Future>(&self, future: F) -> F::Output {
42 let mut pool = self
43 .state
44 .pool
45 .borrow_mut()
46 .take()
47 .expect("deterministic Driver cannot run recursively");
48 let output = pool.run_until(future);
49 self.state.pool.replace(Some(pool));
50 output
51 }
52
53 pub fn advance(&self, duration: Duration) {
55 self.state.now.set(self.state.now.get() + duration);
56 let now = self.state.now.get();
57 let mut timers = self.state.timers.borrow_mut();
58 let mut pending = Vec::with_capacity(timers.len());
59 for (deadline, wakeup) in timers.drain(..) {
60 if deadline <= now {
61 let _ = wakeup.send(());
62 } else {
63 pending.push((deadline, wakeup));
64 }
65 }
66 *timers = pending;
67 }
68
69 pub fn request_shutdown(&self) {
71 self.state.shutdown_requested.set(true);
72 }
73
74 pub fn now(&self) -> Duration {
76 self.state.now.get()
77 }
78
79 pub fn set_jitter(&self, jitter: Duration) {
81 self.state.jitter.set(jitter);
82 }
83
84 #[must_use]
86 pub fn with_jitter(self, jitter: Duration) -> Self {
87 self.set_jitter(jitter);
88 self
89 }
90}
91
92impl Default for DeterministicDriver {
93 fn default() -> Self {
94 Self::new()
95 }
96}
97
98impl RuntimeDriver for DeterministicDriver {
99 fn now(&self) -> Duration {
100 self.now()
101 }
102
103 fn sleep_until(&self, deadline: Duration) -> LocalBoxFuture<'static, ()> {
104 if deadline <= self.now() {
105 return Box::pin(futures::future::ready(()));
106 }
107 let (wakeup, sleeper) = oneshot::channel();
108 self.state.timers.borrow_mut().push((deadline, wakeup));
109 Box::pin(async move {
110 let _ = sleeper.await;
111 })
112 }
113
114 fn yield_now(&self) -> LocalBoxFuture<'static, ()> {
115 let mut yielded = false;
116 Box::pin(futures::future::poll_fn(move |context| {
117 if yielded {
118 Poll::Ready(())
119 } else {
120 yielded = true;
121 context.waker().wake_by_ref();
122 Poll::Pending
123 }
124 }))
125 }
126
127 fn jitter(&self, maximum: Duration) -> Duration {
128 self.state.jitter.get().min(maximum)
129 }
130
131 fn spawn_local(&self, task: LocalTask) -> Result<DriverTask, SpawnError> {
132 let (abort, registration) = AbortHandle::new_pair();
133 let (completed, completion) = oneshot::channel();
134 self.state.spawner.spawn_local(async move {
135 let outcome = match AssertUnwindSafe(Abortable::new(task, registration))
136 .catch_unwind()
137 .await
138 {
139 Ok(Ok(())) => TaskOutcome::Completed,
140 Ok(Err(_)) => TaskOutcome::Cancelled,
141 Err(_) => TaskOutcome::Failed,
142 };
143 let _ = completed.send(outcome);
144 })?;
145 Ok(DriverTask::new(abort, completion))
146 }
147
148 fn shutdown_requested(&self) -> bool {
149 self.state.shutdown_requested.get()
150 }
151}