Use futex.rs for Windows thread parking
This commit is contained in:
parent
2823cfb1e5
commit
51bdcf66d3
@ -3,6 +3,11 @@ use crate::ptr::null;
|
|||||||
use crate::sync::atomic::AtomicU32;
|
use crate::sync::atomic::AtomicU32;
|
||||||
use crate::time::Duration;
|
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 {
|
pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -> bool {
|
||||||
// Calculate the timeout as a relative timespec.
|
// Calculate the timeout as a relative timespec.
|
||||||
//
|
//
|
||||||
|
@ -11,6 +11,11 @@
|
|||||||
use crate::sync::atomic::AtomicU32;
|
use crate::sync::atomic::AtomicU32;
|
||||||
use crate::time::Duration;
|
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.
|
/// Wait for a futex_wake operation to wake us.
|
||||||
///
|
///
|
||||||
/// Returns directly if the futex doesn't hold the expected value.
|
/// Returns directly if the futex doesn't hold the expected value.
|
||||||
|
@ -6,6 +6,11 @@ use core::arch::wasm64 as wasm;
|
|||||||
use crate::sync::atomic::AtomicU32;
|
use crate::sync::atomic::AtomicU32;
|
||||||
use crate::time::Duration;
|
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.
|
/// Wait for a futex_wake operation to wake us.
|
||||||
///
|
///
|
||||||
/// Returns directly if the futex doesn't hold the expected value.
|
/// Returns directly if the futex doesn't hold the expected value.
|
||||||
|
@ -10,6 +10,11 @@ use core::sync::atomic::{
|
|||||||
};
|
};
|
||||||
use core::time::Duration;
|
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 {
|
pub unsafe trait Waitable {
|
||||||
type Atomic;
|
type Atomic;
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,8 @@
|
|||||||
use crate::sync::atomic::{
|
use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release};
|
||||||
self,
|
use crate::sys::futex::{self, futex_wait, futex_wake};
|
||||||
Ordering::{Acquire, Relaxed, Release},
|
|
||||||
};
|
|
||||||
use crate::sys::futex::{futex_wait, futex_wake};
|
|
||||||
|
|
||||||
cfg_if::cfg_if! {
|
type Atomic = futex::SmallAtomic;
|
||||||
if #[cfg(windows)] {
|
type State = futex::SmallPrimitive;
|
||||||
// On Windows we can have a smol futex
|
|
||||||
type Atomic = atomic::AtomicU8;
|
|
||||||
type State = u8;
|
|
||||||
} else {
|
|
||||||
type Atomic = atomic::AtomicU32;
|
|
||||||
type State = u32;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Mutex {
|
pub struct Mutex {
|
||||||
futex: Atomic,
|
futex: Atomic,
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
|
#![forbid(unsafe_op_in_unsafe_fn)]
|
||||||
use crate::pin::Pin;
|
use crate::pin::Pin;
|
||||||
use crate::sync::atomic::AtomicU32;
|
|
||||||
use crate::sync::atomic::Ordering::{Acquire, Release};
|
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;
|
use crate::time::Duration;
|
||||||
|
|
||||||
const PARKED: u32 = u32::MAX;
|
type Atomic = futex::SmallAtomic;
|
||||||
const EMPTY: u32 = 0;
|
type State = futex::SmallPrimitive;
|
||||||
const NOTIFIED: u32 = 1;
|
|
||||||
|
const PARKED: State = State::MAX;
|
||||||
|
const EMPTY: State = 0;
|
||||||
|
const NOTIFIED: State = 1;
|
||||||
|
|
||||||
pub struct Parker {
|
pub struct Parker {
|
||||||
state: AtomicU32,
|
state: Atomic,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notes about memory ordering:
|
// Notes about memory ordering:
|
||||||
@ -36,7 +39,7 @@ impl Parker {
|
|||||||
/// Construct the futex parker. The UNIX parker implementation
|
/// Construct the futex parker. The UNIX parker implementation
|
||||||
/// requires this to happen in-place.
|
/// requires this to happen in-place.
|
||||||
pub unsafe fn new_in_place(parker: *mut Parker) {
|
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,
|
// Assumes this is only called by the thread that owns the Parker,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(any(
|
if #[cfg(any(
|
||||||
|
all(target_os = "windows", not(target_vendor = "win7")),
|
||||||
target_os = "linux",
|
target_os = "linux",
|
||||||
target_os = "android",
|
target_os = "android",
|
||||||
all(target_arch = "wasm32", target_feature = "atomics"),
|
all(target_arch = "wasm32", target_feature = "atomics"),
|
||||||
@ -18,9 +19,9 @@ cfg_if::cfg_if! {
|
|||||||
))] {
|
))] {
|
||||||
mod id;
|
mod id;
|
||||||
pub use id::Parker;
|
pub use id::Parker;
|
||||||
} else if #[cfg(target_os = "windows")] {
|
} else if #[cfg(target_vendor = "win7")] {
|
||||||
mod windows;
|
mod windows7;
|
||||||
pub use windows::Parker;
|
pub use windows7::Parker;
|
||||||
} else if #[cfg(all(target_vendor = "apple", not(miri)))] {
|
} else if #[cfg(all(target_vendor = "apple", not(miri)))] {
|
||||||
mod darwin;
|
mod darwin;
|
||||||
pub use darwin::Parker;
|
pub use darwin::Parker;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user