Skip to content

Commit e1b36d9

Browse files
authored
Rollup merge of rust-lang#137897 - xTachyon:tls-fix, r=thomcc,jieyouxu
fix pthread-based tls on apple targets Tries to fix rust-lang#127773.
2 parents ea44554 + 3f84d8d commit e1b36d9

File tree

3 files changed

+23
-1
lines changed

3 files changed

+23
-1
lines changed

std/src/sys/thread_local/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ pub(crate) mod key {
138138
not(target_family = "wasm"),
139139
target_family = "unix",
140140
),
141+
all(not(target_thread_local), target_vendor = "apple"),
141142
target_os = "teeos",
142143
all(target_os = "wasi", target_env = "p1", target_feature = "atomics"),
143144
))] {

std/tests/thread_local/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![feature(cfg_target_thread_local)]
2+
13
#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))]
24
mod tests;
35

std/tests/thread_local/tests.rs

+20-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::cell::{Cell, UnsafeCell};
22
use std::sync::atomic::{AtomicU8, Ordering};
33
use std::sync::{Arc, Condvar, Mutex};
4-
use std::thread::{self, Builder, LocalKey};
4+
use std::thread::{self, LocalKey};
55
use std::thread_local;
66

77
#[derive(Clone, Default)]
@@ -345,8 +345,27 @@ fn join_orders_after_tls_destructors() {
345345
}
346346

347347
// Test that thread::current is still available in TLS destructors.
348+
//
349+
// The test won't currently work without target_thread_local, aka with slow tls.
350+
// The runtime tries very hard to drop last the TLS variable that keeps the information about the
351+
// current thread, by using several tricks like deffering the drop to a later round of TLS destruction.
352+
// However, this only seems to work with fast tls.
353+
//
354+
// With slow TLS, it seems that multiple libc implementations will just set the value to null the first
355+
// time they encounter it, regardless of it having a destructor or not. This means that trying to
356+
// retrieve it later in a drop impl of another TLS variable will not work.
357+
//
358+
// ** Apple libc: https://github.com/apple-oss-distributions/libpthread/blob/c032e0b076700a0a47db75528a282b8d3a06531a/src/pthread_tsd.c#L293
359+
// Sets the variable to null if it has a destructor and the value is not null. However, all variables
360+
// created with pthread_key_create are marked as having a destructor, even if the fn ptr called with
361+
// it is null.
362+
// ** glibc: https://github.com/bminor/glibc/blob/e5893e6349541d871e8a25120bca014551d13ff5/nptl/nptl_deallocate_tsd.c#L59
363+
// ** musl: https://github.com/kraj/musl/blob/1880359b54ff7dd9f5016002bfdae4b136007dde/src/thread/pthread_key_create.c#L87
364+
#[cfg(target_thread_local)]
348365
#[test]
349366
fn thread_current_in_dtor() {
367+
use std::thread::Builder;
368+
350369
// Go through one round of TLS destruction first.
351370
struct Defer;
352371
impl Drop for Defer {

0 commit comments

Comments
 (0)