Skip to content

Commit

Permalink
Rollup merge of rust-lang#127807 - ChrisDenton:win-parking, r=joboet
Browse files Browse the repository at this point in the history
Use futex.rs for Windows thread parking

If I'm not overlooking anything then the Windows 10+ thread parking implementation is practically the same as the futex.rs implementation. So we may as well use the same implementation for both. The old version is still kept around for Windows 7 support.

r? ````@joboet```` if you wouldn't mind double checking I've not missed something
  • Loading branch information
tgross35 authored Jul 17, 2024
2 parents 61af010 + 1b631e5 commit 0299bb5
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 0299bb5

Please sign in to comment.