forte/lib.rs
1//! An async-compatible thread-pool aiming for "speed through simplicity".
2//!
3//! Forte is a parallel & async work scheduler designed to accommodate very large
4//! workloads with many short-lived tasks. It replicates the `rayon_core` api
5//! but with native support for futures and async tasks. Its design was
6//! prompted by the needs of the bevy game engine, but should be applicable to
7//! any problem that involves running both synchronous and asynchronous work
8//! concurrently.
9//!
10//! The thread-pool provided by this crate does not employ work-stealing. Forte
11//! instead uses "Heartbeat Scheduling", an alternative load-balancing technique
12//! that (theoretically) provides provably small overheads and good utilization.
13//! The end effect is that work is only parallelized every so often, allowing
14//! more work to be done sequentially on each thread and amortizing the
15//! synchronization overhead.
16//!
17//! # Acknowledgments
18//!
19//! Large portions of the code are direct ports from various versions of
20//! `rayon_core`, with minor simplifications and improvements. We also relied
21//! upon `chili` and `spice` for reference while writing the heartbeat
22//! scheduling. Support for futures is based on an approach sketched out by
23//! members of the `rayon` community to whom we are deeply indebted.
24
25#![no_std]
26#![cfg_attr(feature = "shuttle", allow(dead_code))]
27#![cfg_attr(feature = "shuttle", allow(unused_imports))]
28
29// -----------------------------------------------------------------------------
30// Boilerplate for building without the standard library
31
32extern crate alloc;
33extern crate std;
34
35// -----------------------------------------------------------------------------
36// Modules
37
38mod blocker;
39mod job;
40mod scope;
41mod signal;
42mod thread_pool;
43mod unwind;
44
45// -----------------------------------------------------------------------------
46// Top-level exports
47
48pub use scope::Scope;
49pub use thread_pool::ThreadPool;
50pub use thread_pool::Worker;
51pub use thread_pool::Yield;
52pub use thread_pool::block_on;
53pub use thread_pool::join;
54pub use thread_pool::scope;
55pub use thread_pool::spawn;
56pub use thread_pool::spawn_async;
57pub use thread_pool::spawn_future;
58
59// -----------------------------------------------------------------------------
60// Platform Support
61
62// This crate uses `shuttle` for testing, which requires mocking all of the core
63// threading primitives (`Mutex` and the like).
64//
65// To make things a bit simpler, we re-export all the important types in the
66// `primitives` module.
67
68#[cfg(not(feature = "shuttle"))]
69mod platform {
70
71 // Core exports
72
73 pub use alloc::sync::Arc;
74 pub use alloc::sync::Weak;
75 pub use core::sync::atomic::AtomicBool;
76 pub use core::sync::atomic::AtomicU32;
77 pub use core::sync::atomic::Ordering;
78 pub use std::sync::Barrier;
79 pub use std::sync::Condvar;
80 pub use std::sync::Mutex;
81 pub use std::thread::Builder as ThreadBuilder;
82 pub use std::thread::JoinHandle;
83 pub use std::thread::available_parallelism;
84 pub use std::thread_local;
85}
86
87#[cfg(feature = "shuttle")]
88mod platform {
89
90 // Core exports
91
92 pub use shuttle::sync::Arc;
93 pub use shuttle::sync::Barrier;
94 pub use shuttle::sync::Condvar;
95 pub use shuttle::sync::Mutex;
96 pub use shuttle::sync::Weak;
97 pub use shuttle::sync::atomic::AtomicBool;
98 pub use shuttle::sync::atomic::AtomicU32;
99 pub use shuttle::sync::atomic::Ordering;
100 pub use shuttle::thread::Builder as ThreadBuilder;
101 pub use shuttle::thread::JoinHandle;
102 pub use shuttle::thread_local;
103
104 // Available parallelism
105
106 pub fn available_parallelism() -> std::io::Result<core::num::NonZero<usize>> {
107 panic!("available_parallelism does not work on shuttle");
108 }
109}