std: rename Parker::new to Parker::new_in_place, add safe Parker::new constructor for SGX

This commit is contained in:
joboet 2022-12-30 15:49:47 +01:00
parent 3076f4ec30
commit 9abda03da6
No known key found for this signature in database
GPG key ID: 704E0149B0194B3C
9 changed files with 16 additions and 24 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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() })
} }

View file

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