Use futex.rs for Windows thread parking

This commit is contained in:
Chris Denton 2024-07-16 10:08:26 +00:00
parent 2823cfb1e5
commit 51bdcf66d3
No known key found for this signature in database
GPG Key ID: 713472F2F45627DE
8 changed files with 38 additions and 25 deletions

View File

@ -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.
//

View File

@ -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.

View File

@ -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.

View File

@ -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;
}

View File

@ -1,19 +1,8 @@
use crate::sync::atomic::{
self,
Ordering::{Acquire, Relaxed, Release},
};
use crate::sys::futex::{futex_wait, futex_wake};
use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release};
use crate::sys::futex::{self, 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;
}
}
type Atomic = futex::SmallAtomic;
type State = futex::SmallPrimitive;
pub struct Mutex {
futex: Atomic,

View File

@ -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,

View File

@ -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;