diff options
Diffstat (limited to 'library/std')
59 files changed, 332 insertions, 334 deletions
diff --git a/library/std/src/env.rs b/library/std/src/env.rs index 1f2b8d3007d..6f8ac17f12c 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -469,7 +469,6 @@ pub struct SplitPaths<'a> { /// None => println!("{key} is not defined in the environment.") /// } /// ``` -#[doc(alias = "PATH")] #[stable(feature = "env", since = "1.0.0")] pub fn split_paths<T: AsRef<OsStr> + ?Sized>(unparsed: &T) -> SplitPaths<'_> { SplitPaths { inner: os_imp::split_paths(unparsed.as_ref()) } @@ -565,7 +564,6 @@ pub struct JoinPathsError { /// ``` /// /// [`env::split_paths()`]: split_paths -#[doc(alias = "PATH")] #[stable(feature = "env", since = "1.0.0")] pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError> where diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs index 6ec389400ae..de9bde51f2a 100644 --- a/library/std/src/f32.rs +++ b/library/std/src/f32.rs @@ -186,11 +186,8 @@ impl f32 { /// let x = 3.5_f32; /// let y = -3.5_f32; /// - /// let abs_difference_x = (x.abs() - x).abs(); - /// let abs_difference_y = (y.abs() - (-y)).abs(); - /// - /// assert!(abs_difference_x <= f32::EPSILON); - /// assert!(abs_difference_y <= f32::EPSILON); + /// assert_eq!(x.abs(), x); + /// assert_eq!(y.abs(), -y); /// /// assert!(f32::NAN.abs().is_nan()); /// ``` @@ -276,10 +273,17 @@ impl f32 { /// let x = 4.0_f32; /// let b = 60.0_f32; /// - /// // 100.0 - /// let abs_difference = (m.mul_add(x, b) - ((m * x) + b)).abs(); + /// assert_eq!(m.mul_add(x, b), 100.0); + /// assert_eq!(m * x + b, 100.0); /// - /// assert!(abs_difference <= f32::EPSILON); + /// let one_plus_eps = 1.0_f32 + f32::EPSILON; + /// let one_minus_eps = 1.0_f32 - f32::EPSILON; + /// let minus_one = -1.0_f32; + /// + /// // The exact result (1 + eps) * (1 - eps) = 1 - eps * eps. + /// assert_eq!(one_plus_eps.mul_add(one_minus_eps, minus_one), -f32::EPSILON * f32::EPSILON); + /// // Different rounding with the non-fused multiply and add. + /// assert_eq!(one_plus_eps * one_minus_eps + minus_one, 0.0); /// ``` #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] @@ -426,9 +430,7 @@ impl f32 { /// let negative = -4.0_f32; /// let negative_zero = -0.0_f32; /// - /// let abs_difference = (positive.sqrt() - 2.0).abs(); - /// - /// assert!(abs_difference <= f32::EPSILON); + /// assert_eq!(positive.sqrt(), 2.0); /// assert!(negative.sqrt().is_nan()); /// assert!(negative_zero.sqrt() == negative_zero); /// ``` diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs index 7385576c337..944186d602c 100644 --- a/library/std/src/f64.rs +++ b/library/std/src/f64.rs @@ -186,11 +186,8 @@ impl f64 { /// let x = 3.5_f64; /// let y = -3.5_f64; /// - /// let abs_difference_x = (x.abs() - x).abs(); - /// let abs_difference_y = (y.abs() - (-y)).abs(); - /// - /// assert!(abs_difference_x < 1e-10); - /// assert!(abs_difference_y < 1e-10); + /// assert_eq!(x.abs(), x); + /// assert_eq!(y.abs(), -y); /// /// assert!(f64::NAN.abs().is_nan()); /// ``` @@ -276,10 +273,17 @@ impl f64 { /// let x = 4.0_f64; /// let b = 60.0_f64; /// - /// // 100.0 - /// let abs_difference = (m.mul_add(x, b) - ((m * x) + b)).abs(); + /// assert_eq!(m.mul_add(x, b), 100.0); + /// assert_eq!(m * x + b, 100.0); /// - /// assert!(abs_difference < 1e-10); + /// let one_plus_eps = 1.0_f64 + f64::EPSILON; + /// let one_minus_eps = 1.0_f64 - f64::EPSILON; + /// let minus_one = -1.0_f64; + /// + /// // The exact result (1 + eps) * (1 - eps) = 1 - eps * eps. + /// assert_eq!(one_plus_eps.mul_add(one_minus_eps, minus_one), -f64::EPSILON * f64::EPSILON); + /// // Different rounding with the non-fused multiply and add. + /// assert_eq!(one_plus_eps * one_minus_eps + minus_one, 0.0); /// ``` #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] @@ -426,9 +430,7 @@ impl f64 { /// let negative = -4.0_f64; /// let negative_zero = -0.0_f64; /// - /// let abs_difference = (positive.sqrt() - 2.0).abs(); - /// - /// assert!(abs_difference < 1e-10); + /// assert_eq!(positive.sqrt(), 2.0); /// assert!(negative.sqrt().is_nan()); /// assert!(negative_zero.sqrt() == negative_zero); /// ``` diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 6b1dd1b5af4..694cc34cdc1 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -1476,11 +1476,10 @@ impl Permissions { /// On Unix-based platforms this checks if *any* of the owner, group or others /// write permission bits are set. It does not check if the current /// user is in the file's assigned group. It also does not check ACLs. - /// Therefore even if this returns true you may not be able to write to the - /// file, and vice versa. The [`PermissionsExt`] trait gives direct access - /// to the permission bits but also does not read ACLs. If you need to - /// accurately know whether or not a file is writable use the `access()` - /// function from libc. + /// Therefore the return value of this function cannot be relied upon + /// to predict whether attempts to read or write the file will actually succeed. + /// The [`PermissionsExt`] trait gives direct access to the permission bits but + /// also does not read ACLs. /// /// [`PermissionsExt`]: crate::os::unix::fs::PermissionsExt /// diff --git a/library/std/src/io/buffered/linewritershim.rs b/library/std/src/io/buffered/linewritershim.rs index f2a55da05b2..7eadfd41366 100644 --- a/library/std/src/io/buffered/linewritershim.rs +++ b/library/std/src/io/buffered/linewritershim.rs @@ -1,5 +1,5 @@ use crate::io::{self, BufWriter, IoSlice, Write}; -use crate::sys_common::memchr; +use core::slice::memchr; /// Private helper struct for implementing the line-buffered writing logic. /// This shim temporarily wraps a BufWriter, and uses its internals to diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 102db62fced..f35bffd6a3c 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -304,7 +304,7 @@ use crate::ops::{Deref, DerefMut}; use crate::slice; use crate::str; use crate::sys; -use crate::sys_common::memchr; +use core::slice::memchr; #[stable(feature = "bufwriter_into_parts", since = "1.56.0")] pub use self::buffered::WriterPanicked; diff --git a/library/std/src/sync/mutex.rs b/library/std/src/sync/mutex.rs index fa91f9d907a..65ff10e02d4 100644 --- a/library/std/src/sync/mutex.rs +++ b/library/std/src/sync/mutex.rs @@ -369,26 +369,6 @@ impl<T: ?Sized> Mutex<T> { } } - /// Immediately drops the guard, and consequently unlocks the mutex. - /// - /// This function is equivalent to calling [`drop`] on the guard but is more self-documenting. - /// Alternately, the guard will be automatically dropped when it goes out of scope. - /// - /// ``` - /// #![feature(mutex_unlock)] - /// - /// use std::sync::Mutex; - /// let mutex = Mutex::new(0); - /// - /// let mut guard = mutex.lock().unwrap(); - /// *guard += 20; - /// Mutex::unlock(guard); - /// ``` - #[unstable(feature = "mutex_unlock", issue = "81872")] - pub fn unlock(guard: MutexGuard<'_, T>) { - drop(guard); - } - /// Determines whether the mutex is poisoned. /// /// If another thread is active, the mutex can still become poisoned at any diff --git a/library/std/src/sys/locks/condvar/mod.rs b/library/std/src/sys/locks/condvar/mod.rs index 126a42a2a4c..6849cacf88e 100644 --- a/library/std/src/sys/locks/condvar/mod.rs +++ b/library/std/src/sys/locks/condvar/mod.rs @@ -1,5 +1,6 @@ cfg_if::cfg_if! { if #[cfg(any( + all(target_os = "windows", not(target_vendor="win7")), target_os = "linux", target_os = "android", target_os = "freebsd", @@ -14,9 +15,9 @@ cfg_if::cfg_if! { } else if #[cfg(target_family = "unix")] { mod pthread; pub use pthread::Condvar; - } else if #[cfg(target_os = "windows")] { - mod windows; - pub use windows::Condvar; + } else if #[cfg(all(target_os = "windows", target_vendor = "win7"))] { + mod windows7; + pub use windows7::Condvar; } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { mod sgx; pub use sgx::Condvar; diff --git a/library/std/src/sys/locks/condvar/windows.rs b/library/std/src/sys/locks/condvar/windows7.rs index 28a288335d2..28a288335d2 100644 --- a/library/std/src/sys/locks/condvar/windows.rs +++ b/library/std/src/sys/locks/condvar/windows7.rs diff --git a/library/std/src/sys/locks/mutex/futex.rs b/library/std/src/sys/locks/mutex/futex.rs index c01229586c3..7427cae94d6 100644 --- a/library/std/src/sys/locks/mutex/futex.rs +++ b/library/std/src/sys/locks/mutex/futex.rs @@ -1,30 +1,42 @@ use crate::sync::atomic::{ - AtomicU32, + self, Ordering::{Acquire, Relaxed, Release}, }; use crate::sys::futex::{futex_wait, futex_wake}; +cfg_if::cfg_if! { +if #[cfg(windows)] { + // On Windows we can have a smol futex + type Atomic = atomic::AtomicU8; + type State = u8; +} else { + type Atomic = atomic::AtomicU32; + type State = u32; +} +} + pub struct Mutex { - /// 0: unlocked - /// 1: locked, no other threads waiting - /// 2: locked, and other threads waiting (contended) - futex: AtomicU32, + futex: Atomic, } +const UNLOCKED: State = 0; +const LOCKED: State = 1; // locked, no other threads waiting +const CONTENDED: State = 2; // locked, and other threads waiting (contended) + impl Mutex { #[inline] pub const fn new() -> Self { - Self { futex: AtomicU32::new(0) } + Self { futex: Atomic::new(UNLOCKED) } } #[inline] pub fn try_lock(&self) -> bool { - self.futex.compare_exchange(0, 1, Acquire, Relaxed).is_ok() + self.futex.compare_exchange(UNLOCKED, LOCKED, Acquire, Relaxed).is_ok() } #[inline] pub fn lock(&self) { - if self.futex.compare_exchange(0, 1, Acquire, Relaxed).is_err() { + if self.futex.compare_exchange(UNLOCKED, LOCKED, Acquire, Relaxed).is_err() { self.lock_contended(); } } @@ -36,8 +48,8 @@ impl Mutex { // If it's unlocked now, attempt to take the lock // without marking it as contended. - if state == 0 { - match self.futex.compare_exchange(0, 1, Acquire, Relaxed) { + if state == UNLOCKED { + match self.futex.compare_exchange(UNLOCKED, LOCKED, Acquire, Relaxed) { Ok(_) => return, // Locked! Err(s) => state = s, } @@ -45,31 +57,31 @@ impl Mutex { loop { // Put the lock in contended state. - // We avoid an unnecessary write if it as already set to 2, + // We avoid an unnecessary write if it as already set to CONTENDED, // to be friendlier for the caches. - if state != 2 && self.futex.swap(2, Acquire) == 0 { - // We changed it from 0 to 2, so we just successfully locked it. + if state != CONTENDED && self.futex.swap(CONTENDED, Acquire) == UNLOCKED { + // We changed it from UNLOCKED to CONTENDED, so we just successfully locked it. return; } - // Wait for the futex to change state, assuming it is still 2. - futex_wait(&self.futex, 2, None); + // Wait for the futex to change state, assuming it is still CONTENDED. + futex_wait(&self.futex, CONTENDED, None); // Spin again after waking up. state = self.spin(); } } - fn spin(&self) -> u32 { + fn spin(&self) -> State { let mut spin = 100; loop { // We only use `load` (and not `swap` or `compare_exchange`) // while spinning, to be easier on the caches. let state = self.futex.load(Relaxed); - // We stop spinning when the mutex is unlocked (0), - // but also when it's contended (2). - if state != 1 || spin == 0 { + // We stop spinning when the mutex is UNLOCKED, + // but also when it's CONTENDED. + if state != LOCKED || spin == 0 { return state; } @@ -80,9 +92,9 @@ impl Mutex { #[inline] pub unsafe fn unlock(&self) { - if self.futex.swap(0, Release) == 2 { + if self.futex.swap(UNLOCKED, Release) == CONTENDED { // We only wake up one thread. When that thread locks the mutex, it - // will mark the mutex as contended (2) (see lock_contended above), + // will mark the mutex as CONTENDED (see lock_contended above), // which makes sure that any other waiting threads will also be // woken up eventually. self.wake(); diff --git a/library/std/src/sys/locks/mutex/mod.rs b/library/std/src/sys/locks/mutex/mod.rs index 710cb91fb14..73d9bd273de 100644 --- a/library/std/src/sys/locks/mutex/mod.rs +++ b/library/std/src/sys/locks/mutex/mod.rs @@ -1,5 +1,6 @@ cfg_if::cfg_if! { if #[cfg(any( + all(target_os = "windows", not(target_vendor = "win7")), target_os = "linux", target_os = "android", target_os = "freebsd", @@ -19,9 +20,9 @@ cfg_if::cfg_if! { ))] { mod pthread; pub use pthread::{Mutex, raw}; - } else if #[cfg(target_os = "windows")] { - mod windows; - pub use windows::{Mutex, raw}; + } else if #[cfg(all(target_os = "windows", target_vendor = "win7"))] { + mod windows7; + pub use windows7::{Mutex, raw}; } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { mod sgx; pub use sgx::Mutex; diff --git a/library/std/src/sys/locks/mutex/windows.rs b/library/std/src/sys/locks/mutex/windows7.rs index ef2f84082cd..ef2f84082cd 100644 --- a/library/std/src/sys/locks/mutex/windows.rs +++ b/library/std/src/sys/locks/mutex/windows7.rs diff --git a/library/std/src/sys/locks/rwlock/mod.rs b/library/std/src/sys/locks/rwlock/mod.rs index 0564f1fe6fa..675931c64bd 100644 --- a/library/std/src/sys/locks/rwlock/mod.rs +++ b/library/std/src/sys/locks/rwlock/mod.rs @@ -1,5 +1,6 @@ cfg_if::cfg_if! { if #[cfg(any( + all(target_os = "windows", not(target_vendor = "win7")), target_os = "linux", target_os = "android", target_os = "freebsd", @@ -14,9 +15,9 @@ cfg_if::cfg_if! { } else if #[cfg(target_family = "unix")] { mod queue; pub use queue::RwLock; - } else if #[cfg(target_os = "windows")] { - mod windows; - pub use windows::RwLock; + } else if #[cfg(all(target_os = "windows", target_vendor = "win7"))] { + mod windows7; + pub use windows7::RwLock; } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { mod sgx; pub use sgx::RwLock; diff --git a/library/std/src/sys/locks/rwlock/windows.rs b/library/std/src/sys/locks/rwlock/windows7.rs index e69415baac4..e69415baac4 100644 --- a/library/std/src/sys/locks/rwlock/windows.rs +++ b/library/std/src/sys/locks/rwlock/windows7.rs diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs index d77ac7eb027..81200e0061e 100644 --- a/library/std/src/sys/mod.rs +++ b/library/std/src/sys/mod.rs @@ -9,6 +9,9 @@ pub mod cmath; pub mod locks; pub mod os_str; pub mod path; +#[allow(dead_code)] +#[allow(unused_imports)] +pub mod thread_local; // FIXME(117276): remove this, move feature implementations into individual // submodules. diff --git a/library/std/src/sys/pal/common/mod.rs b/library/std/src/sys/pal/common/mod.rs index b35c5d30b41..29fc0835d76 100644 --- a/library/std/src/sys/pal/common/mod.rs +++ b/library/std/src/sys/pal/common/mod.rs @@ -12,8 +12,6 @@ pub mod alloc; pub mod small_c_string; -#[allow(unused_imports)] -pub mod thread_local; #[cfg(test)] mod tests; diff --git a/library/std/src/sys/pal/hermit/memchr.rs b/library/std/src/sys/pal/hermit/memchr.rs deleted file mode 100644 index 9967482197e..00000000000 --- a/library/std/src/sys/pal/hermit/memchr.rs +++ /dev/null @@ -1 +0,0 @@ -pub use core::slice::memchr::{memchr, memrchr}; diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs index ada408107dc..910935541bd 100644 --- a/library/std/src/sys/pal/hermit/mod.rs +++ b/library/std/src/sys/pal/hermit/mod.rs @@ -25,7 +25,6 @@ pub mod fs; pub mod futex; #[path = "../unsupported/io.rs"] pub mod io; -pub mod memchr; pub mod net; pub mod os; #[path = "../unsupported/pipe.rs"] diff --git a/library/std/src/sys/pal/hermit/os.rs b/library/std/src/sys/pal/hermit/os.rs index 645f0dc1e31..1f9affbf773 100644 --- a/library/std/src/sys/pal/hermit/os.rs +++ b/library/std/src/sys/pal/hermit/os.rs @@ -9,9 +9,9 @@ use crate::os::hermit::ffi::OsStringExt; use crate::path::{self, PathBuf}; use crate::str; use crate::sync::Mutex; -use crate::sys::memchr; use crate::sys::unsupported; use crate::vec; +use core::slice::memchr; pub fn errno() -> i32 { unsafe { abi::get_errno() } diff --git a/library/std/src/sys/pal/hermit/thread.rs b/library/std/src/sys/pal/hermit/thread.rs index fee80c02d4a..cf45b9c2396 100644 --- a/library/std/src/sys/pal/hermit/thread.rs +++ b/library/std/src/sys/pal/hermit/thread.rs @@ -2,7 +2,7 @@ use super::abi; use super::thread_local_dtor::run_dtors; -use crate::ffi::CStr; +use crate::ffi::{CStr, CString}; use crate::io; use crate::mem; use crate::num::NonZero; @@ -71,6 +71,10 @@ impl Thread { // nope } + pub fn get_name() -> Option<CString> { + None + } + #[inline] pub fn sleep(dur: Duration) { unsafe { diff --git a/library/std/src/sys/pal/itron/thread.rs b/library/std/src/sys/pal/itron/thread.rs index 9c1387bf408..814a102dd09 100644 --- a/library/std/src/sys/pal/itron/thread.rs +++ b/library/std/src/sys/pal/itron/thread.rs @@ -8,7 +8,7 @@ use super::{ }; use crate::{ cell::UnsafeCell, - ffi::CStr, + ffi::{CStr, CString}, hint, io, mem::ManuallyDrop, num::NonZero, @@ -204,6 +204,10 @@ impl Thread { // nope } + pub fn get_name() -> Option<CString> { + None + } + pub fn sleep(dur: Duration) { for timeout in dur2reltims(dur) { expect_success(unsafe { abi::dly_tsk(timeout) }, &"dly_tsk"); diff --git a/library/std/src/sys/pal/sgx/memchr.rs b/library/std/src/sys/pal/sgx/memchr.rs deleted file mode 100644 index 9967482197e..00000000000 --- a/library/std/src/sys/pal/sgx/memchr.rs +++ /dev/null @@ -1 +0,0 @@ -pub use core::slice::memchr::{memchr, memrchr}; diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs index 8ef3495884f..76f930b86f2 100644 --- a/library/std/src/sys/pal/sgx/mod.rs +++ b/library/std/src/sys/pal/sgx/mod.rs @@ -17,7 +17,6 @@ pub mod fd; pub mod fs; #[path = "../unsupported/io.rs"] pub mod io; -pub mod memchr; pub mod net; pub mod os; #[path = "../unsupported/pipe.rs"] diff --git a/library/std/src/sys/pal/sgx/thread.rs b/library/std/src/sys/pal/sgx/thread.rs index c797fde7fbd..77f68bf7334 100644 --- a/library/std/src/sys/pal/sgx/thread.rs +++ b/library/std/src/sys/pal/sgx/thread.rs @@ -1,6 +1,6 @@ #![cfg_attr(test, allow(dead_code))] // why is this necessary? use super::unsupported; -use crate::ffi::CStr; +use crate::ffi::{CStr, CString}; use crate::io; use crate::num::NonZero; use crate::time::Duration; @@ -133,6 +133,10 @@ impl Thread { // which succeeds as-is with the SGX target. } + pub fn get_name() -> Option<CString> { + None + } + pub fn sleep(dur: Duration) { usercalls::wait_timeout(0, dur, || true); } diff --git a/library/std/src/sys/pal/solid/memchr.rs b/library/std/src/sys/pal/solid/memchr.rs deleted file mode 100644 index 452b7a3de1b..00000000000 --- a/library/std/src/sys/pal/solid/memchr.rs +++ /dev/null @@ -1,21 +0,0 @@ -pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> { - let p = unsafe { - libc::memchr( - haystack.as_ptr() as *const libc::c_void, - needle as libc::c_int, - haystack.len(), - ) - }; - if p.is_null() { None } else { Some(p as usize - (haystack.as_ptr() as usize)) } -} - -pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> { - let p = unsafe { - libc::memrchr( - haystack.as_ptr() as *const libc::c_void, - needle as libc::c_int, - haystack.len(), - ) - }; - if p.is_null() { None } else { Some(p as usize - (haystack.as_ptr() as usize)) } -} diff --git a/library/std/src/sys/pal/solid/mod.rs b/library/std/src/sys/pal/solid/mod.rs index 9ada7d130f0..109ee1a0ab6 100644 --- a/library/std/src/sys/pal/solid/mod.rs +++ b/library/std/src/sys/pal/solid/mod.rs @@ -33,7 +33,6 @@ pub mod pipe; pub mod process; pub mod stdio; pub use self::itron::thread; -pub mod memchr; pub mod thread_local_dtor; pub mod thread_local_key; pub use self::itron::thread_parking; diff --git a/library/std/src/sys/pal/solid/os.rs b/library/std/src/sys/pal/solid/os.rs index 5ceab3b27e0..ef35d8788a2 100644 --- a/library/std/src/sys/pal/solid/os.rs +++ b/library/std/src/sys/pal/solid/os.rs @@ -12,7 +12,9 @@ use crate::sync::{PoisonError, RwLock}; use crate::sys::common::small_c_string::run_with_cstr; use crate::vec; -use super::{error, itron, memchr}; +use super::{error, itron}; + +use core::slice::memchr; // `solid` directly maps `errno`s to μITRON error codes. impl itron::error::ItronError { diff --git a/library/std/src/sys/pal/teeos/mod.rs b/library/std/src/sys/pal/teeos/mod.rs index 51ef96a69a0..1fb9d5438de 100644 --- a/library/std/src/sys/pal/teeos/mod.rs +++ b/library/std/src/sys/pal/teeos/mod.rs @@ -18,8 +18,6 @@ pub mod env; pub mod fs; #[path = "../unsupported/io.rs"] pub mod io; -#[path = "../unix/memchr.rs"] -pub mod memchr; pub mod net; #[path = "../unsupported/once.rs"] pub mod once; diff --git a/library/std/src/sys/pal/teeos/thread.rs b/library/std/src/sys/pal/teeos/thread.rs index 77f9040ead5..b76bcf9bbb0 100644 --- a/library/std/src/sys/pal/teeos/thread.rs +++ b/library/std/src/sys/pal/teeos/thread.rs @@ -1,7 +1,7 @@ use core::convert::TryInto; use crate::cmp; -use crate::ffi::CStr; +use crate::ffi::{CStr, CString}; use crate::io; use crate::mem; use crate::num::NonZero; @@ -101,6 +101,10 @@ impl Thread { // contact the teeos rustzone team. } + pub fn get_name() -> Option<CString> { + None + } + /// only main thread could wait for sometime in teeos pub fn sleep(dur: Duration) { let sleep_millis = dur.as_millis(); diff --git a/library/std/src/sys/pal/uefi/mod.rs b/library/std/src/sys/pal/uefi/mod.rs index ff8e3bd32ad..7c5b37fb490 100644 --- a/library/std/src/sys/pal/uefi/mod.rs +++ b/library/std/src/sys/pal/uefi/mod.rs @@ -48,10 +48,6 @@ use crate::os::uefi; use crate::ptr::NonNull; use crate::sync::atomic::{AtomicPtr, Ordering}; -pub mod memchr { - pub use core::slice::memchr::{memchr, memrchr}; -} - static EXIT_BOOT_SERVICE_EVENT: AtomicPtr<crate::ffi::c_void> = AtomicPtr::new(crate::ptr::null_mut()); diff --git a/library/std/src/sys/pal/uefi/thread.rs b/library/std/src/sys/pal/uefi/thread.rs index 3d8fa27251f..b3a4f9c53e3 100644 --- a/library/std/src/sys/pal/uefi/thread.rs +++ b/library/std/src/sys/pal/uefi/thread.rs @@ -1,5 +1,5 @@ use super::unsupported; -use crate::ffi::CStr; +use crate::ffi::{CStr, CString}; use crate::io; use crate::num::NonZero; use crate::ptr::NonNull; @@ -23,6 +23,10 @@ impl Thread { // nope } + pub fn get_name() -> Option<CString> { + None + } + pub fn sleep(dur: Duration) { let boot_services: NonNull<r_efi::efi::BootServices> = crate::os::uefi::env::boot_services().expect("can't sleep").cast(); diff --git a/library/std/src/sys/pal/unix/memchr.rs b/library/std/src/sys/pal/unix/memchr.rs deleted file mode 100644 index 73ba604eccb..00000000000 --- a/library/std/src/sys/pal/unix/memchr.rs +++ /dev/null @@ -1,40 +0,0 @@ -// Original implementation taken from rust-memchr. -// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch - -pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> { - let p = unsafe { - libc::memchr( - haystack.as_ptr() as *const libc::c_void, - needle as libc::c_int, - haystack.len(), - ) - }; - if p.is_null() { None } else { Some(p.addr() - haystack.as_ptr().addr()) } -} - -pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> { - #[cfg(target_os = "linux")] - fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> { - // GNU's memrchr() will - unlike memchr() - error if haystack is empty. - if haystack.is_empty() { - return None; - } - let p = unsafe { - libc::memrchr( - haystack.as_ptr() as *const libc::c_void, - needle as libc::c_int, - haystack.len(), - ) - }; - // FIXME: this should *likely* use `offset_from`, but more - // investigation is needed (including running tests in miri). - if p.is_null() { None } else { Some(p.addr() - haystack.as_ptr().addr()) } - } - - #[cfg(not(target_os = "linux"))] - fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> { - core::slice::memchr::memrchr(needle, haystack) - } - - memrchr_specific(needle, haystack) -} diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs index 23287258f2f..f608ae47a21 100644 --- a/library/std/src/sys/pal/unix/mod.rs +++ b/library/std/src/sys/pal/unix/mod.rs @@ -20,7 +20,6 @@ pub mod io; pub mod kernel_copy; #[cfg(target_os = "l4re")] mod l4re; -pub mod memchr; #[cfg(not(target_os = "l4re"))] pub mod net; #[cfg(target_os = "l4re")] diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs index af2b9db4685..0b9c8027e6f 100644 --- a/library/std/src/sys/pal/unix/os.rs +++ b/library/std/src/sys/pal/unix/os.rs @@ -21,8 +21,8 @@ use crate::sync::{PoisonError, RwLock}; use crate::sys::common::small_c_string::{run_path_with_cstr, run_with_cstr}; use crate::sys::cvt; use crate::sys::fd; -use crate::sys::memchr; use crate::vec; +use core::slice::memchr; #[cfg(all(target_env = "gnu", not(target_os = "vxworks")))] use crate::sys::weak::weak; diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 864de31c6eb..2af6382f3da 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -1,5 +1,5 @@ use crate::cmp; -use crate::ffi::CStr; +use crate::ffi::{CStr, CString}; use crate::io; use crate::mem; use crate::num::NonZero; @@ -225,6 +225,44 @@ impl Thread { // Newlib, Emscripten, and VxWorks have no way to set a thread name. } + #[cfg(target_os = "linux")] + pub fn get_name() -> Option<CString> { + const TASK_COMM_LEN: usize = 16; + let mut name = vec![0u8; TASK_COMM_LEN]; + let res = unsafe { + libc::pthread_getname_np(libc::pthread_self(), name.as_mut_ptr().cast(), name.len()) + }; + if res != 0 { + return None; + } + name.truncate(name.iter().position(|&c| c == 0)?); + CString::new(name).ok() + } + + #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))] + pub fn get_name() -> Option<CString> { + let mut name = vec![0u8; libc::MAXTHREADNAMESIZE]; + let res = unsafe { + libc::pthread_getname_np(libc::pthread_self(), name.as_mut_ptr().cast(), name.len()) + }; + if res != 0 { + return None; + } + name.truncate(name.iter().position(|&c| c == 0)?); + CString::new(name).ok() + } + + #[cfg(not(any( + target_os = "linux", + target_os = "macos", + target_os = "ios", + target_os = "tvos", + target_os = "watchos" + )))] + pub fn get_name() -> Option<CString> { + None + } + #[cfg(not(target_os = "espidf"))] pub fn sleep(dur: Duration) { let mut secs = dur.as_secs(); diff --git a/library/std/src/sys/pal/unsupported/common.rs b/library/std/src/sys/pal/unsupported/common.rs index 5c379992b20..4f44db610af 100644 --- a/library/std/src/sys/pal/unsupported/common.rs +++ b/library/std/src/sys/pal/unsupported/common.rs @@ -1,9 +1,5 @@ use crate::io as std_io; -pub mod memchr { - pub use core::slice::memchr::{memchr, memrchr}; -} - // SAFETY: must be called only once during runtime initialization. // NOTE: this is not guaranteed to run, for example when Rust code is called externally. pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: u8) {} diff --git a/library/std/src/sys/pal/unsupported/thread.rs b/library/std/src/sys/pal/unsupported/thread.rs index cd1ae7f7d11..b3a91ee1d4c 100644 --- a/library/std/src/sys/pal/unsupported/thread.rs +++ b/library/std/src/sys/pal/unsupported/thread.rs @@ -1,5 +1,5 @@ use super::unsupported; -use crate::ffi::CStr; +use crate::ffi::{CStr, CString}; use crate::io; use crate::num::NonZero; use crate::time::Duration; @@ -22,6 +22,10 @@ impl Thread { // nope } + pub fn get_name() -> Option<CString> { + None + } + pub fn sleep(_dur: Duration) { panic!("can't sleep"); } diff --git a/library/std/src/sys/pal/wasi/os.rs b/library/std/src/sys/pal/wasi/os.rs index d62ff8a2f18..ee377b6ef79 100644 --- a/library/std/src/sys/pal/wasi/os.rs +++ b/library/std/src/sys/pal/wasi/os.rs @@ -10,9 +10,9 @@ use crate::os::wasi::prelude::*; use crate::path::{self, PathBuf}; use crate::str; use crate::sys::common::small_c_string::{run_path_with_cstr, run_with_cstr}; -use crate::sys::memchr; use crate::sys::unsupported; use crate::vec; +use core::slice::memchr; // Add a few symbols not in upstream `libc` just yet. mod libc { diff --git a/library/std/src/sys/pal/wasi/thread.rs b/library/std/src/sys/pal/wasi/thread.rs index 77d8b4378e7..4b116052f8f 100644 --- a/library/std/src/sys/pal/wasi/thread.rs +++ b/library/std/src/sys/pal/wasi/thread.rs @@ -1,4 +1,4 @@ -use crate::ffi::CStr; +use crate::ffi::{CStr, CString}; use crate::io; use crate::mem; use crate::num::NonZero; @@ -134,6 +134,10 @@ impl Thread { // nope } + pub fn get_name() -> Option<CString> { + None + } + pub fn sleep(dur: Duration) { let nanos = dur.as_nanos(); assert!(nanos <= u64::MAX as u128); diff --git a/library/std/src/sys/pal/wasm/atomics/thread.rs b/library/std/src/sys/pal/wasm/atomics/thread.rs index 49f936f1449..3923ff821d9 100644 --- a/library/std/src/sys/pal/wasm/atomics/thread.rs +++ b/library/std/src/sys/pal/wasm/atomics/thread.rs @@ -1,4 +1,5 @@ use crate::ffi::CStr; +use crate::ffi::CString; use crate::io; use crate::num::NonZero; use crate::sys::unsupported; @@ -17,6 +18,9 @@ impl Thread { pub fn yield_now() {} pub fn set_name(_name: &CStr) {} + pub fn get_name() -> Option<CString> { + None + } pub fn sleep(dur: Duration) { use crate::arch::wasm32; diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs index b007796722b..584e17cd196 100644 --- a/library/std/src/sys/pal/windows/c.rs +++ b/library/std/src/sys/pal/windows/c.rs @@ -36,6 +36,7 @@ pub type LPVOID = *mut c_void; pub type LPWCH = *mut WCHAR; pub type LPWSTR = *mut WCHAR; +#[cfg(target_vendor = "win7")] pub type PSRWLOCK = *mut SRWLOCK; pub type socklen_t = c_int; @@ -50,7 +51,9 @@ pub const INVALID_HANDLE_VALUE: HANDLE = ::core::ptr::without_provenance_mut(-1i pub const EXIT_SUCCESS: u32 = 0; pub const EXIT_FAILURE: u32 = 1; +#[cfg(target_vendor = "win7")] pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = CONDITION_VARIABLE { Ptr: ptr::null_mut() }; +#[cfg(target_vendor = "win7")] pub const SRWLOCK_INIT: SRWLOCK = SRWLOCK { Ptr: ptr::null_mut() }; pub const INIT_ONCE_STATIC_INIT: INIT_ONCE = INIT_ONCE { Ptr: ptr::null_mut() }; @@ -344,6 +347,12 @@ compat_fn_with_fallback! { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); E_NOTIMPL } + // >= Win10 1607 + // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getthreaddescription + pub fn GetThreadDescription(hthread: HANDLE, lpthreaddescription: *mut PWSTR) -> HRESULT { + SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); E_NOTIMPL + } + // >= Win8 / Server 2012 // https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimepreciseasfiletime pub fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime: *mut FILETIME) -> () { @@ -367,6 +376,7 @@ extern "system" { dwmilliseconds: u32, ) -> BOOL; pub fn WakeByAddressSingle(address: *const c_void); + pub fn WakeByAddressAll(address: *const c_void); } #[cfg(target_vendor = "win7")] diff --git a/library/std/src/sys/pal/windows/c/bindings.txt b/library/std/src/sys/pal/windows/c/bindings.txt index ab2a8caf5df..7667f761106 100644 --- a/library/std/src/sys/pal/windows/c/bindings.txt +++ b/library/std/src/sys/pal/windows/c/bindings.txt @@ -1923,6 +1923,7 @@ Windows.Win32.Foundation.HANDLE_FLAG_INHERIT Windows.Win32.Foundation.HANDLE_FLAG_PROTECT_FROM_CLOSE Windows.Win32.Foundation.HANDLE_FLAGS Windows.Win32.Foundation.HMODULE +Windows.Win32.Foundation.LocalFree Windows.Win32.Foundation.MAX_PATH Windows.Win32.Foundation.NO_ERROR Windows.Win32.Foundation.NTSTATUS @@ -2481,6 +2482,7 @@ Windows.Win32.System.SystemInformation.SYSTEM_INFO Windows.Win32.System.SystemServices.DLL_PROCESS_DETACH Windows.Win32.System.SystemServices.DLL_THREAD_DETACH Windows.Win32.System.SystemServices.EXCEPTION_MAXIMUM_PARAMETERS +Windows.Win32.System.SystemServices.FAST_FAIL_FATAL_APP_EXIT Windows.Win32.System.SystemServices.IO_REPARSE_TAG_MOUNT_POINT Windows.Win32.System.SystemServices.IO_REPARSE_TAG_SYMLINK Windows.Win32.System.Threading.ABOVE_NORMAL_PRIORITY_CLASS diff --git a/library/std/src/sys/pal/windows/c/windows_sys.rs b/library/std/src/sys/pal/windows/c/windows_sys.rs index 8eb779373f7..7b751079afb 100644 --- a/library/std/src/sys/pal/windows/c/windows_sys.rs +++ b/library/std/src/sys/pal/windows/c/windows_sys.rs @@ -380,6 +380,10 @@ extern "system" { } #[link(name = "kernel32")] extern "system" { + pub fn LocalFree(hmem: HLOCAL) -> HLOCAL; +} +#[link(name = "kernel32")] +extern "system" { pub fn MoveFileExW( lpexistingfilename: PCWSTR, lpnewfilename: PCWSTR, @@ -3086,6 +3090,7 @@ pub type FACILITY_CODE = u32; pub const FACILITY_NT_BIT: FACILITY_CODE = 268435456u32; pub const FALSE: BOOL = 0i32; pub type FARPROC = ::core::option::Option<unsafe extern "system" fn() -> isize>; +pub const FAST_FAIL_FATAL_APP_EXIT: u32 = 7u32; #[repr(C)] pub struct FD_SET { pub fd_count: u32, @@ -3441,6 +3446,7 @@ pub type HANDLE_FLAGS = u32; pub const HANDLE_FLAG_INHERIT: HANDLE_FLAGS = 1u32; pub const HANDLE_FLAG_PROTECT_FROM_CLOSE: HANDLE_FLAGS = 2u32; pub const HIGH_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 128u32; +pub type HLOCAL = *mut ::core::ffi::c_void; pub type HMODULE = *mut ::core::ffi::c_void; pub type HRESULT = i32; pub const IDLE_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 64u32; diff --git a/library/std/src/sys/pal/windows/futex.rs b/library/std/src/sys/pal/windows/futex.rs new file mode 100644 index 00000000000..bc19c402d9c --- /dev/null +++ b/library/std/src/sys/pal/windows/futex.rs @@ -0,0 +1,85 @@ +use super::api; +use crate::sys::c; +use crate::sys::dur2timeout; +use core::ffi::c_void; +use core::mem; +use core::ptr; +use core::sync::atomic::{ + AtomicBool, AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicIsize, AtomicPtr, AtomicU16, + AtomicU32, AtomicU64, AtomicU8, AtomicUsize, +}; +use core::time::Duration; + +pub unsafe trait Waitable { + type Atomic; +} +macro_rules! unsafe_waitable_int { + ($(($int:ty, $atomic:ty)),*$(,)?) => { + $( + unsafe impl Waitable for $int { + type Atomic = $atomic; + } + )* + }; +} +unsafe_waitable_int! { + (bool, AtomicBool), + (i8, AtomicI8), + (i16, AtomicI16), + (i32, AtomicI32), + (i64, AtomicI64), + (isize, AtomicIsize), + (u8, AtomicU8), + (u16, AtomicU16), + (u32, AtomicU32), + (u64, AtomicU64), + (usize, AtomicUsize), +} +unsafe impl<T> Waitable for *const T { + type Atomic = AtomicPtr<T>; +} +unsafe impl<T> Waitable for *mut T { + type Atomic = AtomicPtr<T>; +} + +pub fn wait_on_address<W: Waitable>( + address: &W::Atomic, + compare: W, + timeout: Option<Duration>, +) -> bool { + unsafe { + let addr = ptr::from_ref(address).cast::<c_void>(); + let size = mem::size_of::<W>(); + let compare_addr = ptr::addr_of!(compare).cast::<c_void>(); + let timeout = timeout.map(dur2timeout).unwrap_or(c::INFINITE); + c::WaitOnAddress(addr, compare_addr, size, timeout) == c::TRUE + } +} + +pub fn wake_by_address_single<T>(address: &T) { + unsafe { + let addr = ptr::from_ref(address).cast::<c_void>(); + c::WakeByAddressSingle(addr); + } +} + +pub fn wake_by_address_all<T>(address: &T) { + unsafe { + let addr = ptr::from_ref(address).cast::<c_void>(); + c::WakeByAddressAll(addr); + } +} + +pub fn futex_wait<W: Waitable>(futex: &W::Atomic, expected: W, timeout: Option<Duration>) -> bool { + // return false only on timeout + wait_on_address(futex, expected, timeout) || api::get_last_error().code != c::ERROR_TIMEOUT +} + +pub fn futex_wake<T>(futex: &T) -> bool { + wake_by_address_single(futex); + false +} + +pub fn futex_wake_all<T>(futex: &T) { + wake_by_address_all(futex) +} diff --git a/library/std/src/sys/pal/windows/memchr.rs b/library/std/src/sys/pal/windows/memchr.rs deleted file mode 100644 index b9e5bcc1b4b..00000000000 --- a/library/std/src/sys/pal/windows/memchr.rs +++ /dev/null @@ -1,5 +0,0 @@ -// Original implementation taken from rust-memchr. -// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch - -// Fallback memchr is fastest on Windows. -pub use core::slice::memchr::{memchr, memrchr}; diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs index b47d213df34..6a561518fad 100644 --- a/library/std/src/sys/pal/windows/mod.rs +++ b/library/std/src/sys/pal/windows/mod.rs @@ -17,9 +17,10 @@ pub mod args; pub mod c; pub mod env; pub mod fs; +#[cfg(not(target_vendor = "win7"))] +pub mod futex; pub mod handle; pub mod io; -pub mod memchr; pub mod net; pub mod os; pub mod pipe; @@ -322,25 +323,26 @@ pub fn dur2timeout(dur: Duration) -> c::DWORD { /// /// This is the same implementation as in libpanic_abort's `__rust_start_panic`. See /// that function for more information on `__fastfail` -#[allow(unreachable_code)] +#[cfg(not(miri))] // inline assembly does not work in Miri pub fn abort_internal() -> ! { - #[allow(unused)] - const FAST_FAIL_FATAL_APP_EXIT: usize = 7; - #[cfg(not(miri))] // inline assembly does not work in Miri unsafe { cfg_if::cfg_if! { if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { - core::arch::asm!("int $$0x29", in("ecx") FAST_FAIL_FATAL_APP_EXIT); - crate::intrinsics::unreachable(); + core::arch::asm!("int $$0x29", in("ecx") c::FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack)); } else if #[cfg(all(target_arch = "arm", target_feature = "thumb-mode"))] { - core::arch::asm!(".inst 0xDEFB", in("r0") FAST_FAIL_FATAL_APP_EXIT); - crate::intrinsics::unreachable(); + core::arch::asm!(".inst 0xDEFB", in("r0") c::FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack)); } else if #[cfg(target_arch = "aarch64")] { - core::arch::asm!("brk 0xF003", in("x0") FAST_FAIL_FATAL_APP_EXIT); - crate::intrinsics::unreachable(); + core::arch::asm!("brk 0xF003", in("x0") c::FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack)); + } else { + core::intrinsics::abort(); } } } +} + +// miri is sensitive to changes here so check that miri is happy if touching this +#[cfg(miri)] +pub fn abort_internal() -> ! { crate::intrinsics::abort(); } diff --git a/library/std/src/sys/pal/windows/thread.rs b/library/std/src/sys/pal/windows/thread.rs index 0f709e2ec7b..a8f1e9b726b 100644 --- a/library/std/src/sys/pal/windows/thread.rs +++ b/library/std/src/sys/pal/windows/thread.rs @@ -9,7 +9,7 @@ use crate::sys::handle::Handle; use crate::sys::stack_overflow; use crate::sys_common::FromInner; use crate::time::Duration; - +use alloc::ffi::CString; use core::ffi::c_void; use super::time::WaitableTimer; @@ -71,6 +71,29 @@ impl Thread { }; } + pub fn get_name() -> Option<CString> { + unsafe { + let mut ptr = core::ptr::null_mut(); + let result = c::GetThreadDescription(c::GetCurrentThread(), &mut ptr); + if result < 0 { + return None; + } + let name = String::from_utf16_lossy({ + let mut len = 0; + while *ptr.add(len) != 0 { + len += 1; + } + core::slice::from_raw_parts(ptr, len) + }) + .into_bytes(); + // Attempt to free the memory. + // This should never fail but if it does then there's not much we can do about it. + let result = c::LocalFree(ptr.cast::<c_void>()); + debug_assert!(result.is_null()); + if name.is_empty() { None } else { Some(CString::from_vec_unchecked(name)) } + } + } + pub fn join(self) { let rc = unsafe { c::WaitForSingleObject(self.handle.as_raw_handle(), c::INFINITE) }; if rc == c::WAIT_FAILED { diff --git a/library/std/src/sys/pal/xous/thread.rs b/library/std/src/sys/pal/xous/thread.rs index 21f5954d6e2..f95ceb7343b 100644 --- a/library/std/src/sys/pal/xous/thread.rs +++ b/library/std/src/sys/pal/xous/thread.rs @@ -1,4 +1,4 @@ -use crate::ffi::CStr; +use crate::ffi::{CStr, CString}; use crate::io; use crate::num::NonZero; use crate::os::xous::ffi::{ @@ -113,6 +113,10 @@ impl Thread { // nope } + pub fn get_name() -> Option<CString> { + None + } + pub fn sleep(dur: Duration) { // Because the sleep server works on units of `usized milliseconds`, split // the messages up into these chunks. This means we may run into issues diff --git a/library/std/src/sys/pal/zkvm/mod.rs b/library/std/src/sys/pal/zkvm/mod.rs index 016c977dc33..6c714f76309 100644 --- a/library/std/src/sys/pal/zkvm/mod.rs +++ b/library/std/src/sys/pal/zkvm/mod.rs @@ -43,10 +43,6 @@ mod abi; use crate::io as std_io; -pub mod memchr { - pub use core::slice::memchr::{memchr, memrchr}; -} - // SAFETY: must be called only once during runtime initialization. // NOTE: this is not guaranteed to run, for example when Rust code is called externally. pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: u8) {} diff --git a/library/std/src/sys/pal/common/thread_local/fast_local.rs b/library/std/src/sys/thread_local/fast_local.rs index 646dcd7f3a3..646dcd7f3a3 100644 --- a/library/std/src/sys/pal/common/thread_local/fast_local.rs +++ b/library/std/src/sys/thread_local/fast_local.rs diff --git a/library/std/src/sys/pal/common/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs index 8b2c839f837..8b2c839f837 100644 --- a/library/std/src/sys/pal/common/thread_local/mod.rs +++ b/library/std/src/sys/thread_local/mod.rs diff --git a/library/std/src/sys/pal/common/thread_local/os_local.rs b/library/std/src/sys/thread_local/os_local.rs index 3edffd7e443..3edffd7e443 100644 --- a/library/std/src/sys/pal/common/thread_local/os_local.rs +++ b/library/std/src/sys/thread_local/os_local.rs diff --git a/library/std/src/sys/pal/common/thread_local/static_local.rs b/library/std/src/sys/thread_local/static_local.rs index 4f2b6868962..4f2b6868962 100644 --- a/library/std/src/sys/pal/common/thread_local/static_local.rs +++ b/library/std/src/sys/thread_local/static_local.rs diff --git a/library/std/src/sys_common/memchr.rs b/library/std/src/sys_common/memchr.rs deleted file mode 100644 index b219e878912..00000000000 --- a/library/std/src/sys_common/memchr.rs +++ /dev/null @@ -1,51 +0,0 @@ -// Original implementation taken from rust-memchr. -// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch - -use crate::sys::memchr as sys; - -#[cfg(test)] -mod tests; - -/// A safe interface to `memchr`. -/// -/// Returns the index corresponding to the first occurrence of `needle` in -/// `haystack`, or `None` if one is not found. -/// -/// memchr reduces to super-optimized machine code at around an order of -/// magnitude faster than `haystack.iter().position(|&b| b == needle)`. -/// (See benchmarks.) -/// -/// # Examples -/// -/// This shows how to find the first position of a byte in a byte string. -/// -/// ```ignore (cannot-doctest-private-modules) -/// use memchr::memchr; -/// -/// let haystack = b"the quick brown fox"; -/// assert_eq!(memchr(b'k', haystack), Some(8)); -/// ``` -#[inline] -pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> { - sys::memchr(needle, haystack) -} - -/// A safe interface to `memrchr`. -/// -/// Returns the index corresponding to the last occurrence of `needle` in -/// `haystack`, or `None` if one is not found. -/// -/// # Examples -/// -/// This shows how to find the last position of a byte in a byte string. -/// -/// ```ignore (cannot-doctest-private-modules) -/// use memchr::memrchr; -/// -/// let haystack = b"the quick brown fox"; -/// assert_eq!(memrchr(b'o', haystack), Some(17)); -/// ``` -#[inline] -pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> { - sys::memrchr(needle, haystack) -} diff --git a/library/std/src/sys_common/memchr/tests.rs b/library/std/src/sys_common/memchr/tests.rs deleted file mode 100644 index 557d749c7f6..00000000000 --- a/library/std/src/sys_common/memchr/tests.rs +++ /dev/null @@ -1,86 +0,0 @@ -// Original implementation taken from rust-memchr. -// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch - -// test the implementations for the current platform -use super::{memchr, memrchr}; - -#[test] -fn matches_one() { - assert_eq!(Some(0), memchr(b'a', b"a")); -} - -#[test] -fn matches_begin() { - assert_eq!(Some(0), memchr(b'a', b"aaaa")); -} - -#[test] -fn matches_end() { - assert_eq!(Some(4), memchr(b'z', b"aaaaz")); -} - -#[test] -fn matches_nul() { - assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00")); -} - -#[test] -fn matches_past_nul() { - assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z")); -} - -#[test] -fn no_match_empty() { - assert_eq!(None, memchr(b'a', b"")); -} - -#[test] -fn no_match() { - assert_eq!(None, memchr(b'a', b"xyz")); -} - -#[test] -fn matches_one_reversed() { - assert_eq!(Some(0), memrchr(b'a', b"a")); -} - -#[test] -fn matches_begin_reversed() { - assert_eq!(Some(3), memrchr(b'a', b"aaaa")); -} - -#[test] -fn matches_end_reversed() { - assert_eq!(Some(0), memrchr(b'z', b"zaaaa")); -} - -#[test] -fn matches_nul_reversed() { - assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00")); -} - -#[test] -fn matches_past_nul_reversed() { - assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa")); -} - -#[test] -fn no_match_empty_reversed() { - assert_eq!(None, memrchr(b'a', b"")); -} - -#[test] -fn no_match_reversed() { - assert_eq!(None, memrchr(b'a', b"xyz")); -} - -#[test] -fn each_alignment() { - let mut data = [1u8; 64]; - let needle = 2; - let pos = 40; - data[pos] = needle; - for start in 0..16 { - assert_eq!(Some(pos - start), memchr(needle, &data[start..])); - } -} diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs index 01f83ecb414..c9025a81bf3 100644 --- a/library/std/src/sys_common/mod.rs +++ b/library/std/src/sys_common/mod.rs @@ -24,7 +24,6 @@ pub mod backtrace; pub mod fs; pub mod io; pub mod lazy_box; -pub mod memchr; pub mod once; pub mod process; pub mod thread; diff --git a/library/std/src/sys_common/thread_info.rs b/library/std/src/sys_common/thread_info.rs index 8d51732e035..ec1428ea40e 100644 --- a/library/std/src/sys_common/thread_info.rs +++ b/library/std/src/sys_common/thread_info.rs @@ -1,6 +1,7 @@ #![allow(dead_code)] // stack_guard isn't used right now on all platforms use crate::cell::OnceCell; +use crate::sys; use crate::sys::thread::guard::Guard; use crate::thread::Thread; @@ -23,7 +24,8 @@ impl ThreadInfo { { THREAD_INFO .try_with(move |thread_info| { - let thread = thread_info.thread.get_or_init(|| Thread::new(None)); + let thread = + thread_info.thread.get_or_init(|| Thread::new(sys::thread::Thread::get_name())); f(thread, &thread_info.stack_guard) }) .ok() diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 76af7fec926..85de2980133 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -205,7 +205,7 @@ cfg_if::cfg_if! { #[doc(hidden)] #[unstable(feature = "thread_local_internals", issue = "none")] pub mod local_impl { - pub use crate::sys::common::thread_local::{thread_local_inner, Key, abort_on_dtor_unwind}; + pub use crate::sys::thread_local::{thread_local_inner, Key, abort_on_dtor_unwind}; } } } diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs index 5d6b9e94ee9..813ede06415 100644 --- a/library/std/src/thread/tests.rs +++ b/library/std/src/thread/tests.rs @@ -69,6 +69,25 @@ fn test_named_thread_truncation() { result.unwrap().join().unwrap(); } +#[cfg(any( + all(target_os = "windows", not(target_vendor = "win7")), + target_os = "linux", + target_os = "macos", + target_os = "ios", + target_os = "tvos", + target_os = "watchos" +))] +#[test] +fn test_get_os_named_thread() { + use crate::sys::thread::Thread; + let handler = thread::spawn(|| { + let name = c"test me please"; + Thread::set_name(name); + assert_eq!(name, Thread::get_name().unwrap().as_c_str()); + }); + handler.join().unwrap(); +} + #[test] #[should_panic] fn test_invalid_named_thread() { |
