Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
595 changes: 531 additions & 64 deletions crates/runtime-core/src/sim/executor/mod.rs

Large diffs are not rendered by default.

22 changes: 13 additions & 9 deletions crates/runtime-core/src/sim/executor/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@ use core::{

use spin::Mutex;

use super::NodeId;
use super::TaskMeta;

/// A spawned simulated task.
///
/// Two handles reference the same underlying allocation:
/// - `JoinHandle` awaits the output and holds an `AbortHandle` for cancellation.
/// - The executor holds the `Runnable` (not visible here).
pub struct JoinHandle<T> {
// async_task::Task owns a shared heap-allocated cell that holds the future,
// its output, metadata (NodeId), and waker. Polling it drives the future
// to completion. Dropping it without detach cancels the future.
pub(crate) task: async_task::Task<Result<T, JoinError>, NodeId>,
// async_task::FallibleTask owns a shared heap-allocated cell that holds the
// future, output, task metadata, and waker. `None` means the executor
// intentionally dropped the runnable before polling it.
pub(crate) task: async_task::FallibleTask<Result<T, JoinError>, TaskMeta>,
// Clone of the same AbortHandle that Abortable holds inside the task.
pub(crate) abort: AbortHandle,
}
Expand All @@ -33,16 +33,20 @@ impl<T> JoinHandle<T> {

/// Drop the join handle without cancelling the task.
pub fn detach(self) {
// async_task::Task::detach makes Drop a no-op the future keeps running.
// async_task::Task::detach makes Drop a no-op; the future keeps running.
self.task.detach();
}

/// Poll the underlying async_task::Task for its output.
#[doc(hidden)]
pub fn poll_join(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<T, JoinError>> {
// async_task::Task implements Future. Polling it drives the wrapped
// Abortable future inside the executor.
Pin::new(&mut self.task).poll(cx)
// FallibleTask lets node crash discard stale runnables without panicking
// when their JoinHandle is awaited.
match Pin::new(&mut self.task).poll(cx) {
Poll::Ready(Some(result)) => Poll::Ready(result),
Poll::Ready(None) => Poll::Ready(Err(JoinError)),
Poll::Pending => Poll::Pending,
}
}
}

Expand Down
7 changes: 5 additions & 2 deletions crates/runtime-core/src/sim/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
pub mod buggify;
mod executor;
pub mod net;
mod probability;
mod rng;
pub mod time;

pub use executor::{
yield_now, AbortHandle, Handle, JoinError, JoinHandle, Node, NodeBuilder, NodeId, Runtime, RuntimeConfig,
yield_now, AbortHandle, Handle, JoinError, JoinHandle, Node, NodeBuilder, NodeFaultOptions, NodeId, Runtime,
RuntimeConfig,
};
#[doc(hidden)]
pub use rng::DeterminismLog;
pub use rng::{GlobalRng, Rng};
pub use rng::{GlobalRng, Ratio, Rng};
Loading
Loading