From 8082fb988a5915e693f18e6d299deaae64834079 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 12 Jul 2020 11:37:11 +0200 Subject: [PATCH] rename fast_thread_local -> thread_local_dtor; thread_local -> thread_local_key --- src/libstd/sys/unix/mod.rs | 4 +- ...t_thread_local.rs => thread_local_dtor.rs} | 5 +- .../{thread_local.rs => thread_local_key.rs} | 0 src/libstd/sys/windows/mod.rs | 4 +- ...t_thread_local.rs => thread_local_dtor.rs} | 2 +- .../{thread_local.rs => thread_local_key.rs} | 0 src/libstd/sys_common/mod.rs | 3 +- src/libstd/sys_common/thread_local_dtor.rs | 49 +++++++++++++++++++ .../{thread_local.rs => thread_local_key.rs} | 39 ++------------- src/libstd/thread/local.rs | 4 +- 10 files changed, 65 insertions(+), 45 deletions(-) rename src/libstd/sys/unix/{fast_thread_local.rs => thread_local_dtor.rs} (94%) rename src/libstd/sys/unix/{thread_local.rs => thread_local_key.rs} (100%) rename src/libstd/sys/windows/{fast_thread_local.rs => thread_local_dtor.rs} (52%) rename src/libstd/sys/windows/{thread_local.rs => thread_local_key.rs} (100%) create mode 100644 src/libstd/sys_common/thread_local_dtor.rs rename src/libstd/sys_common/{thread_local.rs => thread_local_key.rs} (85%) diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index b1688e74173..7cde02baedb 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_key; +pub mod thread_local_dtor; 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 8730b4de8be..c3275eb6f0e 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/windows/mod.rs b/src/libstd/sys/windows/mod.rs index 193ab5b47ef..d6a8eec4b80 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_key; +pub mod thread_local_dtor; 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 191fa07f32a..7be13bc4b2b 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 e03e0fc8345..1212b05c88a 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_key; +pub mod thread_local_dtor; 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 00000000000..6f5ebf4a271 --- /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 756b8d044a2..ac5b128298d 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 094c468a677..ecd6fbc6b93 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.