summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_data_structures/src/jobserver.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_data_structures/src/jobserver.rs')
-rw-r--r--compiler/rustc_data_structures/src/jobserver.rs40
1 files changed, 40 insertions, 0 deletions
diff --git a/compiler/rustc_data_structures/src/jobserver.rs b/compiler/rustc_data_structures/src/jobserver.rs
new file mode 100644
index 000000000..09baa3095
--- /dev/null
+++ b/compiler/rustc_data_structures/src/jobserver.rs
@@ -0,0 +1,40 @@
+pub use jobserver_crate::Client;
+use std::sync::LazyLock;
+
+// We can only call `from_env` once per process
+
+// Note that this is unsafe because it may misinterpret file descriptors
+// on Unix as jobserver file descriptors. We hopefully execute this near
+// the beginning of the process though to ensure we don't get false
+// positives, or in other words we try to execute this before we open
+// any file descriptors ourselves.
+//
+// Pick a "reasonable maximum" if we don't otherwise have
+// a jobserver in our environment, capping out at 32 so we
+// don't take everything down by hogging the process run queue.
+// The fixed number is used to have deterministic compilation
+// across machines.
+//
+// Also note that we stick this in a global because there could be
+// multiple rustc instances in this process, and the jobserver is
+// per-process.
+static GLOBAL_CLIENT: LazyLock<Client> = LazyLock::new(|| unsafe {
+ Client::from_env().unwrap_or_else(|| {
+ let client = Client::new(32).expect("failed to create jobserver");
+ // Acquire a token for the main thread which we can release later
+ client.acquire_raw().ok();
+ client
+ })
+});
+
+pub fn client() -> Client {
+ GLOBAL_CLIENT.clone()
+}
+
+pub fn acquire_thread() {
+ GLOBAL_CLIENT.acquire_raw().ok();
+}
+
+pub fn release_thread() {
+ GLOBAL_CLIENT.release_raw().ok();
+}