1
1
use core:: {
2
2
ffi:: c_void,
3
- sync:: atomic:: { AtomicU32 , Ordering :: Relaxed } ,
3
+ sync:: atomic:: { AtomicU32 , AtomicPtr , AtomicU64 , Ordering :: Relaxed } ,
4
4
} ;
5
5
6
6
// On macOS, atomic wait/wake functionality is not available through
@@ -45,20 +45,36 @@ extern "C" {
45
45
}
46
46
47
47
#[ 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 {
50
49
// The 'monitor' is just the notification counter associated
51
50
// with the address of the atomic.
52
51
let monitor = unsafe { __libcpp_atomic_monitor ( ptr. cast ( ) ) } ;
53
52
// Check again if we should still go to sleep.
54
- if a . load ( Relaxed ) != expected {
53
+ if ! should_wait ( ) {
55
54
return ;
56
55
}
57
56
// Wait, but only if there's been no new notifications
58
57
// since we acquired the monitor.
59
58
unsafe { __libcpp_atomic_wait ( ptr. cast ( ) , monitor) } ;
60
59
}
61
60
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
+
62
78
#[ inline]
63
79
pub fn wake_one ( ptr : * const AtomicU32 ) {
64
80
unsafe { __cxx_atomic_notify_one ( ptr. cast ( ) ) } ;
@@ -68,3 +84,23 @@ pub fn wake_one(ptr: *const AtomicU32) {
68
84
pub fn wake_all ( ptr : * const AtomicU32 ) {
69
85
unsafe { __cxx_atomic_notify_all ( ptr. cast ( ) ) } ;
70
86
}
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