diff options
| -rw-r--r-- | library/std/src/sys/unix/futex.rs | 43 | ||||
| -rw-r--r-- | library/std/src/sys/unix/thread.rs | 20 |
2 files changed, 43 insertions, 20 deletions
diff --git a/library/std/src/sys/unix/futex.rs b/library/std/src/sys/unix/futex.rs index e6f0c48c59b..7ec3794d0b0 100644 --- a/library/std/src/sys/unix/futex.rs +++ b/library/std/src/sys/unix/futex.rs @@ -1,10 +1,17 @@ -#![cfg(any(target_os = "linux", target_os = "android"))] +#![cfg(any( + target_os = "linux", + target_os = "android", + all(target_os = "emscripten", target_feature = "atomics") +))] +#[cfg(any(target_os = "linux", target_os = "android"))] use crate::convert::TryInto; +#[cfg(any(target_os = "linux", target_os = "android"))] use crate::ptr::null; use crate::sync::atomic::AtomicI32; use crate::time::Duration; +#[cfg(any(target_os = "linux", target_os = "android"))] pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) { let timespec = timeout.and_then(|d| { Some(libc::timespec { @@ -25,6 +32,29 @@ pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) { } } +#[cfg(target_os = "emscripten")] +pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) { + extern "C" { + fn emscripten_futex_wait( + addr: *const AtomicI32, + val: libc::c_uint, + max_wait_ms: libc::c_double, + ) -> libc::c_int; + } + + let timeout_ms = timeout.map(|d| d.as_millis()); + unsafe { + emscripten_futex_wait( + futex as *const AtomicI32, + // `val` is declared unsigned to match the Emscripten headers, but since it's used as + // an opaque value, we can ignore the meaning of signed vs. unsigned and cast here. + expected as libc::c_uint, + timeout_ms.map_or(crate::f64::INFINITY, |d| d as libc::c_double), + ); + } +} + +#[cfg(any(target_os = "linux", target_os = "android"))] pub fn futex_wake(futex: &AtomicI32) { unsafe { libc::syscall( @@ -35,3 +65,14 @@ pub fn futex_wake(futex: &AtomicI32) { ); } } + +#[cfg(target_os = "emscripten")] +pub fn futex_wake(futex: &AtomicI32) { + extern "C" { + fn emscripten_futex_wake(addr: *const AtomicI32, count: libc::c_int) -> libc::c_int; + } + + unsafe { + emscripten_futex_wake(futex as *const AtomicI32, 1); + } +} diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs index fdf114d6df6..b7b72cc392f 100644 --- a/library/std/src/sys/unix/thread.rs +++ b/library/std/src/sys/unix/thread.rs @@ -22,24 +22,6 @@ pub struct Thread { unsafe impl Send for Thread {} unsafe impl Sync for Thread {} -// The pthread_attr_setstacksize symbol doesn't exist in the emscripten libc, -// so we have to not link to it to satisfy emcc's ERROR_ON_UNDEFINED_SYMBOLS. -#[cfg(not(target_os = "emscripten"))] -unsafe fn pthread_attr_setstacksize( - attr: *mut libc::pthread_attr_t, - stack_size: libc::size_t, -) -> libc::c_int { - libc::pthread_attr_setstacksize(attr, stack_size) -} - -#[cfg(target_os = "emscripten")] -unsafe fn pthread_attr_setstacksize( - _attr: *mut libc::pthread_attr_t, - _stack_size: libc::size_t, -) -> libc::c_int { - panic!() -} - impl Thread { // unsafe: see thread::Builder::spawn_unchecked for safety requirements pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> { @@ -50,7 +32,7 @@ impl Thread { let stack_size = cmp::max(stack, min_stack_size(&attr)); - match pthread_attr_setstacksize(&mut attr, stack_size) { + match libc::pthread_attr_setstacksize(&mut attr, stack_size) { 0 => {} n => { assert_eq!(n, libc::EINVAL); |
