Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use futex.rs for Windows thread parking #127807

Merged
merged 1 commit into from
Jul 17, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions library/std/src/sys/pal/hermit/futex.rs
Original file line number Diff line number Diff line change
@@ -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.
//
5 changes: 5 additions & 0 deletions library/std/src/sys/pal/unix/futex.rs
Original file line number Diff line number Diff line change
@@ -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.
5 changes: 5 additions & 0 deletions library/std/src/sys/pal/wasm/atomics/futex.rs
Original file line number Diff line number Diff line change
@@ -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.
5 changes: 5 additions & 0 deletions library/std/src/sys/pal/windows/futex.rs
Original file line number Diff line number Diff line change
@@ -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;
}
21 changes: 5 additions & 16 deletions library/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,
17 changes: 10 additions & 7 deletions library/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:
@@ -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,
7 changes: 4 additions & 3 deletions library/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"),
@@ -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;
Loading