3 files changed +56
-0
lines changed Original file line number Diff line number Diff line change 351
351
#![ feature( str_internals) ]
352
352
#![ feature( strict_provenance) ]
353
353
#![ feature( strict_provenance_atomic_ptr) ]
354
+ #![ feature( sync_unsafe_cell) ]
354
355
// tidy-alphabetical-end
355
356
//
356
357
// Library features (alloc):
Original file line number Diff line number Diff line change
1
+ //! Mutex for Apple platforms.
2
+ //!
3
+ //! On Apple platforms, priority inheritance is the default for locks. To avoid
4
+ //! having to use pthread's mutex, which needs some tricks to work correctly, we
5
+ //! instead use `os_unfair_lock`, which is small, movable and supports priority-
6
+ //! inheritance and appeared with macOS 10.12, which is exactly our minimum
7
+ //! supported version.
8
+
9
+ use crate :: cell:: SyncUnsafeCell ;
10
+
11
+ // FIXME: move these definitions to libc
12
+
13
+ #[ allow( non_camel_case_types) ]
14
+ #[ repr( C ) ]
15
+ struct os_unfair_lock {
16
+ _opaque : u32 ,
17
+ }
18
+
19
+ const OS_UNFAIR_LOCK_INIT : os_unfair_lock = os_unfair_lock { _opaque : 0 } ;
20
+
21
+ extern "C" {
22
+ fn os_unfair_lock_lock ( lock : * mut os_unfair_lock ) ;
23
+ fn os_unfair_lock_trylock ( lock : * mut os_unfair_lock ) -> bool ;
24
+ fn os_unfair_lock_unlock ( lock : * mut os_unfair_lock ) ;
25
+ }
26
+
27
+ pub struct Mutex {
28
+ lock : SyncUnsafeCell < os_unfair_lock > ,
29
+ }
30
+
31
+ impl Mutex {
32
+ pub const fn new ( ) -> Mutex {
33
+ Mutex { lock : SyncUnsafeCell :: new ( OS_UNFAIR_LOCK_INIT ) }
34
+ }
35
+
36
+ pub fn lock ( & self ) {
37
+ unsafe { os_unfair_lock_lock ( self . lock . get ( ) ) }
38
+ }
39
+
40
+ pub fn try_lock ( & self ) -> bool {
41
+ unsafe { os_unfair_lock_trylock ( self . lock . get ( ) ) }
42
+ }
43
+
44
+ pub unsafe fn unlock ( & self ) {
45
+ unsafe { os_unfair_lock_unlock ( self . lock . get ( ) ) }
46
+ }
47
+ }
Original file line number Diff line number Diff line change @@ -11,6 +11,14 @@ cfg_if::cfg_if! {
11
11
) ) ] {
12
12
mod futex;
13
13
pub use futex:: Mutex ;
14
+ } else if #[ cfg( any(
15
+ target_os = "macos" ,
16
+ target_os = "ios" ,
17
+ target_os = "tvos" ,
18
+ target_os = "watchos" ,
19
+ ) ) ] {
20
+ mod apple;
21
+ pub use apple:: Mutex ;
14
22
} else if #[ cfg( target_os = "fuchsia" ) ] {
15
23
mod fuchsia;
16
24
pub use fuchsia:: Mutex ;
0 commit comments