Skip to content

Commit 2fc091f

Browse files
committed
Use volatile to make p_thread_callback used
1 parent 34aab62 commit 2fc091f

File tree

1 file changed

+11
-17
lines changed

1 file changed

+11
-17
lines changed

library/std/src/sys/pal/windows/thread_local_key.rs

+11-17
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
11
use crate::cell::UnsafeCell;
22
use crate::ptr;
33
use crate::sync::atomic::{
4-
AtomicBool, AtomicPtr, AtomicU32,
4+
AtomicPtr, AtomicU32,
55
Ordering::{AcqRel, Acquire, Relaxed, Release},
66
};
77
use crate::sys::c;
88

99
#[cfg(test)]
1010
mod tests;
1111

12-
/// An optimization hint. The compiler is often smart enough to know if an atomic
13-
/// is never set and can remove dead code based on that fact.
14-
static HAS_DTORS: AtomicBool = AtomicBool::new(false);
15-
1612
// Using a per-thread list avoids the problems in synchronizing global state.
1713
#[thread_local]
1814
#[cfg(target_thread_local)]
@@ -24,12 +20,11 @@ static DESTRUCTORS: crate::cell::RefCell<Vec<(*mut u8, unsafe extern "C" fn(*mut
2420
#[inline(never)]
2521
#[cfg(target_thread_local)]
2622
pub unsafe fn register_keyless_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
23+
dtors_used();
2724
match DESTRUCTORS.try_borrow_mut() {
2825
Ok(mut dtors) => dtors.push((t, dtor)),
2926
Err(_) => rtabort!("global allocator may not use TLS"),
3027
}
31-
32-
HAS_DTORS.store(true, Relaxed);
3328
}
3429

3530
#[inline(never)] // See comment above
@@ -130,6 +125,7 @@ impl StaticKey {
130125
#[cold]
131126
unsafe fn init(&'static self) -> Key {
132127
if self.dtor.is_some() {
128+
dtors_used();
133129
let mut pending = c::FALSE;
134130
let r = c::InitOnceBeginInitialize(self.once.get(), 0, &mut pending, ptr::null_mut());
135131
assert_eq!(r, c::TRUE);
@@ -215,7 +211,6 @@ unsafe fn register_dtor(key: &'static StaticKey) {
215211
Err(new) => head = new,
216212
}
217213
}
218-
HAS_DTORS.store(true, Release);
219214
}
220215

221216
// -------------------------------------------------------------------------
@@ -281,17 +276,16 @@ unsafe fn register_dtor(key: &'static StaticKey) {
281276
// the address of the symbol to ensure it sticks around.
282277

283278
#[link_section = ".CRT$XLB"]
284-
#[allow(dead_code, unused_variables)]
285-
#[used] // we don't want LLVM eliminating this symbol for any reason, and
286-
// when the symbol makes it to the linker the linker will take over
287279
pub static p_thread_callback: unsafe extern "system" fn(c::LPVOID, c::DWORD, c::LPVOID) =
288280
on_tls_callback;
289281

290-
#[allow(dead_code, unused_variables)]
291-
unsafe extern "system" fn on_tls_callback(h: c::LPVOID, dwReason: c::DWORD, pv: c::LPVOID) {
292-
if !HAS_DTORS.load(Acquire) {
293-
return;
294-
}
282+
fn dtors_used() {
283+
// we don't want LLVM eliminating p_thread_callback when destructors are used.
284+
// when the symbol makes it to the linker the linker will take over
285+
unsafe { crate::intrinsics::volatile_load(&p_thread_callback) };
286+
}
287+
288+
unsafe extern "system" fn on_tls_callback(_h: c::LPVOID, dwReason: c::DWORD, _pv: c::LPVOID) {
295289
if dwReason == c::DLL_THREAD_DETACH || dwReason == c::DLL_PROCESS_DETACH {
296290
#[cfg(not(target_thread_local))]
297291
run_dtors();
@@ -313,7 +307,7 @@ unsafe extern "system" fn on_tls_callback(h: c::LPVOID, dwReason: c::DWORD, pv:
313307
unsafe fn reference_tls_used() {}
314308
}
315309

316-
#[allow(dead_code)] // actually called below
310+
#[cfg(not(target_thread_local))]
317311
unsafe fn run_dtors() {
318312
for _ in 0..5 {
319313
let mut any_run = false;

0 commit comments

Comments
 (0)