From 64ca36dafbe6efb680a2ed3335f0c4531e473faa Mon Sep 17 00:00:00 2001 From: peamaeq Date: Tue, 3 May 2022 21:28:32 +0800 Subject: [PATCH 1/3] 0503 --- core/src/thread_parker/windows/keyed_event.rs | 18 +++++----- core/src/thread_parker/windows/waitaddress.rs | 12 +++---- src/condvar.rs | 36 ++++++++----------- src/once.rs | 12 +++---- 4 files changed, 34 insertions(+), 44 deletions(-) diff --git a/core/src/thread_parker/windows/keyed_event.rs b/core/src/thread_parker/windows/keyed_event.rs index bbe45a4c..fa8f3fc9 100644 --- a/core/src/thread_parker/windows/keyed_event.rs +++ b/core/src/thread_parker/windows/keyed_event.rs @@ -55,25 +55,24 @@ impl KeyedEvent { #[allow(non_snake_case)] pub fn create() -> Option { - unsafe { - let ntdll = GetModuleHandleA(b"ntdll.dll\0".as_ptr()); + let ntdll = unsafe { GetModuleHandleA(b"ntdll.dll\0".as_ptr()) }; if ntdll == 0 { return None; } let NtCreateKeyedEvent = - GetProcAddress(ntdll, b"NtCreateKeyedEvent\0".as_ptr())?; + unsafe { GetProcAddress(ntdll, b"NtCreateKeyedEvent\0".as_ptr())? }; let NtReleaseKeyedEvent = - GetProcAddress(ntdll, b"NtReleaseKeyedEvent\0".as_ptr())?; + unsafe { GetProcAddress(ntdll, b"NtReleaseKeyedEvent\0".as_ptr())? }; let NtWaitForKeyedEvent = - GetProcAddress(ntdll, b"NtWaitForKeyedEvent\0".as_ptr())?; + unsafe { GetProcAddress(ntdll, b"NtWaitForKeyedEvent\0".as_ptr())?}; let NtCreateKeyedEvent: extern "system" fn( KeyedEventHandle: *mut HANDLE, DesiredAccess: u32, ObjectAttributes: *mut ffi::c_void, Flags: u32, - ) -> NTSTATUS = mem::transmute(NtCreateKeyedEvent); + ) -> NTSTATUS = unsafe { mem::transmute(NtCreateKeyedEvent) }; let mut handle = MaybeUninit::uninit(); let status = NtCreateKeyedEvent( handle.as_mut_ptr(), @@ -86,11 +85,10 @@ impl KeyedEvent { } Some(KeyedEvent { - handle: handle.assume_init(), - NtReleaseKeyedEvent: mem::transmute(NtReleaseKeyedEvent), - NtWaitForKeyedEvent: mem::transmute(NtWaitForKeyedEvent), + handle: unsafe { handle.assume_init() }, + NtReleaseKeyedEvent: unsafe { mem::transmute(NtReleaseKeyedEvent) }, + NtWaitForKeyedEvent: unsafe { mem::transmute(NtWaitForKeyedEvent) }, }) - } } #[inline] diff --git a/core/src/thread_parker/windows/waitaddress.rs b/core/src/thread_parker/windows/waitaddress.rs index dde0db7b..2d4a544b 100644 --- a/core/src/thread_parker/windows/waitaddress.rs +++ b/core/src/thread_parker/windows/waitaddress.rs @@ -32,24 +32,22 @@ pub struct WaitAddress { impl WaitAddress { #[allow(non_snake_case)] pub fn create() -> Option { - unsafe { // MSDN claims that that WaitOnAddress and WakeByAddressSingle are // located in kernel32.dll, but they are lying... let synch_dll = - GetModuleHandleA(b"api-ms-win-core-synch-l1-2-0.dll\0".as_ptr()); + unsafe { GetModuleHandleA(b"api-ms-win-core-synch-l1-2-0.dll\0".as_ptr()) }; if synch_dll == 0 { return None; } - let WaitOnAddress = GetProcAddress(synch_dll, b"WaitOnAddress\0".as_ptr())?; + let WaitOnAddress = unsafe { GetProcAddress(synch_dll, b"WaitOnAddress\0".as_ptr())? }; let WakeByAddressSingle = - GetProcAddress(synch_dll, b"WakeByAddressSingle\0".as_ptr())?; + unsafe { GetProcAddress(synch_dll, b"WakeByAddressSingle\0".as_ptr())? }; Some(WaitAddress { - WaitOnAddress: mem::transmute(WaitOnAddress), - WakeByAddressSingle: mem::transmute(WakeByAddressSingle), + WaitOnAddress: unsafe { mem::transmute(WaitOnAddress) }, + WakeByAddressSingle: unsafe { mem::transmute(WakeByAddressSingle) }, }) - } } #[inline] diff --git a/src/condvar.rs b/src/condvar.rs index 27fd4c82..70e5b2c6 100644 --- a/src/condvar.rs +++ b/src/condvar.rs @@ -136,11 +136,10 @@ impl Condvar { #[cold] fn notify_one_slow(&self, mutex: *mut RawMutex) -> bool { - unsafe { - // Unpark one thread and requeue the rest onto the mutex - let from = self as *const _ as usize; - let to = mutex as usize; - let validate = || { + // Unpark one thread and requeue the rest onto the mutex + let from = self as *const _ as usize; + let to = mutex as usize; + let validate = unsafe { || { // Make sure that our atomic state still points to the same // mutex. If not then it means that all threads on the current // mutex were woken up and a new waiting thread switched to a @@ -161,7 +160,7 @@ impl Condvar { } else { RequeueOp::UnparkOne } - }; + } }; let callback = |_op, result: UnparkResult| { // Clear our state if there are no more waiting threads if !result.have_more_threads { @@ -169,10 +168,9 @@ impl Condvar { } TOKEN_NORMAL }; - let res = parking_lot_core::unpark_requeue(from, to, validate, callback); + let res = unsafe { parking_lot_core::unpark_requeue(from, to, validate, callback) }; res.unparked_threads + res.requeued_threads != 0 - } } /// Wakes up all blocked threads on this condvar. @@ -197,11 +195,10 @@ impl Condvar { #[cold] fn notify_all_slow(&self, mutex: *mut RawMutex) -> usize { - unsafe { // Unpark one thread and requeue the rest onto the mutex let from = self as *const _ as usize; let to = mutex as usize; - let validate = || { + let validate = unsafe { || { // Make sure that our atomic state still points to the same // mutex. If not then it means that all threads on the current // mutex were woken up and a new waiting thread switched to a @@ -226,19 +223,18 @@ impl Condvar { } else { RequeueOp::UnparkOneRequeueRest } - }; + } }; let callback = |op, result: UnparkResult| { // If we requeued threads to the mutex, mark it as having // parked threads. The RequeueAll case is already handled above. if op == RequeueOp::UnparkOneRequeueRest && result.requeued_threads != 0 { - (*mutex).mark_parked(); + unsafe { (*mutex).mark_parked() }; } TOKEN_NORMAL }; - let res = parking_lot_core::unpark_requeue(from, to, validate, callback); + let res = unsafe { parking_lot_core::unpark_requeue(from, to, validate, callback) }; res.unparked_threads + res.requeued_threads - } } /// Blocks the current thread until this condition variable receives a @@ -297,7 +293,6 @@ impl Condvar { // This is a non-generic function to reduce the monomorphization cost of // using `wait_until`. fn wait_until_internal(&self, mutex: &RawMutex, timeout: Option) -> WaitTimeoutResult { - unsafe { let result; let mut bad_mutex = false; let mut requeued = false; @@ -317,10 +312,10 @@ impl Condvar { } true }; - let before_sleep = || { + let before_sleep = unsafe { || { // Unlock the mutex before sleeping... mutex.unlock(); - }; + } }; let timed_out = |k, was_last_thread| { // If we were requeued to a mutex, then we did not time out. // We'll just park ourselves on the mutex again when we try @@ -334,14 +329,14 @@ impl Condvar { self.state.store(ptr::null_mut(), Ordering::Relaxed); } }; - result = parking_lot_core::park( + result = unsafe { parking_lot_core::park( addr, validate, before_sleep, timed_out, DEFAULT_PARK_TOKEN, timeout, - ); + ) }; } // Panic if we tried to use multiple mutexes with a Condvar. Note @@ -353,13 +348,12 @@ impl Condvar { // ... and re-lock it once we are done sleeping if result == ParkResult::Unparked(TOKEN_HANDOFF) { - deadlock::acquire_resource(mutex as *const _ as usize); + unsafe { deadlock::acquire_resource(mutex as *const _ as usize) }; } else { mutex.lock(); } WaitTimeoutResult(!(result.is_unparked() || requeued)) - } } /// Waits on this condition variable for a notification, timing out after a diff --git a/src/once.rs b/src/once.rs index f458c9c0..6b91ac4a 100644 --- a/src/once.rs +++ b/src/once.rs @@ -258,11 +258,11 @@ impl Once { // Park our thread until we are woken up by the thread that owns the // lock. + let addr = self as *const _ as usize; + let validate = || self.0.load(Ordering::Relaxed) == LOCKED_BIT | PARKED_BIT; + let before_sleep = || {}; + let timed_out = |_, _| unreachable!(); unsafe { - let addr = self as *const _ as usize; - let validate = || self.0.load(Ordering::Relaxed) == LOCKED_BIT | PARKED_BIT; - let before_sleep = || {}; - let timed_out = |_, _| unreachable!(); parking_lot_core::park( addr, validate, @@ -285,8 +285,8 @@ impl Once { let once = self.0; let state = once.0.swap(POISON_BIT, Ordering::Release); if state & PARKED_BIT != 0 { + let addr = once as *const _ as usize; unsafe { - let addr = once as *const _ as usize; parking_lot_core::unpark_all(addr, DEFAULT_UNPARK_TOKEN); } } @@ -307,8 +307,8 @@ impl Once { // Now unlock the state, set the done bit and unpark all threads let state = self.0.swap(DONE_BIT, Ordering::Release); if state & PARKED_BIT != 0 { + let addr = self as *const _ as usize; unsafe { - let addr = self as *const _ as usize; parking_lot_core::unpark_all(addr, DEFAULT_UNPARK_TOKEN); } } From 94ced119dacb9802687035f32c3a6f6eac88731d Mon Sep 17 00:00:00 2001 From: peamaeq Date: Mon, 9 May 2022 09:40:01 +0800 Subject: [PATCH 2/3] 0503 --- src/condvar.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/condvar.rs b/src/condvar.rs index 70e5b2c6..4b275a56 100644 --- a/src/condvar.rs +++ b/src/condvar.rs @@ -139,7 +139,7 @@ impl Condvar { // Unpark one thread and requeue the rest onto the mutex let from = self as *const _ as usize; let to = mutex as usize; - let validate = unsafe { || { + let validate = || { // Make sure that our atomic state still points to the same // mutex. If not then it means that all threads on the current // mutex were woken up and a new waiting thread switched to a @@ -155,12 +155,12 @@ impl Condvar { // locking the queue. There is the possibility of a race if the // mutex gets locked after we check, but that doesn't matter in // this case. - if (*mutex).mark_parked_if_locked() { + if unsafe { (*mutex).mark_parked_if_locked() } { RequeueOp::RequeueOne } else { RequeueOp::UnparkOne } - } }; + }; let callback = |_op, result: UnparkResult| { // Clear our state if there are no more waiting threads if !result.have_more_threads { @@ -198,7 +198,7 @@ impl Condvar { // Unpark one thread and requeue the rest onto the mutex let from = self as *const _ as usize; let to = mutex as usize; - let validate = unsafe { || { + let validate = || { // Make sure that our atomic state still points to the same // mutex. If not then it means that all threads on the current // mutex were woken up and a new waiting thread switched to a @@ -218,12 +218,12 @@ impl Condvar { // locking the queue. There is the possibility of a race if the // mutex gets locked after we check, but that doesn't matter in // this case. - if (*mutex).mark_parked_if_locked() { + if unsafe { (*mutex).mark_parked_if_locked() } { RequeueOp::RequeueAll } else { RequeueOp::UnparkOneRequeueRest } - } }; + }; let callback = |op, result: UnparkResult| { // If we requeued threads to the mutex, mark it as having // parked threads. The RequeueAll case is already handled above. From ff078dfd8040f8aa4f70e955142522a78ffef23d Mon Sep 17 00:00:00 2001 From: peamaeq Date: Mon, 9 May 2022 10:12:12 +0800 Subject: [PATCH 3/3] 0503 --- src/condvar.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/condvar.rs b/src/condvar.rs index 4b275a56..46a5d448 100644 --- a/src/condvar.rs +++ b/src/condvar.rs @@ -312,10 +312,10 @@ impl Condvar { } true }; - let before_sleep = unsafe { || { + let before_sleep = || { // Unlock the mutex before sleeping... - mutex.unlock(); - } }; + unsafe { mutex.unlock() }; + }; let timed_out = |k, was_last_thread| { // If we were requeued to a mutex, then we did not time out. // We'll just park ourselves on the mutex again when we try