From ec5f41a9531947cd87d7daca124e2e7b55f23b35 Mon Sep 17 00:00:00 2001 From: Sebastian Urban Date: Sat, 23 Nov 2024 21:28:09 +0100 Subject: [PATCH 1/4] Run TLS destructors for wasm32-wasip1-threads The target has support for pthreads and allows registration of TLS destructors. --- .../std/src/sys/thread_local/guard/wasi.rs | 71 +++++++++++++++++++ library/std/src/sys/thread_local/mod.rs | 3 + 2 files changed, 74 insertions(+) create mode 100644 library/std/src/sys/thread_local/guard/wasi.rs diff --git a/library/std/src/sys/thread_local/guard/wasi.rs b/library/std/src/sys/thread_local/guard/wasi.rs new file mode 100644 index 0000000000000..dfd1f126aa0f1 --- /dev/null +++ b/library/std/src/sys/thread_local/guard/wasi.rs @@ -0,0 +1,71 @@ +//! wasm32-wasip1 has pthreads support. + +use crate::cell::Cell; +use crate::sync::atomic::{AtomicBool, Ordering}; +use crate::sys::thread_local::destructors; +use crate::{ffi, ptr}; + +// Add a few symbols not in upstream `libc` just yet. +mod libc { + pub use libc::*; + + use crate::ffi; + + #[allow(non_camel_case_types)] + pub type pthread_key_t = ffi::c_uint; + + extern "C" { + pub fn pthread_key_create( + key: *mut pthread_key_t, + destructor: unsafe extern "C" fn(*mut ffi::c_void), + ) -> ffi::c_int; + + pub fn pthread_setspecific(key: pthread_key_t, value: *const ffi::c_void) -> ffi::c_int; + } +} + +pub fn enable() { + enable_main(); + enable_thread(); +} + +fn enable_main() { + static REGISTERED: AtomicBool = AtomicBool::new(false); + + if !REGISTERED.swap(true, Ordering::AcqRel) { + unsafe { + assert_eq!(libc::atexit(run_main_dtors), 0); + } + } + + extern "C" fn run_main_dtors() { + unsafe { + destructors::run(); + crate::rt::thread_cleanup(); + } + } +} + +fn enable_thread() { + #[thread_local] + static REGISTERED: Cell = Cell::new(false); + + if !REGISTERED.replace(true) { + unsafe { + let mut key: libc::pthread_key_t = 0; + assert_eq!(libc::pthread_key_create(&mut key, run_thread_dtors), 0); + + // We must set the value to a non-NULL pointer value so that + // the destructor is run on thread exit. The pointer is only + // passed to run_dtors and never dereferenced. + assert_eq!(libc::pthread_setspecific(key, ptr::without_provenance(1)), 0); + } + } + + extern "C" fn run_thread_dtors(_: *mut ffi::c_void) { + unsafe { + destructors::run(); + crate::rt::thread_cleanup(); + } + } +} diff --git a/library/std/src/sys/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs index 31d3b43906004..042f0f76c9a4d 100644 --- a/library/std/src/sys/thread_local/mod.rs +++ b/library/std/src/sys/thread_local/mod.rs @@ -85,6 +85,9 @@ pub(crate) mod guard { } else if #[cfg(target_os = "windows")] { mod windows; pub(crate) use windows::enable; + } else if #[cfg(all(target_os = "wasi"))] { + mod wasi; + pub(crate) use wasi::enable; } else if #[cfg(any( target_family = "wasm", target_os = "uefi", From 4fe15b06e8f3ea9ebcb916df2fd4b2f0e9537296 Mon Sep 17 00:00:00 2001 From: Sebastian Urban Date: Tue, 3 Dec 2024 16:16:08 +0100 Subject: [PATCH 2/4] Use UNIX thread_local implementation for WASI. --- .../std/src/sys/thread_local/guard/wasi.rs | 71 ------------------- library/std/src/sys/thread_local/key/unix.rs | 20 ++++++ library/std/src/sys/thread_local/mod.rs | 6 +- 3 files changed, 22 insertions(+), 75 deletions(-) delete mode 100644 library/std/src/sys/thread_local/guard/wasi.rs diff --git a/library/std/src/sys/thread_local/guard/wasi.rs b/library/std/src/sys/thread_local/guard/wasi.rs deleted file mode 100644 index dfd1f126aa0f1..0000000000000 --- a/library/std/src/sys/thread_local/guard/wasi.rs +++ /dev/null @@ -1,71 +0,0 @@ -//! wasm32-wasip1 has pthreads support. - -use crate::cell::Cell; -use crate::sync::atomic::{AtomicBool, Ordering}; -use crate::sys::thread_local::destructors; -use crate::{ffi, ptr}; - -// Add a few symbols not in upstream `libc` just yet. -mod libc { - pub use libc::*; - - use crate::ffi; - - #[allow(non_camel_case_types)] - pub type pthread_key_t = ffi::c_uint; - - extern "C" { - pub fn pthread_key_create( - key: *mut pthread_key_t, - destructor: unsafe extern "C" fn(*mut ffi::c_void), - ) -> ffi::c_int; - - pub fn pthread_setspecific(key: pthread_key_t, value: *const ffi::c_void) -> ffi::c_int; - } -} - -pub fn enable() { - enable_main(); - enable_thread(); -} - -fn enable_main() { - static REGISTERED: AtomicBool = AtomicBool::new(false); - - if !REGISTERED.swap(true, Ordering::AcqRel) { - unsafe { - assert_eq!(libc::atexit(run_main_dtors), 0); - } - } - - extern "C" fn run_main_dtors() { - unsafe { - destructors::run(); - crate::rt::thread_cleanup(); - } - } -} - -fn enable_thread() { - #[thread_local] - static REGISTERED: Cell = Cell::new(false); - - if !REGISTERED.replace(true) { - unsafe { - let mut key: libc::pthread_key_t = 0; - assert_eq!(libc::pthread_key_create(&mut key, run_thread_dtors), 0); - - // We must set the value to a non-NULL pointer value so that - // the destructor is run on thread exit. The pointer is only - // passed to run_dtors and never dereferenced. - assert_eq!(libc::pthread_setspecific(key, ptr::without_provenance(1)), 0); - } - } - - extern "C" fn run_thread_dtors(_: *mut ffi::c_void) { - unsafe { - destructors::run(); - crate::rt::thread_cleanup(); - } - } -} diff --git a/library/std/src/sys/thread_local/key/unix.rs b/library/std/src/sys/thread_local/key/unix.rs index 28e48a750b9bf..6661e378dbf44 100644 --- a/library/std/src/sys/thread_local/key/unix.rs +++ b/library/std/src/sys/thread_local/key/unix.rs @@ -1,5 +1,25 @@ use crate::mem; +// For WASI add a few symbols not in upstream `libc` just yet. +#[cfg(target_os = "wasi")] +mod libc { + use crate::ffi; + + #[allow(non_camel_case_types)] + pub type pthread_key_t = ffi::c_uint; + + extern "C" { + pub fn pthread_key_create( + key: *mut pthread_key_t, + destructor: unsafe extern "C" fn(*mut ffi::c_void), + ) -> ffi::c_int; + #[allow(dead_code)] + pub fn pthread_getspecific(key: pthread_key_t) -> *mut ffi::c_void; + pub fn pthread_setspecific(key: pthread_key_t, value: *const ffi::c_void) -> ffi::c_int; + pub fn pthread_key_delete(key: pthread_key_t) -> ffi::c_int; + } +} + pub type Key = libc::pthread_key_t; #[inline] diff --git a/library/std/src/sys/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs index 042f0f76c9a4d..82e1aeabf5ba1 100644 --- a/library/std/src/sys/thread_local/mod.rs +++ b/library/std/src/sys/thread_local/mod.rs @@ -85,11 +85,8 @@ pub(crate) mod guard { } else if #[cfg(target_os = "windows")] { mod windows; pub(crate) use windows::enable; - } else if #[cfg(all(target_os = "wasi"))] { - mod wasi; - pub(crate) use wasi::enable; } else if #[cfg(any( - target_family = "wasm", + all(target_family = "wasm", not(target_os="wasi")), target_os = "uefi", target_os = "zkvm", ))] { @@ -138,6 +135,7 @@ pub(crate) mod key { target_family = "unix", ), target_os = "teeos", + target_os = "wasi", ))] { mod racy; mod unix; From e4092bd9091a68fcc6ddce0a0a72290003c4d560 Mon Sep 17 00:00:00 2001 From: Sebastian Urban Date: Thu, 5 Dec 2024 12:18:14 +0100 Subject: [PATCH 3/4] Fix compilation for wasm32-wasip1 (without threads). --- library/std/src/sys/thread_local/mod.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs index 82e1aeabf5ba1..f0a13323ec93f 100644 --- a/library/std/src/sys/thread_local/mod.rs +++ b/library/std/src/sys/thread_local/mod.rs @@ -86,7 +86,9 @@ pub(crate) mod guard { mod windows; pub(crate) use windows::enable; } else if #[cfg(any( - all(target_family = "wasm", not(target_os="wasi")), + all(target_family = "wasm", not( + all(target_os = "wasi", target_env = "p1", target_feature = "atomics") + )), target_os = "uefi", target_os = "zkvm", ))] { @@ -135,7 +137,7 @@ pub(crate) mod key { target_family = "unix", ), target_os = "teeos", - target_os = "wasi", + all(target_os = "wasi", target_env = "p1", target_feature = "atomics"), ))] { mod racy; mod unix; From 4f16640bbf88df43ac34b4c772589931d7d567d2 Mon Sep 17 00:00:00 2001 From: Sebastian Urban Date: Thu, 5 Dec 2024 12:24:19 +0100 Subject: [PATCH 4/4] Add libc funcitons only for wasm32-wasip1-threads. --- library/std/src/sys/thread_local/key/unix.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/thread_local/key/unix.rs b/library/std/src/sys/thread_local/key/unix.rs index 6661e378dbf44..b4b58b3470631 100644 --- a/library/std/src/sys/thread_local/key/unix.rs +++ b/library/std/src/sys/thread_local/key/unix.rs @@ -1,7 +1,7 @@ use crate::mem; // For WASI add a few symbols not in upstream `libc` just yet. -#[cfg(target_os = "wasi")] +#[cfg(all(target_os = "wasi", target_env = "p1", target_feature = "atomics"))] mod libc { use crate::ffi;