Skip to main content

std/sys/thread/
mod.rs

1cfg_select! {
2    target_os = "hermit" => {
3        mod hermit;
4        pub use hermit::{Thread, available_parallelism, sleep, yield_now, DEFAULT_MIN_STACK_SIZE};
5        #[expect(dead_code)]
6        mod unsupported;
7        pub use unsupported::{current_os_id, set_name};
8    }
9    target_os = "motor" => {
10        mod motor;
11        pub use motor::*;
12    }
13    all(target_vendor = "fortanix", target_env = "sgx") => {
14        mod sgx;
15        pub use sgx::{Thread, current_os_id, sleep, yield_now, DEFAULT_MIN_STACK_SIZE};
16
17        // SGX should protect in-enclave data from outside attackers, so there
18        // must not be any data leakage to the OS, particularly no 1-1 mapping
19        // between SGX thread names and OS thread names. Hence `set_name` is
20        // intentionally a no-op.
21        //
22        // Note that the internally visible SGX thread name is already provided
23        // by the platform-agnostic Rust thread code. This can be observed in
24        // the [`std::thread::tests::test_named_thread`] test, which succeeds
25        // as-is with the SGX target.
26        #[expect(dead_code)]
27        mod unsupported;
28        pub use unsupported::{available_parallelism, set_name};
29    }
30    target_os = "solid_asp3" => {
31        mod solid;
32        pub use solid::{Thread, sleep, yield_now, DEFAULT_MIN_STACK_SIZE};
33        #[expect(dead_code)]
34        mod unsupported;
35        pub use unsupported::{available_parallelism, current_os_id, set_name};
36    }
37    target_os = "teeos" => {
38        mod teeos;
39        pub use teeos::{Thread, sleep, yield_now, DEFAULT_MIN_STACK_SIZE};
40        #[expect(dead_code)]
41        mod unsupported;
42        pub use unsupported::{available_parallelism, current_os_id, set_name};
43    }
44    target_os = "uefi" => {
45        mod uefi;
46        pub use uefi::{available_parallelism, sleep};
47        #[expect(dead_code)]
48        mod unsupported;
49        pub use unsupported::{Thread, current_os_id, set_name, yield_now, DEFAULT_MIN_STACK_SIZE};
50    }
51    any(target_family = "unix", target_os = "wasi") => {
52        mod unix;
53        pub use unix::{Thread, available_parallelism, current_os_id, sleep, yield_now, DEFAULT_MIN_STACK_SIZE};
54        #[cfg(not(any(
55            target_env = "newlib",
56            target_os = "l4re",
57            target_os = "emscripten",
58            target_os = "redox",
59            target_os = "hurd",
60            target_os = "aix",
61            target_os = "wasi",
62        )))]
63        pub use unix::set_name;
64        #[cfg(any(
65            target_os = "freebsd",
66            target_os = "netbsd",
67            target_os = "linux",
68            target_os = "android",
69            target_os = "solaris",
70            target_os = "illumos",
71            target_os = "dragonfly",
72            target_os = "hurd",
73            target_os = "fuchsia",
74            target_os = "vxworks",
75            target_os = "wasi",
76            target_vendor = "apple",
77        ))]
78        pub use unix::sleep_until;
79        #[expect(dead_code)]
80        mod unsupported;
81        #[cfg(any(
82            target_env = "newlib",
83            target_os = "l4re",
84            target_os = "emscripten",
85            target_os = "redox",
86            target_os = "hurd",
87            target_os = "aix",
88            target_os = "wasi",
89        ))]
90        pub use unsupported::set_name;
91    }
92    target_os = "vexos" => {
93        mod vexos;
94        pub use vexos::{sleep, sleep_until, yield_now};
95        #[expect(dead_code)]
96        mod unsupported;
97        pub use unsupported::{Thread, available_parallelism, current_os_id, set_name, DEFAULT_MIN_STACK_SIZE};
98    }
99    all(target_family = "wasm", target_feature = "atomics") => {
100        mod wasm;
101        pub use wasm::sleep;
102
103        #[expect(dead_code)]
104        mod unsupported;
105        pub use unsupported::{Thread, available_parallelism, current_os_id, set_name, yield_now, DEFAULT_MIN_STACK_SIZE};
106    }
107    target_os = "windows" => {
108        mod windows;
109        pub use windows::{Thread, available_parallelism, current_os_id, set_name, set_name_wide, sleep, yield_now, DEFAULT_MIN_STACK_SIZE};
110    }
111    target_os = "xous" => {
112        mod xous;
113        pub use xous::{Thread, available_parallelism, sleep, yield_now, DEFAULT_MIN_STACK_SIZE};
114
115        #[expect(dead_code)]
116        mod unsupported;
117        pub use unsupported::{current_os_id, set_name};
118    }
119    _ => {
120        mod unsupported;
121        pub use unsupported::{Thread, available_parallelism, current_os_id, set_name, sleep, yield_now, DEFAULT_MIN_STACK_SIZE};
122    }
123}
124
125#[cfg(not(any(
126    target_os = "freebsd",
127    target_os = "netbsd",
128    target_os = "linux",
129    target_os = "android",
130    target_os = "solaris",
131    target_os = "illumos",
132    target_os = "dragonfly",
133    target_os = "hurd",
134    target_os = "fuchsia",
135    target_os = "vxworks",
136    target_os = "wasi",
137    target_vendor = "apple",
138    target_os = "motor",
139    target_os = "vexos"
140)))]
141pub fn sleep_until(deadline: crate::time::Instant) {
142    use crate::time::Instant;
143
144    // The clock source used for `sleep` might not be the same used for `Instant`.
145    // Since this function *must not* return before the deadline, we recheck the
146    // time after every call to `sleep`. See #149935 for an example of this
147    // occurring on older Windows systems.
148    while let Some(delay) = deadline.checked_duration_since(Instant::now()) {
149        // Sleep for the estimated time remaining until the deadline.
150        //
151        // If your system has a better way of estimating the delay time or
152        // provides a way to sleep until an absolute time, specialize this
153        // function for your system.
154        sleep(delay);
155    }
156}