Skip to content

Commit

Permalink
rename fast_thread_local -> thread_local_dtor; thread_local -> thread…
Browse files Browse the repository at this point in the history
…_local_key
  • Loading branch information
RalfJung committed Jul 12, 2020
1 parent daecab3 commit 8082fb9
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 45 deletions.
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_key;
pub mod thread_local_dtor;
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
File renamed without changes.
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_key;
pub mod thread_local_dtor;
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;
File renamed without changes.
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_key;
pub mod thread_local_dtor;
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

0 comments on commit 8082fb9

Please sign in to comment.