1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//! nuclei's own runtime: thread-per-core shards that run tasks, a blocking
//! pool, and the functions that place work on them.
//!
//! A [`Runtime`] runs one shard per worker thread. A shard owns its run
//! queue, its timers and its poller, and a task stays on the shard it was
//! placed on: [`spawn`] keeps it near the spawning thread's other tasks
//! within a margin of load (see [`Builder::local_spawn_margin`]),
//! [`spawn_local`] keeps it on the calling thread. [`block_on`] runs a
//! future on the calling thread and nests: called from a task, it keeps the
//! shard running its other tasks until the future completes.
//!
//! [`RuntimeHandle::spawn_on_worker`], [`RuntimeHandle::on_each_worker`] and
//! [`task::Builder::worker`](crate::task::Builder::worker) place a task on a
//! worker the caller names, where it stays; [`shard_local!`](crate::shard_local)
//! keeps a [`ShardLocal`](crate::runtime::ShardLocal) value per worker, which moves with the worker's
//! shard when a handoff gives the shard to another thread.
//!
//! The free functions use the runtime the calling thread is inside, or the
//! process default runtime, which starts on first use with no configuration
//! (one worker per core). [`Builder`] sets everything else, and
//! [`Runtime::stats`] reads one runtime's counters.
//!
//! ```
//! use nuclei::runtime::{Runtime, spawn};
//!
//! let runtime = Runtime::builder().worker_threads(2).build().unwrap();
//! let sum = runtime.block_on(async {
//! let tasks: Vec<_> = (0..4u64).map(|n| spawn(async move { n * n })).collect();
//! let mut sum = 0;
//! for task in tasks {
//! sum += task.await;
//! }
//! sum
//! });
//! assert_eq!(sum, 14);
//! ```
pub use crate;
pub use crate;
pub use crate;