Skip to main content

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}