binius_utils/rayon/config.rs
1// Copyright 2024-2025 Irreducible Inc.
2
3use cfg_if::cfg_if;
4
5use super::ThreadPoolBuildError;
6
7/// Builds the global rayon pool on the current thread when `RAYON_NUM_THREADS=1`.
8///
9/// A one-thread pool with `use_current_thread` buys two things over rayon's default:
10///
11/// 1. Throughput close to a build with rayon compiled out.
12/// 2. Call stacks with no worker frames, which keeps profiles and debugger sessions readable.
13///
14/// Call this before anything touches the pool — rayon builds the global pool on first use, and
15/// refuses to build it twice. That first use is what the returned error reports, so callers that
16/// cannot guarantee they run first should treat it as advisory rather than fatal.
17///
18/// Calling it more than once is harmless: the result is computed once and cached.
19///
20/// # Returns
21///
22/// A reference, because [`ThreadPoolBuildError`] is not `Clone`.
23pub fn adjust_thread_pool() -> &'static Result<(), ThreadPoolBuildError> {
24 cfg_if! {
25 if #[cfg(feature = "rayon")] {
26 use std::sync::OnceLock;
27
28 static ONCE_GUARD: OnceLock<Result<(), ThreadPoolBuildError>> = OnceLock::new();
29
30 ONCE_GUARD.get_or_init(|| {
31 // Read the environment rather than `current_num_threads`: that call would build
32 // the global pool, leaving nothing to override.
33 match std::env::var("RAYON_NUM_THREADS") {
34 Ok(v) if v == "1" => super::ThreadPoolBuilder::new()
35 .num_threads(1)
36 .use_current_thread()
37 .build_global(),
38 _ => Ok(()),
39 }
40 })
41 }
42 else {
43 static RESULT: Result<(), ThreadPoolBuildError> = Ok(());
44
45 &RESULT
46 }
47 }
48}