Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

std: use realstd fast key when building tests #100201

Merged
merged 2 commits into from
Aug 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions library/std/src/sys_common/thread_local_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions library/std/src/thread/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
Expand Down
24 changes: 17 additions & 7 deletions library/std/src/thread/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It turns out that only one of these three key types is ever actually used now. So I considered refactoring this to avoid giving them different names, instead making __LocalKeyInner always be the key type for the current configuration. Do you think that would be a good idea?

The only issue I can see is that the types have to be used in slightly different ways: __FastLocalKeyInner wants a #[thread_local] static, the others a regular static. Using the same name for both usages slightly increases the risk that this would be mixed up.

Also I wasn't sure whether all(target_family = "wasm", not(target_feature = "atomics")) implied not(target_thread_local), if that is the case some of these cfg could be simplified and we could potentially at least merge __OsLocalKeyInner and __StaticLocalKeyInner into one type (i.e., move the logic for which implementation to use for that into the local module, rather than having it spread between that module and this file).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure whether all(target_family = "wasm", not(target_feature = "atomics")) implied not(target_thread_local)

Turns out the answer is no: #84224

Copy link
Member

@thomcc thomcc Aug 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I considered refactoring this to avoid giving them different names, instead making __LocalKeyInner always be the key type for the current configuration. Do you think that would be a good idea?

Hm, you mean just always using the same name? If you want to do this, please submit it as a different PR. I think it might be cleaner, but also might end up ending up making mistakes more likely (as you mention). Either way, it feels like an unrelated change to this. Feel free to r?me if you decide to do this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, basically have a single name for "the TLS key type we are using".

Not sure if it's worth it though.

#[unstable(feature = "libstd_thread_internals", issue = "none")]
#[cfg(all(target_family = "wasm", not(target_feature = "atomics")))]
Expand Down