Skip to main content

rayon_pool/
rayon_pool.rs

1//! Runs links inside a rayon pool the caller owns, several at once.
2//!
3//! ```sh
4//! cargo run --example rayon_pool
5//! ```
6//!
7//! A link called inside [`rayon::ThreadPool::install`] runs its parallel
8//! stages on that pool's threads instead of creating its own (unless
9//! [`LinkOptions::threads`] asks for a specific count). qld keeps no global
10//! state, so links can also run concurrently, here one per task of a
11//! parallel iterator; the output does not depend on the thread count.
12
13#[path = "support/objects.rs"]
14mod objects;
15
16use rayon::prelude::*;
17
18use qld::args::{InputAttrs, InputKind, LinkOptions, OutputBuffer, OutputKind};
19use qld::diag::Collect;
20
21/// Links a program that exits with `value`, into memory.
22fn link(value: u8) -> qld::Result<Vec<u8>> {
23    let mut options = LinkOptions::new();
24    options.kind = OutputKind::StaticExecutable;
25    options.push_input(
26        InputKind::bytes("main.o", objects::main_object()),
27        InputAttrs::default(),
28    );
29    options.push_input(
30        InputKind::bytes("answer.o", objects::answer_object(value)),
31        InputAttrs::default(),
32    );
33    let buffer = OutputBuffer::new();
34    options.output_buffer = Some(buffer.clone());
35    qld::link(&options, &Collect::new())?;
36    buffer
37        .take()
38        .ok_or_else(|| qld::Error::Internal("no output".into()))
39}
40
41fn main() -> qld::Result<()> {
42    let pool = rayon::ThreadPoolBuilder::new()
43        .num_threads(4)
44        .thread_name(|index| format!("build-worker-{index}"))
45        .build()
46        .map_err(|error| qld::Error::Internal(error.to_string()))?;
47
48    // One link, on the pool's threads.
49    let single = pool.install(|| link(1))?;
50    println!("one link in the pool: {} bytes", single.len());
51
52    // Sixteen links sharing the pool with each other.
53    let images = pool.install(|| {
54        (0..16u8)
55            .into_par_iter()
56            .map(link)
57            .collect::<qld::Result<Vec<_>>>()
58    })?;
59    println!("{} concurrent links in the pool", images.len());
60    assert_eq!(images[1], single, "the same inputs give the same output");
61
62    // Outside any pool, the same link gives the same bytes.
63    assert_eq!(link(1)?, single);
64    Ok(())
65}