pub struct ThreadTree { /* private fields */ }
Expand description
A hierarchical thread pool used for splitting work in a branching fashion.
See ThreadTree::new_with_level()
to create a new thread tree,
and see ThreadTree::top()
for a usage example.
The thread tree has the benefit that at each level, jobs can be sent directly to the thread that is going to execute it - that means there is no contention between waiting threads. The downside is that the structure of the thread tree is rather static.
Implementations§
Source§impl ThreadTree
impl ThreadTree
Sourcepub const fn new_level0() -> Self
pub const fn new_level0() -> Self
Create a level 0 tree (with no parallelism)
Sourcepub fn new_with_level(level: usize) -> Box<Self>
pub fn new_with_level(level: usize) -> Box<Self>
Create an n-level thread tree with 2n leaves
Level 0 has no parallelism Level 1 has two nodes Level 2 has four nodes (et.c.)
Level must be <= 12; panics on invalid input
Sourcepub fn is_parallel(&self) -> bool
pub fn is_parallel(&self) -> bool
Return true if this is a non-dummy pool which will parallelize in join
Sourcepub fn top(&self) -> ThreadTreeCtx<'_>
pub fn top(&self) -> ThreadTreeCtx<'_>
Get the top thread tree context, where we can inject tasks with join. Each job gets a sub-context that can be used to inject tasks further down the corresponding branch of the tree.
Note to avoid deadlocks, tasks should never be injected into a tree context that doesn’t belong to the current level. To avoid this should be easy - only call .top() at the top level.
The following example shows using a two-level tree and using context to spawn tasks.
use thread_tree::{ThreadTree, ThreadTreeCtx};
let tp = ThreadTree::new_with_level(2);
fn f(index: i32, ctx: ThreadTreeCtx<'_>) -> i32 {
// do work in subtasks here
let (a, b) = ctx.join(move |_| index + 1, |_| index + 2);
return a + b;
}
let (r0, r1) = tp.top().join(|ctx| f(0, ctx), |ctx| f(1, ctx));
assert_eq!(r0 + r1, (0 + 1) + (0 + 2) + (1 + 1) + (1 + 2));