Skip to content

Commit

Permalink
Use futex.rs for Windows thread parking
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisDenton committed Jul 16, 2024
1 parent a778c83 commit 1b631e5
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 26 deletions.
5 changes: 5 additions & 0 deletions std/src/sys/pal/hermit/futex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ use crate::ptr::null;
use crate::sync::atomic::AtomicU32;
use crate::time::Duration;

/// An atomic for use as a futex that is at least 8-bits but may be larger.
pub type SmallAtomic = AtomicU32;
/// Must be the underlying type of SmallAtomic
pub type SmallPrimitive = u32;

pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -> bool {
// Calculate the timeout as a relative timespec.
//
Expand Down
5 changes: 5 additions & 0 deletions std/src/sys/pal/unix/futex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
use crate::sync::atomic::AtomicU32;
use crate::time::Duration;

/// An atomic for use as a futex that is at least 8-bits but may be larger.
pub type SmallAtomic = AtomicU32;
/// Must be the underlying type of SmallAtomic
pub type SmallPrimitive = u32;

/// Wait for a futex_wake operation to wake us.
///
/// Returns directly if the futex doesn't hold the expected value.
Expand Down
5 changes: 5 additions & 0 deletions std/src/sys/pal/wasm/atomics/futex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ use core::arch::wasm64 as wasm;
use crate::sync::atomic::AtomicU32;
use crate::time::Duration;

/// An atomic for use as a futex that is at least 8-bits but may be larger.
pub type SmallAtomic = AtomicU32;
/// Must be the underlying type of SmallAtomic
pub type SmallPrimitive = u32;

/// Wait for a futex_wake operation to wake us.
///
/// Returns directly if the futex doesn't hold the expected value.
Expand Down
5 changes: 5 additions & 0 deletions std/src/sys/pal/windows/futex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ use core::sync::atomic::{
};
use core::time::Duration;

/// An atomic for use as a futex that is at least 8-bits but may be larger.
pub type SmallAtomic = AtomicU8;
/// Must be the underlying type of SmallAtomic
pub type SmallPrimitive = u8;

pub unsafe trait Waitable {
type Atomic;
}
Expand Down
21 changes: 5 additions & 16 deletions std/src/sys/sync/mutex/futex.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,8 @@
use crate::sync::atomic::{
self,
Ordering::{Acquire, Relaxed, Release},
};
use crate::sys::futex::{futex_wait, futex_wake};

cfg_if::cfg_if! {
if #[cfg(windows)] {
// On Windows we can have a smol futex
type Atomic = atomic::AtomicU8;
type State = u8;
} else {
type Atomic = atomic::AtomicU32;
type State = u32;
}
}
use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release};
use crate::sys::futex::{self, futex_wait, futex_wake};

type Atomic = futex::SmallAtomic;
type State = futex::SmallPrimitive;

pub struct Mutex {
futex: Atomic,
Expand Down
17 changes: 10 additions & 7 deletions std/src/sys/sync/thread_parking/futex.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
#![forbid(unsafe_op_in_unsafe_fn)]
use crate::pin::Pin;
use crate::sync::atomic::AtomicU32;
use crate::sync::atomic::Ordering::{Acquire, Release};
use crate::sys::futex::{futex_wait, futex_wake};
use crate::sys::futex::{self, futex_wait, futex_wake};
use crate::time::Duration;

const PARKED: u32 = u32::MAX;
const EMPTY: u32 = 0;
const NOTIFIED: u32 = 1;
type Atomic = futex::SmallAtomic;
type State = futex::SmallPrimitive;

const PARKED: State = State::MAX;
const EMPTY: State = 0;
const NOTIFIED: State = 1;

pub struct Parker {
state: AtomicU32,
state: Atomic,
}

// Notes about memory ordering:
Expand All @@ -36,7 +39,7 @@ impl Parker {
/// Construct the futex parker. The UNIX parker implementation
/// requires this to happen in-place.
pub unsafe fn new_in_place(parker: *mut Parker) {
parker.write(Self { state: AtomicU32::new(EMPTY) });
unsafe { parker.write(Self { state: Atomic::new(EMPTY) }) };
}

// Assumes this is only called by the thread that owns the Parker,
Expand Down
7 changes: 4 additions & 3 deletions std/src/sys/sync/thread_parking/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
cfg_if::cfg_if! {
if #[cfg(any(
all(target_os = "windows", not(target_vendor = "win7")),
target_os = "linux",
target_os = "android",
all(target_arch = "wasm32", target_feature = "atomics"),
Expand All @@ -18,9 +19,9 @@ cfg_if::cfg_if! {
))] {
mod id;
pub use id::Parker;
} else if #[cfg(target_os = "windows")] {
mod windows;
pub use windows::Parker;
} else if #[cfg(target_vendor = "win7")] {
mod windows7;
pub use windows7::Parker;
} else if #[cfg(all(target_vendor = "apple", not(miri)))] {
mod darwin;
pub use darwin::Parker;
Expand Down
File renamed without changes.

0 comments on commit 1b631e5

Please sign in to comment.