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

Slight reorganization of sys/(fast_)thread_local #74263

Merged
merged 2 commits into from
Jul 14, 2020
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
4 changes: 2 additions & 2 deletions src/libstd/sys/cloudabi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions src/libstd/sys/hermit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,25 @@ pub type Key = usize;

#[inline]
pub unsafe fn create(_dtor: Option<unsafe extern "C" fn(*mut u8)>) -> 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");
}
2 changes: 1 addition & 1 deletion src/libstd/sys/sgx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions src/libstd/sys/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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!
Expand All @@ -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"]
Expand Down
4 changes: 2 additions & 2 deletions src/libstd/sys/vxworks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
8 changes: 4 additions & 4 deletions src/libstd/sys/wasi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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))]
Expand Down
4 changes: 2 additions & 2 deletions src/libstd/sys/wasm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions src/libstd/sys/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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"))] {
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
3 changes: 2 additions & 1 deletion src/libstd/sys_common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
49 changes: 49 additions & 0 deletions src/libstd/sys_common/thread_local_dtor.rs
Original file line number Diff line number Diff line change
@@ -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<List> = 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<List> = Box::from_raw(ptr as *mut List);
for (ptr, dtor) in list.into_iter() {
dtor(ptr);
}
ptr = DTORS.get();
DTORS.set(ptr::null_mut());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
//!
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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<List> = 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<List> = 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};
Expand Down
4 changes: 2 additions & 2 deletions src/libstd/thread/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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<T> {
// OS-TLS key that we'll use to key off.
Expand Down