std: rename Parker::new
to Parker::new_in_place
, add safe Parker::new
constructor for SGX
This commit is contained in:
parent
3076f4ec30
commit
9abda03da6
9 changed files with 16 additions and 24 deletions
|
@ -65,7 +65,6 @@ mod task_queue {
|
||||||
/// execution. The signal is sent once all TLS destructors have finished at
|
/// execution. The signal is sent once all TLS destructors have finished at
|
||||||
/// which point no new thread locals should be created.
|
/// which point no new thread locals should be created.
|
||||||
pub mod wait_notify {
|
pub mod wait_notify {
|
||||||
use crate::mem::MaybeUninit;
|
|
||||||
use crate::pin::Pin;
|
use crate::pin::Pin;
|
||||||
use crate::sync::Arc;
|
use crate::sync::Arc;
|
||||||
use crate::sys_common::thread_parking::Parker;
|
use crate::sys_common::thread_parking::Parker;
|
||||||
|
@ -88,25 +87,14 @@ pub mod wait_notify {
|
||||||
/// called, this will return immediately, otherwise the current thread
|
/// called, this will return immediately, otherwise the current thread
|
||||||
/// is blocked until notified.
|
/// is blocked until notified.
|
||||||
pub fn wait(self) {
|
pub fn wait(self) {
|
||||||
// This is not actually `unsafe`, but it uses the `Parker` API,
|
// SAFETY:
|
||||||
// which needs `unsafe` on some platforms.
|
// This is only ever called on one thread.
|
||||||
unsafe { Pin::new(&*self.0).park() }
|
unsafe { Pin::new(&*self.0).park() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new() -> (Notifier, Waiter) {
|
pub fn new() -> (Notifier, Waiter) {
|
||||||
// Safety:
|
let inner = Arc::new(Parker::new());
|
||||||
// Some other platforms (looking at you, UNIX!) require that the thread
|
|
||||||
// parker is constructed in-place. This is just a noisy way of writing:
|
|
||||||
// ```rust
|
|
||||||
// let parker = Parker::new();
|
|
||||||
// ```
|
|
||||||
let parker = unsafe {
|
|
||||||
let mut place = MaybeUninit::uninit();
|
|
||||||
Parker::new(place.as_mut_ptr());
|
|
||||||
place.assume_init()
|
|
||||||
};
|
|
||||||
let inner = Arc::new(parker);
|
|
||||||
(Notifier(inner.clone()), Waiter(inner))
|
(Notifier(inner.clone()), Waiter(inner))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ unsafe impl Sync for Parker {}
|
||||||
unsafe impl Send for Parker {}
|
unsafe impl Send for Parker {}
|
||||||
|
|
||||||
impl Parker {
|
impl Parker {
|
||||||
pub unsafe fn new(parker: *mut Parker) {
|
pub unsafe fn new_in_place(parker: *mut Parker) {
|
||||||
let semaphore = dispatch_semaphore_create(0);
|
let semaphore = dispatch_semaphore_create(0);
|
||||||
assert!(
|
assert!(
|
||||||
!semaphore.is_null(),
|
!semaphore.is_null(),
|
||||||
|
|
|
@ -99,7 +99,7 @@ impl Parker {
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// The constructed parker must never be moved.
|
/// The constructed parker must never be moved.
|
||||||
pub unsafe fn new(parker: *mut Parker) {
|
pub unsafe fn new_in_place(parker: *mut Parker) {
|
||||||
// Use the default mutex implementation to allow for simpler initialization.
|
// Use the default mutex implementation to allow for simpler initialization.
|
||||||
// This could lead to undefined behaviour when deadlocking. This is avoided
|
// This could lead to undefined behaviour when deadlocking. This is avoided
|
||||||
// by not deadlocking. Note in particular the unlocking operation before any
|
// by not deadlocking. Note in particular the unlocking operation before any
|
||||||
|
|
|
@ -97,7 +97,7 @@ const NOTIFIED: i8 = 1;
|
||||||
impl Parker {
|
impl Parker {
|
||||||
/// Construct the Windows parker. The UNIX parker implementation
|
/// Construct the Windows parker. The UNIX parker implementation
|
||||||
/// requires this to happen in-place.
|
/// requires this to happen in-place.
|
||||||
pub unsafe fn new(parker: *mut Parker) {
|
pub unsafe fn new_in_place(parker: *mut Parker) {
|
||||||
parker.write(Self { state: AtomicI8::new(EMPTY) });
|
parker.write(Self { state: AtomicI8::new(EMPTY) });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ pub struct Parker {
|
||||||
impl Parker {
|
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(parker: *mut Parker) {
|
pub unsafe fn new_in_place(parker: *mut Parker) {
|
||||||
parker.write(Self { state: AtomicU32::new(EMPTY) });
|
parker.write(Self { state: AtomicU32::new(EMPTY) });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ pub struct Parker {
|
||||||
impl Parker {
|
impl Parker {
|
||||||
/// Construct the generic parker. The UNIX parker implementation
|
/// Construct the generic parker. The UNIX parker implementation
|
||||||
/// requires this to happen in-place.
|
/// requires this to happen in-place.
|
||||||
pub unsafe fn new(parker: *mut Parker) {
|
pub unsafe fn new_in_place(parker: *mut Parker) {
|
||||||
parker.write(Parker {
|
parker.write(Parker {
|
||||||
state: AtomicUsize::new(EMPTY),
|
state: AtomicUsize::new(EMPTY),
|
||||||
lock: Mutex::new(()),
|
lock: Mutex::new(()),
|
||||||
|
|
|
@ -26,9 +26,13 @@ const EMPTY: i8 = 0;
|
||||||
const NOTIFIED: i8 = 1;
|
const NOTIFIED: i8 = 1;
|
||||||
|
|
||||||
impl Parker {
|
impl Parker {
|
||||||
|
pub fn new() -> Parker {
|
||||||
|
Parker { state: AtomicI8::new(EMPTY), tid: UnsafeCell::new(None) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a new thread parker. UNIX requires this to happen in-place.
|
/// Create a new thread parker. UNIX requires this to happen in-place.
|
||||||
pub unsafe fn new(parker: *mut Parker) {
|
pub unsafe fn new_in_place(parker: *mut Parker) {
|
||||||
parker.write(Parker { state: AtomicI8::new(EMPTY), tid: UnsafeCell::new(None) })
|
parker.write(Parker::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Safety
|
/// # Safety
|
||||||
|
|
|
@ -41,7 +41,7 @@ pub struct Parker {
|
||||||
impl Parker {
|
impl Parker {
|
||||||
/// Construct a parker for the current thread. The UNIX parker
|
/// Construct a parker for the current thread. The UNIX parker
|
||||||
/// implementation requires this to happen in-place.
|
/// implementation requires this to happen in-place.
|
||||||
pub unsafe fn new(parker: *mut Parker) {
|
pub unsafe fn new_in_place(parker: *mut Parker) {
|
||||||
parker.write(Parker { state: AtomicI8::new(EMPTY), wait_flag: WaitFlag::new() })
|
parker.write(Parker { state: AtomicI8::new(EMPTY), wait_flag: WaitFlag::new() })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1216,7 +1216,7 @@ impl Thread {
|
||||||
let ptr = Arc::get_mut_unchecked(&mut arc).as_mut_ptr();
|
let ptr = Arc::get_mut_unchecked(&mut arc).as_mut_ptr();
|
||||||
addr_of_mut!((*ptr).name).write(name);
|
addr_of_mut!((*ptr).name).write(name);
|
||||||
addr_of_mut!((*ptr).id).write(ThreadId::new());
|
addr_of_mut!((*ptr).id).write(ThreadId::new());
|
||||||
Parker::new(addr_of_mut!((*ptr).parker));
|
Parker::new_in_place(addr_of_mut!((*ptr).parker));
|
||||||
Pin::new_unchecked(arc.assume_init())
|
Pin::new_unchecked(arc.assume_init())
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue