Skip to content

Commit fadd91c

Browse files
authoredJul 14, 2020
Rollup merge of #74263 - RalfJung:thread-local, r=Mark-Simulacrum
Slight reorganization of sys/(fast_)thread_local I was long confused by the `thread_local` and `fast_thread_local` modules in the `sys(_common)` part of libstd. The names make it *sound* like `fast_thread_local` is just a faster version of `thread_local`, but really these are totally different APIs: one provides thread-local "keys", which are non-addressable pointer-sized pieces of local storage with an associated destructor; the other (the "fast" one) provides just a destructor. So I propose we rename `fast_thread_local` to `thread_local_dtor`, and `thread_local` to `thread_local_key`. That's what this PR does.
2 parents 1e74f28 + 7dc3886 commit fadd91c

23 files changed

+83
-67
lines changed
 

‎src/libstd/sys/cloudabi/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ pub mod rwlock;
1616
pub mod stack_overflow;
1717
pub mod stdio;
1818
pub mod thread;
19-
#[path = "../unix/thread_local.rs"]
20-
pub mod thread_local;
19+
#[path = "../unix/thread_local_key.rs"]
20+
pub mod thread_local_key;
2121
pub mod time;
2222

2323
pub use crate::sys_common::os_str_bytes as os_str;

‎src/libstd/sys/hermit/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ pub mod cmath;
2222
pub mod condvar;
2323
pub mod env;
2424
pub mod ext;
25-
pub mod fast_thread_local;
2625
pub mod fd;
2726
pub mod fs;
2827
pub mod io;
@@ -37,7 +36,8 @@ pub mod rwlock;
3736
pub mod stack_overflow;
3837
pub mod stdio;
3938
pub mod thread;
40-
pub mod thread_local;
39+
pub mod thread_local_dtor;
40+
pub mod thread_local_key;
4141
pub mod time;
4242

4343
use crate::io::ErrorKind;

‎src/libstd/sys/wasm/thread_local.rs ‎src/libstd/sys/hermit/thread_local_key.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,25 @@ pub type Key = usize;
22

33
#[inline]
44
pub unsafe fn create(_dtor: Option<unsafe extern "C" fn(*mut u8)>) -> Key {
5-
panic!("should not be used on the wasm target");
5+
panic!("should not be used on the hermit target");
66
}
77

88
#[inline]
99
pub unsafe fn set(_key: Key, _value: *mut u8) {
10-
panic!("should not be used on the wasm target");
10+
panic!("should not be used on the hermit target");
1111
}
1212

1313
#[inline]
1414
pub unsafe fn get(_key: Key) -> *mut u8 {
15-
panic!("should not be used on the wasm target");
15+
panic!("should not be used on the hermit target");
1616
}
1717

1818
#[inline]
1919
pub unsafe fn destroy(_key: Key) {
20-
panic!("should not be used on the wasm target");
20+
panic!("should not be used on the hermit target");
2121
}
2222

2323
#[inline]
2424
pub fn requires_synchronized_create() -> bool {
25-
panic!("should not be used on the wasm target");
25+
panic!("should not be used on the hermit target");
2626
}

‎src/libstd/sys/sgx/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub mod rwlock;
3030
pub mod stack_overflow;
3131
pub mod stdio;
3232
pub mod thread;
33-
pub mod thread_local;
33+
pub mod thread_local_key;
3434
pub mod time;
3535

3636
pub use crate::sys_common::os_str_bytes as os_str;
File renamed without changes.

‎src/libstd/sys/unix/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ pub mod cmath;
4747
pub mod condvar;
4848
pub mod env;
4949
pub mod ext;
50-
pub mod fast_thread_local;
5150
pub mod fd;
5251
pub mod fs;
5352
pub mod io;
@@ -68,7 +67,8 @@ pub mod rwlock;
6867
pub mod stack_overflow;
6968
pub mod stdio;
7069
pub mod thread;
71-
pub mod thread_local;
70+
pub mod thread_local_dtor;
71+
pub mod thread_local_key;
7272
pub mod time;
7373

7474
pub use crate::sys_common::os_str_bytes as os_str;

‎src/libstd/sys/unix/fast_thread_local.rs ‎src/libstd/sys/unix/thread_local_dtor.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#![cfg(target_thread_local)]
22
#![unstable(feature = "thread_local_internals", issue = "none")]
33

4+
//! Provides thread-local destructors without an associated "key", which
5+
//! can be more efficient.
6+
47
// Since what appears to be glibc 2.18 this symbol has been shipped which
58
// GCC and clang both use to invoke destructors in thread_local globals, so
69
// let's do the same!
@@ -16,7 +19,7 @@
1619
))]
1720
pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
1821
use crate::mem;
19-
use crate::sys_common::thread_local::register_dtor_fallback;
22+
use crate::sys_common::thread_local_dtor::register_dtor_fallback;
2023

2124
extern "C" {
2225
#[linkage = "extern_weak"]
File renamed without changes.

‎src/libstd/sys/vxworks/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ pub mod cmath;
1313
pub mod condvar;
1414
pub mod env;
1515
pub mod ext;
16-
pub mod fast_thread_local;
1716
pub mod fd;
1817
pub mod fs;
1918
pub mod io;
@@ -29,7 +28,8 @@ pub mod rwlock;
2928
pub mod stack_overflow;
3029
pub mod stdio;
3130
pub mod thread;
32-
pub mod thread_local;
31+
pub mod thread_local_dtor;
32+
pub mod thread_local_key;
3333
pub mod time;
3434

3535
pub use crate::sys_common::os_str_bytes as os_str;

‎src/libstd/sys/vxworks/fast_thread_local.rs ‎src/libstd/sys/vxworks/thread_local_dtor.rs

-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,3 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
55
use crate::sys_common::thread_local::register_dtor_fallback;
66
register_dtor_fallback(t, dtor);
77
}
8-
9-
pub fn requires_move_before_drop() -> bool {
10-
false
11-
}

‎src/libstd/sys/wasi/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ pub mod net;
3636
pub mod os;
3737
pub use crate::sys_common::os_str_bytes as os_str;
3838
pub mod ext;
39-
#[path = "../wasm/fast_thread_local.rs"]
40-
pub mod fast_thread_local;
4139
pub mod path;
4240
pub mod pipe;
4341
pub mod process;
@@ -47,8 +45,10 @@ pub mod rwlock;
4745
pub mod stack_overflow;
4846
pub mod stdio;
4947
pub mod thread;
50-
#[path = "../wasm/thread_local.rs"]
51-
pub mod thread_local;
48+
#[path = "../wasm/thread_local_dtor.rs"]
49+
pub mod thread_local_dtor;
50+
#[path = "../wasm/thread_local_key.rs"]
51+
pub mod thread_local_key;
5252
pub mod time;
5353

5454
#[cfg(not(test))]

‎src/libstd/sys/wasm/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ pub mod alloc;
2020
pub mod args;
2121
pub mod cmath;
2222
pub mod env;
23-
pub mod fast_thread_local;
2423
pub mod fs;
2524
pub mod io;
2625
pub mod memchr;
@@ -32,7 +31,8 @@ pub mod process;
3231
pub mod stack_overflow;
3332
pub mod stdio;
3433
pub mod thread;
35-
pub mod thread_local;
34+
pub mod thread_local_dtor;
35+
pub mod thread_local_key;
3636
pub mod time;
3737

3838
pub use crate::sys_common::os_str_bytes as os_str;
File renamed without changes.

‎src/libstd/sys/windows/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ pub mod cmath;
2020
pub mod condvar;
2121
pub mod env;
2222
pub mod ext;
23-
pub mod fast_thread_local;
2423
pub mod fs;
2524
pub mod handle;
2625
pub mod io;
@@ -35,7 +34,8 @@ pub mod process;
3534
pub mod rand;
3635
pub mod rwlock;
3736
pub mod thread;
38-
pub mod thread_local;
37+
pub mod thread_local_dtor;
38+
pub mod thread_local_key;
3939
pub mod time;
4040
cfg_if::cfg_if! {
4141
if #[cfg(not(target_vendor = "uwp"))] {
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
#![unstable(feature = "thread_local_internals", issue = "none")]
22
#![cfg(target_thread_local)]
33

4-
pub use crate::sys_common::thread_local::register_dtor_fallback as register_dtor;
4+
pub use crate::sys_common::thread_local_dtor::register_dtor_fallback as register_dtor;

‎src/libstd/sys_common/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ pub mod remutex;
6565
pub mod rwlock;
6666
pub mod thread;
6767
pub mod thread_info;
68-
pub mod thread_local;
68+
pub mod thread_local_dtor;
69+
pub mod thread_local_key;
6970
pub mod util;
7071
pub mod wtf8;
7172

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//! Thread-local destructor
2+
//!
3+
//! Besides thread-local "keys" (pointer-sized non-adressable thread-local store
4+
//! with an associated destructor), many platforms also provide thread-local
5+
//! destructors that are not associated with any particular data. These are
6+
//! often more efficient.
7+
//!
8+
//! This module provides a fallback implementation for that interface, based
9+
//! on the less efficient thread-local "keys". Each platform provides
10+
//! a `thread_local_dtor` module which will either re-export the fallback,
11+
//! or implement something more efficient.
12+
13+
#![unstable(feature = "thread_local_internals", issue = "none")]
14+
#![allow(dead_code)] // sys isn't exported yet
15+
16+
use crate::ptr;
17+
use crate::sys_common::thread_local_key::StaticKey;
18+
19+
pub unsafe fn register_dtor_fallback(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
20+
// The fallback implementation uses a vanilla OS-based TLS key to track
21+
// the list of destructors that need to be run for this thread. The key
22+
// then has its own destructor which runs all the other destructors.
23+
//
24+
// The destructor for DTORS is a little special in that it has a `while`
25+
// loop to continuously drain the list of registered destructors. It
26+
// *should* be the case that this loop always terminates because we
27+
// provide the guarantee that a TLS key cannot be set after it is
28+
// flagged for destruction.
29+
30+
static DTORS: StaticKey = StaticKey::new(Some(run_dtors));
31+
type List = Vec<(*mut u8, unsafe extern "C" fn(*mut u8))>;
32+
if DTORS.get().is_null() {
33+
let v: Box<List> = box Vec::new();
34+
DTORS.set(Box::into_raw(v) as *mut u8);
35+
}
36+
let list: &mut List = &mut *(DTORS.get() as *mut List);
37+
list.push((t, dtor));
38+
39+
unsafe extern "C" fn run_dtors(mut ptr: *mut u8) {
40+
while !ptr.is_null() {
41+
let list: Box<List> = Box::from_raw(ptr as *mut List);
42+
for (ptr, dtor) in list.into_iter() {
43+
dtor(ptr);
44+
}
45+
ptr = DTORS.get();
46+
DTORS.set(ptr::null_mut());
47+
}
48+
}
49+
}

‎src/libstd/sys_common/thread_local.rs ‎src/libstd/sys_common/thread_local_key.rs

+3-36
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//! using the native OS-provided facilities (think `TlsAlloc` or
55
//! `pthread_setspecific`). The interface of this differs from the other types
66
//! of thread-local-storage provided in this crate in that OS-based TLS can only
7-
//! get/set pointers,
7+
//! get/set pointer-sized data, possibly with an associated destructor.
88
//!
99
//! This module also provides two flavors of TLS. One is intended for static
1010
//! initialization, and does not contain a `Drop` implementation to deallocate
@@ -14,7 +14,7 @@
1414
//! # Usage
1515
//!
1616
//! This module should likely not be used directly unless other primitives are
17-
//! being built on. types such as `thread_local::spawn::Key` are likely much
17+
//! being built on. Types such as `thread_local::spawn::Key` are likely much
1818
//! more useful in practice than this OS-based version which likely requires
1919
//! unsafe code to interoperate with.
2020
//!
@@ -48,9 +48,8 @@
4848
#![unstable(feature = "thread_local_internals", issue = "none")]
4949
#![allow(dead_code)] // sys isn't exported yet
5050

51-
use crate::ptr;
5251
use crate::sync::atomic::{self, AtomicUsize, Ordering};
53-
use crate::sys::thread_local as imp;
52+
use crate::sys::thread_local_key as imp;
5453
use crate::sys_common::mutex::Mutex;
5554

5655
/// A type for TLS keys that are statically allocated.
@@ -233,38 +232,6 @@ impl Drop for Key {
233232
}
234233
}
235234

236-
pub unsafe fn register_dtor_fallback(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
237-
// The fallback implementation uses a vanilla OS-based TLS key to track
238-
// the list of destructors that need to be run for this thread. The key
239-
// then has its own destructor which runs all the other destructors.
240-
//
241-
// The destructor for DTORS is a little special in that it has a `while`
242-
// loop to continuously drain the list of registered destructors. It
243-
// *should* be the case that this loop always terminates because we
244-
// provide the guarantee that a TLS key cannot be set after it is
245-
// flagged for destruction.
246-
247-
static DTORS: StaticKey = StaticKey::new(Some(run_dtors));
248-
type List = Vec<(*mut u8, unsafe extern "C" fn(*mut u8))>;
249-
if DTORS.get().is_null() {
250-
let v: Box<List> = box Vec::new();
251-
DTORS.set(Box::into_raw(v) as *mut u8);
252-
}
253-
let list: &mut List = &mut *(DTORS.get() as *mut List);
254-
list.push((t, dtor));
255-
256-
unsafe extern "C" fn run_dtors(mut ptr: *mut u8) {
257-
while !ptr.is_null() {
258-
let list: Box<List> = Box::from_raw(ptr as *mut List);
259-
for (ptr, dtor) in list.into_iter() {
260-
dtor(ptr);
261-
}
262-
ptr = DTORS.get();
263-
DTORS.set(ptr::null_mut());
264-
}
265-
}
266-
}
267-
268235
#[cfg(test)]
269236
mod tests {
270237
use super::{Key, StaticKey};

‎src/libstd/thread/local.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ pub mod fast {
363363
use crate::cell::Cell;
364364
use crate::fmt;
365365
use crate::mem;
366-
use crate::sys::fast_thread_local::register_dtor;
366+
use crate::sys::thread_local_dtor::register_dtor;
367367

368368
#[derive(Copy, Clone)]
369369
enum DtorState {
@@ -468,7 +468,7 @@ pub mod os {
468468
use crate::fmt;
469469
use crate::marker;
470470
use crate::ptr;
471-
use crate::sys_common::thread_local::StaticKey as OsStaticKey;
471+
use crate::sys_common::thread_local_key::StaticKey as OsStaticKey;
472472

473473
pub struct Key<T> {
474474
// OS-TLS key that we'll use to key off.

0 commit comments

Comments
 (0)
Please sign in to comment.