Auto merge of #100201 - RalfJung:thread-local-key, r=thomcc
std: use realstd fast key when building tests
Under `cfg(test)`, the `std` crate is not the actual standard library, just any old crate we are testing. It imports the real standard library as `realstd`, and then does some careful `cfg` magic so that the crate built for testing uses the `realstd` global state rather than having its own copy of that.
However, this was not done for all global state hidden in std: the 'fast' version of thread-local keys, at least on some platforms, also involves some global state. Specifically its macOS version has this [`static REGISTERED`](bc63d5a26a/library/std/src/sys/unix/thread_local_dtor.rs (L62)
) that would get duplicated. So this PR imports the 'fast' key type from `realstd` rather than using the local copy, to ensure its internal state (and that of the functions it calls) does not get duplicated.
I also noticed that the `__OsLocalKeyInner` is unused under `cfg(target_thread_local)`, so I removed it for that configuration. There was a comment saying macOS picks between `__OsLocalKeyInner` and `__FastLocalKeyInner` at runtime, but I think that comment is outdated -- I found no trace of such a runtime switching mechanism, and the library still check-builds on apple targets with this PR. (I don't have a Mac so I cannot actually run it.)
This commit is contained in:
commit
223d16ebbd
3 changed files with 22 additions and 7 deletions
|
@ -69,8 +69,10 @@ use crate::sys_common::mutex::StaticMutex;
|
|||
/// ```ignore (cannot-doctest-private-modules)
|
||||
/// use tls::os::{StaticKey, INIT};
|
||||
///
|
||||
/// // Use a regular global static to store the key.
|
||||
/// static KEY: StaticKey = INIT;
|
||||
///
|
||||
/// // The state provided via `get` and `set` is thread-local.
|
||||
/// unsafe {
|
||||
/// assert!(KEY.get().is_null());
|
||||
/// KEY.set(1 as *mut u8);
|
||||
|
|
|
@ -1036,6 +1036,7 @@ pub mod fast {
|
|||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[cfg(not(target_thread_local))]
|
||||
pub mod os {
|
||||
use super::lazy::LazyKeyInner;
|
||||
use crate::cell::Cell;
|
||||
|
@ -1044,6 +1045,8 @@ pub mod os {
|
|||
use crate::ptr;
|
||||
use crate::sys_common::thread_local_key::StaticKey as OsStaticKey;
|
||||
|
||||
/// Use a regular global static to store this key; the state provided will then be
|
||||
/// thread-local.
|
||||
pub struct Key<T> {
|
||||
// OS-TLS key that we'll use to key off.
|
||||
os: OsStaticKey,
|
||||
|
|
|
@ -192,21 +192,31 @@ pub use scoped::{scope, Scope, ScopedJoinHandle};
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use self::local::{AccessError, LocalKey};
|
||||
|
||||
// The types used by the thread_local! macro to access TLS keys. Note that there
|
||||
// are two types, the "OS" type and the "fast" type. The OS thread local key
|
||||
// type is accessed via platform-specific API calls and is slow, while the fast
|
||||
// Select the type used by the thread_local! macro to access TLS keys. 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. Note that the OS TLS type is always available: on macOS
|
||||
// the standard library is compiled with support for older platform versions
|
||||
// where fast TLS was not available; end-user code is compiled with fast TLS
|
||||
// where available, but both are needed.
|
||||
// by the elf linker. "static" is for single-threaded platforms where a global
|
||||
// static is sufficient.
|
||||
|
||||
#[unstable(feature = "libstd_thread_internals", issue = "none")]
|
||||
#[cfg(target_thread_local)]
|
||||
#[cfg(not(test))]
|
||||
#[doc(hidden)]
|
||||
pub use self::local::fast::Key as __FastLocalKeyInner;
|
||||
#[unstable(feature = "libstd_thread_internals", issue = "none")]
|
||||
#[cfg(target_thread_local)]
|
||||
#[cfg(test)] // when building for tests, use real std's key
|
||||
pub use realstd::thread::__FastLocalKeyInner;
|
||||
|
||||
#[unstable(feature = "libstd_thread_internals", issue = "none")]
|
||||
#[cfg(target_thread_local)]
|
||||
#[cfg(test)]
|
||||
pub use self::local::fast::Key as __FastLocalKeyInnerUnused; // we import this anyway to silence 'unused' warnings
|
||||
|
||||
#[unstable(feature = "libstd_thread_internals", issue = "none")]
|
||||
#[doc(hidden)]
|
||||
#[cfg(not(target_thread_local))]
|
||||
pub use self::local::os::Key as __OsLocalKeyInner;
|
||||
#[unstable(feature = "libstd_thread_internals", issue = "none")]
|
||||
#[cfg(all(target_family = "wasm", not(target_feature = "atomics")))]
|
||||
|
|
Loading…
Add table
Reference in a new issue