diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:42 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:42 +0000 |
commit | 837b550238aa671a591ccf282dddeab29cadb206 (patch) | |
tree | 914b6b8862bace72bd3245ca184d374b08d8a672 /library/std/src/thread | |
parent | Adding debian version 1.70.0+dfsg2-1. (diff) | |
download | rustc-837b550238aa671a591ccf282dddeab29cadb206.tar.xz rustc-837b550238aa671a591ccf282dddeab29cadb206.zip |
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'library/std/src/thread')
-rw-r--r-- | library/std/src/thread/local.rs | 34 | ||||
-rw-r--r-- | library/std/src/thread/mod.rs | 35 | ||||
-rw-r--r-- | library/std/src/thread/tests.rs | 4 |
3 files changed, 48 insertions, 25 deletions
diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs index 7fdf03acc..1b86d898c 100644 --- a/library/std/src/thread/local.rs +++ b/library/std/src/thread/local.rs @@ -18,8 +18,8 @@ use crate::fmt; /// target platform. It is instantiated with the [`thread_local!`] macro and the /// primary method is the [`with`] method. /// -/// The [`with`] method yields a reference to the contained value which cannot be -/// sent across threads or escape the given closure. +/// The [`with`] method yields a reference to the contained value which cannot +/// outlive the current thread or escape the given closure. /// /// [`thread_local!`]: crate::thread_local /// @@ -134,10 +134,28 @@ impl<T: 'static> fmt::Debug for LocalKey<T> { /// thread_local! { /// pub static FOO: RefCell<u32> = RefCell::new(1); /// -/// #[allow(unused)] /// static BAR: RefCell<f32> = RefCell::new(1.0); /// } -/// # fn main() {} +/// +/// FOO.with(|foo| assert_eq!(*foo.borrow(), 1)); +/// BAR.with(|bar| assert_eq!(*bar.borrow(), 1.0)); +/// ``` +/// +/// This macro supports a special `const {}` syntax that can be used +/// when the initialization expression can be evaluated as a constant. +/// This can enable a more efficient thread local implementation that +/// can avoid lazy initialization. For types that do not +/// [need to be dropped][crate::mem::needs_drop], this can enable an +/// even more efficient implementation that does not need to +/// track any additional state. +/// +/// ``` +/// use std::cell::Cell; +/// thread_local! { +/// pub static FOO: Cell<u32> = const { Cell::new(1) }; +/// } +/// +/// FOO.with(|foo| assert_eq!(foo.get(), 1)); /// ``` /// /// See [`LocalKey` documentation][`std::thread::LocalKey`] for more @@ -153,23 +171,23 @@ macro_rules! thread_local { () => {}; ($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty = const { $init:expr }; $($rest:tt)*) => ( - $crate::__thread_local_inner!($(#[$attr])* $vis $name, $t, const $init); + $crate::thread::local_impl::thread_local_inner!($(#[$attr])* $vis $name, $t, const $init); $crate::thread_local!($($rest)*); ); ($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty = const { $init:expr }) => ( - $crate::__thread_local_inner!($(#[$attr])* $vis $name, $t, const $init); + $crate::thread::local_impl::thread_local_inner!($(#[$attr])* $vis $name, $t, const $init); ); // process multiple declarations ($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty = $init:expr; $($rest:tt)*) => ( - $crate::__thread_local_inner!($(#[$attr])* $vis $name, $t, $init); + $crate::thread::local_impl::thread_local_inner!($(#[$attr])* $vis $name, $t, $init); $crate::thread_local!($($rest)*); ); // handle a single declaration ($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty = $init:expr) => ( - $crate::__thread_local_inner!($(#[$attr])* $vis $name, $t, $init); + $crate::thread::local_impl::thread_local_inner!($(#[$attr])* $vis $name, $t, $init); ); } diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 13b845b25..f712c8727 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -193,20 +193,23 @@ pub use scoped::{scope, Scope, ScopedJoinHandle}; #[macro_use] mod local; -#[stable(feature = "rust1", since = "1.0.0")] -pub use self::local::{AccessError, LocalKey}; - -// Provide the type used by the thread_local! macro to access TLS keys. This -// needs to be kept in sync with the macro itself (in `local.rs`). -// There are three types: "static", "fast", "OS". The "OS" thread local key -// type is accessed via platform-specific API calls and is slow, while the "fast" -// key type is accessed via code generated via LLVM, where TLS keys are set up -// by the elf linker. "static" is for single-threaded platforms where a global -// static is sufficient. - -#[doc(hidden)] -#[unstable(feature = "libstd_thread_internals", issue = "none")] -pub use crate::sys::common::thread_local::Key as __LocalKeyInner; +cfg_if::cfg_if! { + if #[cfg(test)] { + // Avoid duplicating the global state assoicated with thread-locals between this crate and + // realstd. Miri relies on this. + pub use realstd::thread::{local_impl, AccessError, LocalKey}; + } else { + #[stable(feature = "rust1", since = "1.0.0")] + pub use self::local::{AccessError, LocalKey}; + + // Implementation details used by the thread_local!{} macro. + #[doc(hidden)] + #[unstable(feature = "thread_local_internals", issue = "none")] + pub mod local_impl { + pub use crate::sys::common::thread_local::{thread_local_inner, Key}; + } + } +} //////////////////////////////////////////////////////////////////////////////// // Builder @@ -494,7 +497,7 @@ impl Builder { MaybeDangling(mem::MaybeUninit::new(x)) } fn into_inner(self) -> T { - // SAFETY: we are always initiailized. + // SAFETY: we are always initialized. let ret = unsafe { self.0.assume_init_read() }; // Make sure we don't drop. mem::forget(self); @@ -503,7 +506,7 @@ impl Builder { } impl<T> Drop for MaybeDangling<T> { fn drop(&mut self) { - // SAFETY: we are always initiailized. + // SAFETY: we are always initialized. unsafe { self.0.assume_init_drop() }; } } diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs index 6c9ce6fa0..b65e2572c 100644 --- a/library/std/src/thread/tests.rs +++ b/library/std/src/thread/tests.rs @@ -375,7 +375,9 @@ fn test_scoped_threads_nll() { // this is mostly a *compilation test* for this exact function: fn foo(x: &u8) { thread::scope(|s| { - s.spawn(|| drop(x)); + s.spawn(|| match x { + _ => (), + }); }); } // let's also run it for good measure |