| 1 | cfg_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 = "vxworks" , |
| 74 | target_os = "wasi" , |
| 75 | target_vendor = "apple" , |
| 76 | ))] |
| 77 | pub use unix::sleep_until; |
| 78 | #[expect(dead_code)] |
| 79 | mod unsupported; |
| 80 | #[cfg(any( |
| 81 | target_env = "newlib" , |
| 82 | target_os = "l4re" , |
| 83 | target_os = "emscripten" , |
| 84 | target_os = "redox" , |
| 85 | target_os = "hurd" , |
| 86 | target_os = "aix" , |
| 87 | target_os = "wasi" , |
| 88 | ))] |
| 89 | pub use unsupported::set_name; |
| 90 | } |
| 91 | target_os = "vexos" => { |
| 92 | mod vexos; |
| 93 | pub use vexos::{sleep, sleep_until, yield_now}; |
| 94 | #[expect(dead_code)] |
| 95 | mod unsupported; |
| 96 | pub use unsupported::{Thread, available_parallelism, current_os_id, set_name, DEFAULT_MIN_STACK_SIZE}; |
| 97 | } |
| 98 | all(target_family = "wasm" , target_feature = "atomics" ) => { |
| 99 | mod wasm; |
| 100 | pub use wasm::sleep; |
| 101 | |
| 102 | #[expect(dead_code)] |
| 103 | mod unsupported; |
| 104 | pub use unsupported::{Thread, available_parallelism, current_os_id, set_name, yield_now, DEFAULT_MIN_STACK_SIZE}; |
| 105 | } |
| 106 | target_os = "windows" => { |
| 107 | mod windows; |
| 108 | pub use windows::{Thread, available_parallelism, current_os_id, set_name, set_name_wide, sleep, yield_now, DEFAULT_MIN_STACK_SIZE}; |
| 109 | } |
| 110 | target_os = "xous" => { |
| 111 | mod xous; |
| 112 | pub use xous::{Thread, available_parallelism, sleep, yield_now, DEFAULT_MIN_STACK_SIZE}; |
| 113 | |
| 114 | #[expect(dead_code)] |
| 115 | mod unsupported; |
| 116 | pub use unsupported::{current_os_id, set_name}; |
| 117 | } |
| 118 | _ => { |
| 119 | mod unsupported; |
| 120 | pub use unsupported::{Thread, available_parallelism, current_os_id, set_name, sleep, yield_now, DEFAULT_MIN_STACK_SIZE}; |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | #[cfg (not(any( |
| 125 | target_os = "freebsd" , |
| 126 | target_os = "netbsd" , |
| 127 | target_os = "linux" , |
| 128 | target_os = "android" , |
| 129 | target_os = "solaris" , |
| 130 | target_os = "illumos" , |
| 131 | target_os = "dragonfly" , |
| 132 | target_os = "hurd" , |
| 133 | target_os = "vxworks" , |
| 134 | target_os = "wasi" , |
| 135 | target_vendor = "apple" , |
| 136 | target_os = "motor" , |
| 137 | target_os = "vexos" |
| 138 | )))] |
| 139 | pub fn sleep_until(deadline: crate::time::Instant) { |
| 140 | use crate::time::Instant; |
| 141 | |
| 142 | // The clock source used for `sleep` might not be the same used for `Instant`. |
| 143 | // Since this function *must not* return before the deadline, we recheck the |
| 144 | // time after every call to `sleep`. See #149935 for an example of this |
| 145 | // occurring on older Windows systems. |
| 146 | while let Some(delay) = deadline.checked_duration_since(Instant::now()) { |
| 147 | // Sleep for the estimated time remaining until the deadline. |
| 148 | // |
| 149 | // If your system has a better way of estimating the delay time or |
| 150 | // provides a way to sleep until an absolute time, specialize this |
| 151 | // function for your system. |
| 152 | sleep(delay); |
| 153 | } |
| 154 | } |
| 155 | |