diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2020-04-06 00:53:50 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-04-06 00:53:50 +0200 |
| commit | 534f8dadb3d6d006509926c64d54eac2eefae9e5 (patch) | |
| tree | 0ab39271195d61d073af8f1e809e50dbb017091d /src | |
| parent | e1b380a675d5ab00ad7230a3823b73abe44cea56 (diff) | |
| parent | 935683bd9cf668a0f616a336528c768115847aad (diff) | |
| download | rust-534f8dadb3d6d006509926c64d54eac2eefae9e5.tar.gz rust-534f8dadb3d6d006509926c64d54eac2eefae9e5.zip | |
Rollup merge of #70808 - hermitcore:tls, r=dtolnay
Simplify dtor registration for HermitCore by using a list of destructors The implementation is similar to the macOS version and doesn't depend on additional OS support
Diffstat (limited to 'src')
| -rw-r--r-- | src/libstd/sys/hermit/fast_thread_local.rs | 34 | ||||
| -rw-r--r-- | src/libstd/sys/hermit/mod.rs | 2 | ||||
| -rw-r--r-- | src/libstd/sys/hermit/thread.rs | 4 | ||||
| -rw-r--r-- | src/libstd/sys/hermit/thread_local.rs | 52 |
4 files changed, 48 insertions, 44 deletions
diff --git a/src/libstd/sys/hermit/fast_thread_local.rs b/src/libstd/sys/hermit/fast_thread_local.rs index 1108e2545bd..9b683fce157 100644 --- a/src/libstd/sys/hermit/fast_thread_local.rs +++ b/src/libstd/sys/hermit/fast_thread_local.rs @@ -1,4 +1,36 @@ #![cfg(target_thread_local)] #![unstable(feature = "thread_local_internals", issue = "none")] -pub use crate::sys_common::thread_local::register_dtor_fallback as register_dtor; +// Simplify dtor registration by using a list of destructors. +// The this solution works like the implementation of macOS and +// doesn't additional OS support + +use crate::cell::Cell; +use crate::ptr; + +#[thread_local] +static DTORS: Cell<*mut List> = Cell::new(ptr::null_mut()); + +type List = Vec<(*mut u8, unsafe extern "C" fn(*mut u8))>; + +pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { + if DTORS.get().is_null() { + let v: Box<List> = box Vec::new(); + DTORS.set(Box::into_raw(v)); + } + + let list: &mut List = &mut *DTORS.get(); + list.push((t, dtor)); +} + +// every thread call this function to run through all possible destructors +pub unsafe fn run_dtors() { + let mut ptr = DTORS.replace(ptr::null_mut()); + while !ptr.is_null() { + let list = Box::from_raw(ptr); + for (ptr, dtor) in list.into_iter() { + dtor(ptr); + } + ptr = DTORS.replace(ptr::null_mut()); + } +} diff --git a/src/libstd/sys/hermit/mod.rs b/src/libstd/sys/hermit/mod.rs index 958532b8fc4..6736d964e52 100644 --- a/src/libstd/sys/hermit/mod.rs +++ b/src/libstd/sys/hermit/mod.rs @@ -103,6 +103,7 @@ pub unsafe extern "C" fn runtime_entry( argv: *const *const c_char, env: *const *const c_char, ) -> ! { + use crate::sys::hermit::fast_thread_local::run_dtors; extern "C" { fn main(argc: isize, argv: *const *const c_char) -> i32; } @@ -112,6 +113,7 @@ pub unsafe extern "C" fn runtime_entry( let result = main(argc as isize, argv); + run_dtors(); abi::exit(result); } diff --git a/src/libstd/sys/hermit/thread.rs b/src/libstd/sys/hermit/thread.rs index 0bb774ca137..7e3fb4c6d20 100644 --- a/src/libstd/sys/hermit/thread.rs +++ b/src/libstd/sys/hermit/thread.rs @@ -4,6 +4,7 @@ use crate::ffi::CStr; use crate::io; use crate::mem; use crate::sys::hermit::abi; +use crate::sys::hermit::fast_thread_local::run_dtors; use crate::time::Duration; pub type Tid = abi::Tid; @@ -46,6 +47,9 @@ impl Thread { unsafe { // Finally, let's run some code. Box::from_raw(main as *mut Box<dyn FnOnce()>)(); + + // run all destructors + run_dtors(); } } } diff --git a/src/libstd/sys/hermit/thread_local.rs b/src/libstd/sys/hermit/thread_local.rs index c6f8adb2162..f8be9863ed5 100644 --- a/src/libstd/sys/hermit/thread_local.rs +++ b/src/libstd/sys/hermit/thread_local.rs @@ -1,60 +1,26 @@ -#![allow(dead_code)] // not used on all platforms - -use crate::collections::BTreeMap; -use crate::ptr; -use crate::sync::atomic::{AtomicUsize, Ordering}; -use crate::sys_common::mutex::Mutex; - pub type Key = usize; -type Dtor = unsafe extern "C" fn(*mut u8); - -static NEXT_KEY: AtomicUsize = AtomicUsize::new(0); - -static mut KEYS: *mut BTreeMap<Key, Option<Dtor>> = ptr::null_mut(); -static KEYS_LOCK: Mutex = Mutex::new(); - -#[thread_local] -static mut LOCALS: *mut BTreeMap<Key, *mut u8> = ptr::null_mut(); - -unsafe fn keys() -> &'static mut BTreeMap<Key, Option<Dtor>> { - if KEYS.is_null() { - KEYS = Box::into_raw(Box::new(BTreeMap::new())); - } - &mut *KEYS -} - -unsafe fn locals() -> &'static mut BTreeMap<Key, *mut u8> { - if LOCALS.is_null() { - LOCALS = Box::into_raw(Box::new(BTreeMap::new())); - } - &mut *LOCALS -} - #[inline] -pub unsafe fn create(dtor: Option<Dtor>) -> Key { - let key = NEXT_KEY.fetch_add(1, Ordering::SeqCst); - let _guard = KEYS_LOCK.lock(); - keys().insert(key, dtor); - key +pub unsafe fn create(_dtor: Option<unsafe extern "C" fn(*mut u8)>) -> Key { + panic!("should not be used on the wasm target"); } #[inline] -pub unsafe fn get(key: Key) -> *mut u8 { - if let Some(&entry) = locals().get(&key) { entry } else { ptr::null_mut() } +pub unsafe fn set(_key: Key, _value: *mut u8) { + panic!("should not be used on the wasm target"); } #[inline] -pub unsafe fn set(key: Key, value: *mut u8) { - locals().insert(key, value); +pub unsafe fn get(_key: Key) -> *mut u8 { + panic!("should not be used on the wasm target"); } #[inline] -pub unsafe fn destroy(key: Key) { - keys().remove(&key); +pub unsafe fn destroy(_key: Key) { + panic!("should not be used on the wasm target"); } #[inline] pub fn requires_synchronized_create() -> bool { - false + panic!("should not be used on the wasm target"); } |
