Skip to content

Commit a317b94

Browse files
committed
Implement missing MacOS functions
1 parent b946916 commit a317b94

File tree

1 file changed

+40
-4
lines changed

1 file changed

+40
-4
lines changed

src/macos.rs

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use core::{
22
ffi::c_void,
3-
sync::atomic::{AtomicU32, Ordering::Relaxed},
3+
sync::atomic::{AtomicU32, AtomicPtr, AtomicU64, Ordering::Relaxed},
44
};
55

66
// On macOS, atomic wait/wake functionality is not available through
@@ -45,20 +45,36 @@ extern "C" {
4545
}
4646

4747
#[inline]
48-
pub fn wait(a: &AtomicU32, expected: u32) {
49-
let ptr: *const AtomicU32 = a;
48+
fn wait_inner<F>(ptr: *const c_void, should_wait: F) where F: FnOnce() -> bool {
5049
// The 'monitor' is just the notification counter associated
5150
// with the address of the atomic.
5251
let monitor = unsafe { __libcpp_atomic_monitor(ptr.cast()) };
5352
// Check again if we should still go to sleep.
54-
if a.load(Relaxed) != expected {
53+
if !should_wait() {
5554
return;
5655
}
5756
// Wait, but only if there's been no new notifications
5857
// since we acquired the monitor.
5958
unsafe { __libcpp_atomic_wait(ptr.cast(), monitor) };
6059
}
6160

61+
#[inline]
62+
pub fn wait(a: &AtomicU32, expected: u32) {
63+
let ptr: *const _ = a;
64+
wait_inner(ptr as _, || a.load(Relaxed) == expected);
65+
}
66+
67+
#[inline]
68+
pub fn wait_u64(a: &AtomicU64, expected: u64) {
69+
let ptr: *const _ = a;
70+
wait_inner(ptr as _, || a.load(Relaxed) == expected);
71+
}
72+
73+
#[inline]
74+
pub fn wait_ptr<T>(a: *const AtomicPtr<T>, expected: *mut T) {
75+
wait_inner(a as _, || unsafe { (*a).load(Relaxed) } == expected);
76+
}
77+
6278
#[inline]
6379
pub fn wake_one(ptr: *const AtomicU32) {
6480
unsafe { __cxx_atomic_notify_one(ptr.cast()) };
@@ -68,3 +84,23 @@ pub fn wake_one(ptr: *const AtomicU32) {
6884
pub fn wake_all(ptr: *const AtomicU32) {
6985
unsafe { __cxx_atomic_notify_all(ptr.cast()) };
7086
}
87+
88+
#[inline]
89+
pub fn wake_one_u64(ptr: *const AtomicU64) {
90+
unsafe { __cxx_atomic_notify_all(ptr.cast()) };
91+
}
92+
93+
#[inline]
94+
pub fn wake_one_ptr<T>(ptr: *const AtomicPtr<T>) {
95+
unsafe { __cxx_atomic_notify_all(ptr.cast()) };
96+
}
97+
98+
#[inline]
99+
pub fn wake_all_u64(ptr: *const AtomicU64) {
100+
unsafe { __cxx_atomic_notify_all(ptr.cast()) };
101+
}
102+
103+
#[inline]
104+
pub fn wake_all_ptr<T>(ptr: *const AtomicPtr<T>) {
105+
unsafe { __cxx_atomic_notify_all(ptr.cast()) };
106+
}

0 commit comments

Comments
 (0)