Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 76b3461

Browse files
committedMar 9, 2024
std: use os_unfair_lock for Mutex on Apple platforms
1 parent 113f7e9 commit 76b3461

File tree

3 files changed

+56
-0
lines changed

3 files changed

+56
-0
lines changed
 

‎library/std/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@
351351
#![feature(str_internals)]
352352
#![feature(strict_provenance)]
353353
#![feature(strict_provenance_atomic_ptr)]
354+
#![feature(sync_unsafe_cell)]
354355
// tidy-alphabetical-end
355356
//
356357
// Library features (alloc):
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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+
}

‎library/std/src/sys/locks/mutex/mod.rs

+8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@ cfg_if::cfg_if! {
1111
))] {
1212
mod futex;
1313
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;
1422
} else if #[cfg(target_os = "fuchsia")] {
1523
mod fuchsia;
1624
pub use fuchsia::Mutex;

0 commit comments

Comments
 (0)
Failed to load comments.