diff --git a/src/libstd/sys/cloudabi/mod.rs b/src/libstd/sys/cloudabi/mod.rs index 8dbc31472d637..f7dd2c8d00fd2 100644 --- a/src/libstd/sys/cloudabi/mod.rs +++ b/src/libstd/sys/cloudabi/mod.rs @@ -16,8 +16,8 @@ pub mod rwlock; pub mod stack_overflow; pub mod stdio; pub mod thread; -#[path = "../unix/thread_local.rs"] -pub mod thread_local; +#[path = "../unix/thread_local_key.rs"] +pub mod thread_local_key; pub mod time; pub use crate::sys_common::os_str_bytes as os_str; diff --git a/src/libstd/sys/hermit/mod.rs b/src/libstd/sys/hermit/mod.rs index 7bdc1be3b1702..675b82ceb775f 100644 --- a/src/libstd/sys/hermit/mod.rs +++ b/src/libstd/sys/hermit/mod.rs @@ -22,7 +22,6 @@ pub mod cmath; pub mod condvar; pub mod env; pub mod ext; -pub mod fast_thread_local; pub mod fd; pub mod fs; pub mod io; @@ -37,7 +36,8 @@ pub mod rwlock; pub mod stack_overflow; pub mod stdio; pub mod thread; -pub mod thread_local; +pub mod thread_local_dtor; +pub mod thread_local_key; pub mod time; use crate::io::ErrorKind; diff --git a/src/libstd/sys/hermit/fast_thread_local.rs b/src/libstd/sys/hermit/thread_local_dtor.rs similarity index 100% rename from src/libstd/sys/hermit/fast_thread_local.rs rename to src/libstd/sys/hermit/thread_local_dtor.rs diff --git a/src/libstd/sys/wasm/thread_local.rs b/src/libstd/sys/hermit/thread_local_key.rs similarity index 54% rename from src/libstd/sys/wasm/thread_local.rs rename to src/libstd/sys/hermit/thread_local_key.rs index f8be9863ed56f..bf1b49eb83b7e 100644 --- a/src/libstd/sys/wasm/thread_local.rs +++ b/src/libstd/sys/hermit/thread_local_key.rs @@ -2,25 +2,25 @@ pub type Key = usize; #[inline] pub unsafe fn create(_dtor: Option) -> Key { - panic!("should not be used on the wasm target"); + panic!("should not be used on the hermit target"); } #[inline] pub unsafe fn set(_key: Key, _value: *mut u8) { - panic!("should not be used on the wasm target"); + panic!("should not be used on the hermit target"); } #[inline] pub unsafe fn get(_key: Key) -> *mut u8 { - panic!("should not be used on the wasm target"); + panic!("should not be used on the hermit target"); } #[inline] pub unsafe fn destroy(_key: Key) { - panic!("should not be used on the wasm target"); + panic!("should not be used on the hermit target"); } #[inline] pub fn requires_synchronized_create() -> bool { - panic!("should not be used on the wasm target"); + panic!("should not be used on the hermit target"); } diff --git a/src/libstd/sys/sgx/mod.rs b/src/libstd/sys/sgx/mod.rs index 397dd496ae8af..a4968ff7d4f54 100644 --- a/src/libstd/sys/sgx/mod.rs +++ b/src/libstd/sys/sgx/mod.rs @@ -30,7 +30,7 @@ pub mod rwlock; pub mod stack_overflow; pub mod stdio; pub mod thread; -pub mod thread_local; +pub mod thread_local_key; pub mod time; pub use crate::sys_common::os_str_bytes as os_str; diff --git a/src/libstd/sys/sgx/thread_local.rs b/src/libstd/sys/sgx/thread_local_key.rs similarity index 100% rename from src/libstd/sys/sgx/thread_local.rs rename to src/libstd/sys/sgx/thread_local_key.rs diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index b1688e74173d7..eddf00d3979f5 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -47,7 +47,6 @@ pub mod cmath; pub mod condvar; pub mod env; pub mod ext; -pub mod fast_thread_local; pub mod fd; pub mod fs; pub mod io; @@ -68,7 +67,8 @@ pub mod rwlock; pub mod stack_overflow; pub mod stdio; pub mod thread; -pub mod thread_local; +pub mod thread_local_dtor; +pub mod thread_local_key; pub mod time; pub use crate::sys_common::os_str_bytes as os_str; diff --git a/src/libstd/sys/unix/fast_thread_local.rs b/src/libstd/sys/unix/thread_local_dtor.rs similarity index 94% rename from src/libstd/sys/unix/fast_thread_local.rs rename to src/libstd/sys/unix/thread_local_dtor.rs index 8730b4de8bed2..c3275eb6f0e50 100644 --- a/src/libstd/sys/unix/fast_thread_local.rs +++ b/src/libstd/sys/unix/thread_local_dtor.rs @@ -1,6 +1,9 @@ #![cfg(target_thread_local)] #![unstable(feature = "thread_local_internals", issue = "none")] +//! Provides thread-local destructors without an associated "key", which +//! can be more efficient. + // Since what appears to be glibc 2.18 this symbol has been shipped which // GCC and clang both use to invoke destructors in thread_local globals, so // let's do the same! @@ -16,7 +19,7 @@ ))] pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { use crate::mem; - use crate::sys_common::thread_local::register_dtor_fallback; + use crate::sys_common::thread_local_dtor::register_dtor_fallback; extern "C" { #[linkage = "extern_weak"] diff --git a/src/libstd/sys/unix/thread_local.rs b/src/libstd/sys/unix/thread_local_key.rs similarity index 100% rename from src/libstd/sys/unix/thread_local.rs rename to src/libstd/sys/unix/thread_local_key.rs diff --git a/src/libstd/sys/vxworks/mod.rs b/src/libstd/sys/vxworks/mod.rs index 0787e7098988c..1132a849e2f18 100644 --- a/src/libstd/sys/vxworks/mod.rs +++ b/src/libstd/sys/vxworks/mod.rs @@ -13,7 +13,6 @@ pub mod cmath; pub mod condvar; pub mod env; pub mod ext; -pub mod fast_thread_local; pub mod fd; pub mod fs; pub mod io; @@ -29,7 +28,8 @@ pub mod rwlock; pub mod stack_overflow; pub mod stdio; pub mod thread; -pub mod thread_local; +pub mod thread_local_dtor; +pub mod thread_local_key; pub mod time; pub use crate::sys_common::os_str_bytes as os_str; diff --git a/src/libstd/sys/vxworks/fast_thread_local.rs b/src/libstd/sys/vxworks/thread_local_dtor.rs similarity index 82% rename from src/libstd/sys/vxworks/fast_thread_local.rs rename to src/libstd/sys/vxworks/thread_local_dtor.rs index 098668cf521dd..3f73f6c490326 100644 --- a/src/libstd/sys/vxworks/fast_thread_local.rs +++ b/src/libstd/sys/vxworks/thread_local_dtor.rs @@ -5,7 +5,3 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { use crate::sys_common::thread_local::register_dtor_fallback; register_dtor_fallback(t, dtor); } - -pub fn requires_move_before_drop() -> bool { - false -} diff --git a/src/libstd/sys/vxworks/thread_local.rs b/src/libstd/sys/vxworks/thread_local_key.rs similarity index 100% rename from src/libstd/sys/vxworks/thread_local.rs rename to src/libstd/sys/vxworks/thread_local_key.rs diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs index 4fe9661421b03..85f5282034ff1 100644 --- a/src/libstd/sys/wasi/mod.rs +++ b/src/libstd/sys/wasi/mod.rs @@ -36,8 +36,6 @@ pub mod net; pub mod os; pub use crate::sys_common::os_str_bytes as os_str; pub mod ext; -#[path = "../wasm/fast_thread_local.rs"] -pub mod fast_thread_local; pub mod path; pub mod pipe; pub mod process; @@ -47,8 +45,10 @@ pub mod rwlock; pub mod stack_overflow; pub mod stdio; pub mod thread; -#[path = "../wasm/thread_local.rs"] -pub mod thread_local; +#[path = "../wasm/thread_local_dtor.rs"] +pub mod thread_local_dtor; +#[path = "../wasm/thread_local_key.rs"] +pub mod thread_local_key; pub mod time; #[cfg(not(test))] diff --git a/src/libstd/sys/wasm/mod.rs b/src/libstd/sys/wasm/mod.rs index 050e8099af4ba..6939596e52d78 100644 --- a/src/libstd/sys/wasm/mod.rs +++ b/src/libstd/sys/wasm/mod.rs @@ -20,7 +20,6 @@ pub mod alloc; pub mod args; pub mod cmath; pub mod env; -pub mod fast_thread_local; pub mod fs; pub mod io; pub mod memchr; @@ -32,7 +31,8 @@ pub mod process; pub mod stack_overflow; pub mod stdio; pub mod thread; -pub mod thread_local; +pub mod thread_local_dtor; +pub mod thread_local_key; pub mod time; pub use crate::sys_common::os_str_bytes as os_str; diff --git a/src/libstd/sys/wasm/fast_thread_local.rs b/src/libstd/sys/wasm/thread_local_dtor.rs similarity index 100% rename from src/libstd/sys/wasm/fast_thread_local.rs rename to src/libstd/sys/wasm/thread_local_dtor.rs diff --git a/src/libstd/sys/hermit/thread_local.rs b/src/libstd/sys/wasm/thread_local_key.rs similarity index 100% rename from src/libstd/sys/hermit/thread_local.rs rename to src/libstd/sys/wasm/thread_local_key.rs diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index 193ab5b47ef13..9a52371280e15 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -20,7 +20,6 @@ pub mod cmath; pub mod condvar; pub mod env; pub mod ext; -pub mod fast_thread_local; pub mod fs; pub mod handle; pub mod io; @@ -35,7 +34,8 @@ pub mod process; pub mod rand; pub mod rwlock; pub mod thread; -pub mod thread_local; +pub mod thread_local_dtor; +pub mod thread_local_key; pub mod time; cfg_if::cfg_if! { if #[cfg(not(target_vendor = "uwp"))] { diff --git a/src/libstd/sys/windows/fast_thread_local.rs b/src/libstd/sys/windows/thread_local_dtor.rs similarity index 52% rename from src/libstd/sys/windows/fast_thread_local.rs rename to src/libstd/sys/windows/thread_local_dtor.rs index 191fa07f32a55..7be13bc4b2bc7 100644 --- a/src/libstd/sys/windows/fast_thread_local.rs +++ b/src/libstd/sys/windows/thread_local_dtor.rs @@ -1,4 +1,4 @@ #![unstable(feature = "thread_local_internals", issue = "none")] #![cfg(target_thread_local)] -pub use crate::sys_common::thread_local::register_dtor_fallback as register_dtor; +pub use crate::sys_common::thread_local_dtor::register_dtor_fallback as register_dtor; diff --git a/src/libstd/sys/windows/thread_local.rs b/src/libstd/sys/windows/thread_local_key.rs similarity index 100% rename from src/libstd/sys/windows/thread_local.rs rename to src/libstd/sys/windows/thread_local_key.rs diff --git a/src/libstd/sys_common/mod.rs b/src/libstd/sys_common/mod.rs index e03e0fc83454b..e57bb267cbd0f 100644 --- a/src/libstd/sys_common/mod.rs +++ b/src/libstd/sys_common/mod.rs @@ -65,7 +65,8 @@ pub mod remutex; pub mod rwlock; pub mod thread; pub mod thread_info; -pub mod thread_local; +pub mod thread_local_dtor; +pub mod thread_local_key; pub mod util; pub mod wtf8; diff --git a/src/libstd/sys_common/thread_local_dtor.rs b/src/libstd/sys_common/thread_local_dtor.rs new file mode 100644 index 0000000000000..6f5ebf4a27158 --- /dev/null +++ b/src/libstd/sys_common/thread_local_dtor.rs @@ -0,0 +1,49 @@ +//! Thread-local destructor +//! +//! Besides thread-local "keys" (pointer-sized non-adressable thread-local store +//! with an associated destructor), many platforms also provide thread-local +//! destructors that are not associated with any particular data. These are +//! often more efficient. +//! +//! This module provides a fallback implementation for that interface, based +//! on the less efficient thread-local "keys". Each platform provides +//! a `thread_local_dtor` module which will either re-export the fallback, +//! or implement something more efficient. + +#![unstable(feature = "thread_local_internals", issue = "none")] +#![allow(dead_code)] // sys isn't exported yet + +use crate::ptr; +use crate::sys_common::thread_local_key::StaticKey; + +pub unsafe fn register_dtor_fallback(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { + // The fallback implementation uses a vanilla OS-based TLS key to track + // the list of destructors that need to be run for this thread. The key + // then has its own destructor which runs all the other destructors. + // + // The destructor for DTORS is a little special in that it has a `while` + // loop to continuously drain the list of registered destructors. It + // *should* be the case that this loop always terminates because we + // provide the guarantee that a TLS key cannot be set after it is + // flagged for destruction. + + static DTORS: StaticKey = StaticKey::new(Some(run_dtors)); + type List = Vec<(*mut u8, unsafe extern "C" fn(*mut u8))>; + if DTORS.get().is_null() { + let v: Box = box Vec::new(); + DTORS.set(Box::into_raw(v) as *mut u8); + } + let list: &mut List = &mut *(DTORS.get() as *mut List); + list.push((t, dtor)); + + unsafe extern "C" fn run_dtors(mut ptr: *mut u8) { + while !ptr.is_null() { + let list: Box = Box::from_raw(ptr as *mut List); + for (ptr, dtor) in list.into_iter() { + dtor(ptr); + } + ptr = DTORS.get(); + DTORS.set(ptr::null_mut()); + } + } +} diff --git a/src/libstd/sys_common/thread_local.rs b/src/libstd/sys_common/thread_local_key.rs similarity index 85% rename from src/libstd/sys_common/thread_local.rs rename to src/libstd/sys_common/thread_local_key.rs index 756b8d044a20e..ac5b128298d78 100644 --- a/src/libstd/sys_common/thread_local.rs +++ b/src/libstd/sys_common/thread_local_key.rs @@ -4,7 +4,7 @@ //! using the native OS-provided facilities (think `TlsAlloc` or //! `pthread_setspecific`). The interface of this differs from the other types //! of thread-local-storage provided in this crate in that OS-based TLS can only -//! get/set pointers, +//! get/set pointer-sized data, possibly with an associated destructor. //! //! This module also provides two flavors of TLS. One is intended for static //! initialization, and does not contain a `Drop` implementation to deallocate @@ -14,7 +14,7 @@ //! # Usage //! //! This module should likely not be used directly unless other primitives are -//! being built on. types such as `thread_local::spawn::Key` are likely much +//! being built on. Types such as `thread_local::spawn::Key` are likely much //! more useful in practice than this OS-based version which likely requires //! unsafe code to interoperate with. //! @@ -48,9 +48,8 @@ #![unstable(feature = "thread_local_internals", issue = "none")] #![allow(dead_code)] // sys isn't exported yet -use crate::ptr; use crate::sync::atomic::{self, AtomicUsize, Ordering}; -use crate::sys::thread_local as imp; +use crate::sys::thread_local_key as imp; use crate::sys_common::mutex::Mutex; /// A type for TLS keys that are statically allocated. @@ -233,38 +232,6 @@ impl Drop for Key { } } -pub unsafe fn register_dtor_fallback(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { - // The fallback implementation uses a vanilla OS-based TLS key to track - // the list of destructors that need to be run for this thread. The key - // then has its own destructor which runs all the other destructors. - // - // The destructor for DTORS is a little special in that it has a `while` - // loop to continuously drain the list of registered destructors. It - // *should* be the case that this loop always terminates because we - // provide the guarantee that a TLS key cannot be set after it is - // flagged for destruction. - - static DTORS: StaticKey = StaticKey::new(Some(run_dtors)); - type List = Vec<(*mut u8, unsafe extern "C" fn(*mut u8))>; - if DTORS.get().is_null() { - let v: Box = box Vec::new(); - DTORS.set(Box::into_raw(v) as *mut u8); - } - let list: &mut List = &mut *(DTORS.get() as *mut List); - list.push((t, dtor)); - - unsafe extern "C" fn run_dtors(mut ptr: *mut u8) { - while !ptr.is_null() { - let list: Box = Box::from_raw(ptr as *mut List); - for (ptr, dtor) in list.into_iter() { - dtor(ptr); - } - ptr = DTORS.get(); - DTORS.set(ptr::null_mut()); - } - } -} - #[cfg(test)] mod tests { use super::{Key, StaticKey}; diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs index 094c468a6770e..ecd6fbc6b9395 100644 --- a/src/libstd/thread/local.rs +++ b/src/libstd/thread/local.rs @@ -363,7 +363,7 @@ pub mod fast { use crate::cell::Cell; use crate::fmt; use crate::mem; - use crate::sys::fast_thread_local::register_dtor; + use crate::sys::thread_local_dtor::register_dtor; #[derive(Copy, Clone)] enum DtorState { @@ -468,7 +468,7 @@ pub mod os { use crate::fmt; use crate::marker; use crate::ptr; - use crate::sys_common::thread_local::StaticKey as OsStaticKey; + use crate::sys_common::thread_local_key::StaticKey as OsStaticKey; pub struct Key { // OS-TLS key that we'll use to key off.