| 1 | #![cfg_attr (any(not(feature = "full" ), loom), allow(unused_imports, dead_code))] |
| 2 | |
| 3 | mod atomic_u16; |
| 4 | mod atomic_u32; |
| 5 | mod atomic_u64; |
| 6 | mod atomic_usize; |
| 7 | mod barrier; |
| 8 | mod mutex; |
| 9 | #[cfg (all(feature = "parking_lot" , not(miri)))] |
| 10 | mod parking_lot; |
| 11 | mod rwlock; |
| 12 | mod unsafe_cell; |
| 13 | |
| 14 | pub(crate) mod cell { |
| 15 | pub(crate) use super::unsafe_cell::UnsafeCell; |
| 16 | } |
| 17 | |
| 18 | #[cfg (any( |
| 19 | feature = "net" , |
| 20 | feature = "process" , |
| 21 | feature = "signal" , |
| 22 | feature = "sync" , |
| 23 | ))] |
| 24 | pub(crate) mod future { |
| 25 | pub(crate) use crate::sync::AtomicWaker; |
| 26 | } |
| 27 | |
| 28 | pub(crate) mod hint { |
| 29 | pub(crate) use std::hint::spin_loop; |
| 30 | } |
| 31 | |
| 32 | pub(crate) mod rand { |
| 33 | use std::collections::hash_map::RandomState; |
| 34 | use std::hash::{BuildHasher, Hash, Hasher}; |
| 35 | use std::sync::atomic::AtomicU32; |
| 36 | use std::sync::atomic::Ordering::Relaxed; |
| 37 | |
| 38 | static COUNTER: AtomicU32 = AtomicU32::new(1); |
| 39 | |
| 40 | pub(crate) fn seed() -> u64 { |
| 41 | let rand_state: RandomState = RandomState::new(); |
| 42 | |
| 43 | let mut hasher: DefaultHasher = rand_state.build_hasher(); |
| 44 | |
| 45 | // Hash some unique-ish data to generate some new state |
| 46 | COUNTER.fetch_add(1, Relaxed).hash(&mut hasher); |
| 47 | |
| 48 | // Get the seed |
| 49 | hasher.finish() |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | pub(crate) mod sync { |
| 54 | pub(crate) use std::sync::{Arc, Weak}; |
| 55 | |
| 56 | // Below, make sure all the feature-influenced types are exported for |
| 57 | // internal use. Note however that some are not _currently_ named by |
| 58 | // consuming code. |
| 59 | |
| 60 | #[cfg (all(feature = "parking_lot" , not(miri)))] |
| 61 | #[allow (unused_imports)] |
| 62 | pub(crate) use crate::loom::std::parking_lot::{ |
| 63 | Condvar, Mutex, MutexGuard, RwLock, RwLockReadGuard, WaitTimeoutResult, |
| 64 | }; |
| 65 | |
| 66 | #[cfg (not(all(feature = "parking_lot" , not(miri))))] |
| 67 | #[allow (unused_imports)] |
| 68 | pub(crate) use std::sync::{Condvar, MutexGuard, RwLockReadGuard, WaitTimeoutResult}; |
| 69 | |
| 70 | #[cfg (not(all(feature = "parking_lot" , not(miri))))] |
| 71 | pub(crate) use crate::loom::std::mutex::Mutex; |
| 72 | |
| 73 | #[cfg (not(all(feature = "parking_lot" , not(miri))))] |
| 74 | pub(crate) use crate::loom::std::rwlock::RwLock; |
| 75 | |
| 76 | pub(crate) mod atomic { |
| 77 | pub(crate) use crate::loom::std::atomic_u16::AtomicU16; |
| 78 | pub(crate) use crate::loom::std::atomic_u32::AtomicU32; |
| 79 | pub(crate) use crate::loom::std::atomic_u64::{AtomicU64, StaticAtomicU64}; |
| 80 | pub(crate) use crate::loom::std::atomic_usize::AtomicUsize; |
| 81 | |
| 82 | pub(crate) use std::sync::atomic::{fence, AtomicBool, AtomicPtr, AtomicU8, Ordering}; |
| 83 | } |
| 84 | |
| 85 | pub(crate) use super::barrier::Barrier; |
| 86 | } |
| 87 | |
| 88 | pub(crate) mod sys { |
| 89 | #[cfg (feature = "rt-multi-thread" )] |
| 90 | pub(crate) fn num_cpus() -> usize { |
| 91 | use std::num::NonZeroUsize; |
| 92 | |
| 93 | const ENV_WORKER_THREADS: &str = "TOKIO_WORKER_THREADS" ; |
| 94 | |
| 95 | match std::env::var(ENV_WORKER_THREADS) { |
| 96 | Ok(s) => { |
| 97 | let n = s.parse().unwrap_or_else(|e| { |
| 98 | panic!(" \"{ENV_WORKER_THREADS} \" must be usize, error: {e}, value: {s}" ) |
| 99 | }); |
| 100 | assert!(n > 0, " \"{ENV_WORKER_THREADS} \" cannot be set to 0" ); |
| 101 | n |
| 102 | } |
| 103 | Err(std::env::VarError::NotPresent) => { |
| 104 | std::thread::available_parallelism().map_or(1, NonZeroUsize::get) |
| 105 | } |
| 106 | Err(std::env::VarError::NotUnicode(e)) => { |
| 107 | panic!(" \"{ENV_WORKER_THREADS} \" must be valid unicode, error: {e:?}" ) |
| 108 | } |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | #[cfg (not(feature = "rt-multi-thread" ))] |
| 113 | pub(crate) fn num_cpus() -> usize { |
| 114 | 1 |
| 115 | } |
| 116 | } |
| 117 | |
| 118 | pub(crate) mod thread { |
| 119 | #[inline ] |
| 120 | pub(crate) fn yield_now() { |
| 121 | std::hint::spin_loop(); |
| 122 | } |
| 123 | |
| 124 | #[allow (unused_imports)] |
| 125 | pub(crate) use std::thread::{ |
| 126 | current, panicking, park, park_timeout, sleep, spawn, AccessError, Builder, JoinHandle, |
| 127 | LocalKey, Result, Thread, ThreadId, |
| 128 | }; |
| 129 | } |
| 130 | |