Skip to content

Commit

Permalink
Rollup merge of #96206 - m-ou-se:wasm-futex-locks, r=alexcrichton
Browse files Browse the repository at this point in the history
Use sys::unix::locks::futex* on wasm+atomics.

This removes the wasm-specific lock implementations and instead re-uses the implementations from sys::unix.

Tracking issue: #93740

cc ``@alexcrichton``
  • Loading branch information
Dylan-DPC authored Apr 20, 2022
2 parents 01d4731 + 8f2913c commit 41235ef
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 358 deletions.
102 changes: 0 additions & 102 deletions library/std/src/sys/wasm/atomics/condvar.rs

This file was deleted.

22 changes: 18 additions & 4 deletions library/std/src/sys/wasm/atomics/futex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,33 @@ use crate::convert::TryInto;
use crate::sync::atomic::AtomicU32;
use crate::time::Duration;

pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) {
/// Wait for a futex_wake operation to wake us.
///
/// Returns directly if the futex doesn't hold the expected value.
///
/// Returns false on timeout, and true in all other cases.
pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -> bool {
let timeout = timeout.and_then(|t| t.as_nanos().try_into().ok()).unwrap_or(-1);
unsafe {
wasm32::memory_atomic_wait32(
futex as *const AtomicU32 as *mut i32,
expected as i32,
timeout,
);
) < 2
}
}

pub fn futex_wake(futex: &AtomicU32) {
/// Wake up one thread that's blocked on futex_wait on this futex.
///
/// Returns true if this actually woke up such a thread,
/// or false if no thread was waiting on this futex.
pub fn futex_wake(futex: &AtomicU32) -> bool {
unsafe { wasm32::memory_atomic_notify(futex as *const AtomicU32 as *mut i32, 1) > 0 }
}

/// Wake up all threads that are waiting on futex_wait on this futex.
pub fn futex_wake_all(futex: &AtomicU32) {
unsafe {
wasm32::memory_atomic_notify(futex as *const AtomicU32 as *mut i32, 1);
wasm32::memory_atomic_notify(futex as *const AtomicU32 as *mut i32, i32::MAX as u32);
}
}
64 changes: 0 additions & 64 deletions library/std/src/sys/wasm/atomics/mutex.rs

This file was deleted.

145 changes: 0 additions & 145 deletions library/std/src/sys/wasm/atomics/rwlock.rs

This file was deleted.

34 changes: 0 additions & 34 deletions library/std/src/sys/wasm/atomics/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,37 +53,3 @@ pub mod guard {
None
}
}

// We currently just use our own thread-local to store our
// current thread's ID, and then we lazily initialize it to something allocated
// from a global counter.
pub fn my_id() -> u32 {
use crate::sync::atomic::{AtomicU32, Ordering::SeqCst};

static NEXT_ID: AtomicU32 = AtomicU32::new(0);

#[thread_local]
static mut MY_ID: u32 = 0;

unsafe {
// If our thread ID isn't set yet then we need to allocate one. Do so
// with with a simple "atomically add to a global counter" strategy.
// This strategy doesn't handled what happens when the counter
// overflows, however, so just abort everything once the counter
// overflows and eventually we could have some sort of recycling scheme
// (or maybe this is all totally irrelevant by that point!). In any case
// though we're using a CAS loop instead of a `fetch_add` to ensure that
// the global counter never overflows.
if MY_ID == 0 {
let mut cur = NEXT_ID.load(SeqCst);
MY_ID = loop {
let next = cur.checked_add(1).unwrap_or_else(|| crate::process::abort());
match NEXT_ID.compare_exchange(cur, next, SeqCst, SeqCst) {
Ok(_) => break next,
Err(i) => cur = i,
}
};
}
MY_ID
}
}
Loading

0 comments on commit 41235ef

Please sign in to comment.