Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit e9ec022

Browse files
authored
Rollup merge of rust-lang#97647 - m-ou-se:lazy-box-locks, r=Amanieu
Lazily allocate and initialize pthread locks. Lazily allocate and initialize pthread locks. This allows {Mutex, Condvar, RwLock}::new() to be const, while still using the platform's native locks for features like priority inheritance and debug tooling. E.g. on macOS, we cannot directly use the (private) APIs that pthread's locks are implemented with, making it impossible for us to use anything other than pthread while still preserving priority inheritance, etc. This PR doesn't yet make the public APIs const. That's for a separate PR with an FCP. Tracking issue: rust-lang#93740
2 parents 07f586f + 6a417d4 commit e9ec022

File tree

29 files changed

+184
-123
lines changed

29 files changed

+184
-123
lines changed

library/std/src/sys/hermit/condvar.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,13 @@ impl Condvar {
7070
mutex.lock();
7171
res == 0
7272
}
73+
}
7374

74-
pub unsafe fn destroy(&self) {
75-
let _ = abi::sem_destroy(self.sem1);
76-
let _ = abi::sem_destroy(self.sem2);
75+
impl Drop for Condvar {
76+
fn drop(&mut self) {
77+
unsafe {
78+
let _ = abi::sem_destroy(self.sem1);
79+
let _ = abi::sem_destroy(self.sem2);
80+
}
7781
}
7882
}

library/std/src/sys/hermit/mutex.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,4 @@ impl Mutex {
215215
}
216216
guard.locked
217217
}
218-
219-
#[inline]
220-
pub unsafe fn destroy(&self) {}
221218
}

library/std/src/sys/hermit/rwlock.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,6 @@ impl RwLock {
8484
// FIXME: should only wake up one of these some of the time
8585
self.cond.notify_all();
8686
}
87-
88-
#[inline]
89-
pub unsafe fn destroy(&self) {
90-
self.lock.destroy();
91-
self.cond.destroy();
92-
}
9387
}
9488

9589
impl State {

library/std/src/sys/itron/condvar.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,6 @@ impl Condvar {
117117
unsafe { mutex.lock() };
118118
success
119119
}
120-
121-
pub unsafe fn destroy(&self) {}
122120
}
123121

124122
mod waiter_queue {

library/std/src/sys/itron/mutex.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,10 @@ impl Mutex {
6464
}
6565
}
6666
}
67+
}
6768

68-
pub unsafe fn destroy(&self) {
69+
impl Drop for Mutex {
70+
fn drop(&mut self) {
6971
if let Some(mtx) = self.mtx.get().map(|x| x.0) {
7072
expect_success_aborting(unsafe { abi::del_mtx(mtx) }, &"del_mtx");
7173
}

library/std/src/sys/sgx/condvar.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::sys::locks::Mutex;
2+
use crate::sys_common::lazy_box::{LazyBox, LazyInit};
23
use crate::time::Duration;
34

45
use super::waitqueue::{SpinMutex, WaitQueue, WaitVariable};
@@ -7,16 +8,19 @@ pub struct Condvar {
78
inner: SpinMutex<WaitVariable<()>>,
89
}
910

10-
pub type MovableCondvar = Box<Condvar>;
11+
pub(crate) type MovableCondvar = LazyBox<Condvar>;
12+
13+
impl LazyInit for Condvar {
14+
fn init() -> Box<Self> {
15+
Box::new(Self::new())
16+
}
17+
}
1118

1219
impl Condvar {
1320
pub const fn new() -> Condvar {
1421
Condvar { inner: SpinMutex::new(WaitVariable::new(())) }
1522
}
1623

17-
#[inline]
18-
pub unsafe fn init(&mut self) {}
19-
2024
#[inline]
2125
pub unsafe fn notify_one(&self) {
2226
let _ = WaitQueue::notify_one(self.inner.lock());
@@ -38,7 +42,4 @@ impl Condvar {
3842
unsafe { mutex.lock() };
3943
success
4044
}
41-
42-
#[inline]
43-
pub unsafe fn destroy(&self) {}
4445
}

library/std/src/sys/sgx/mutex.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
use super::waitqueue::{try_lock_or_false, SpinMutex, WaitQueue, WaitVariable};
2+
use crate::sys_common::lazy_box::{LazyBox, LazyInit};
23

34
pub struct Mutex {
45
inner: SpinMutex<WaitVariable<bool>>,
56
}
67

78
// not movable: see UnsafeList implementation
8-
pub type MovableMutex = Box<Mutex>;
9+
pub(crate) type MovableMutex = LazyBox<Mutex>;
10+
11+
impl LazyInit for Mutex {
12+
fn init() -> Box<Self> {
13+
Box::new(Self::new())
14+
}
15+
}
916

1017
// Implementation according to “Operating Systems: Three Easy Pieces”, chapter 28
1118
impl Mutex {
@@ -52,7 +59,4 @@ impl Mutex {
5259
true
5360
}
5461
}
55-
56-
#[inline]
57-
pub unsafe fn destroy(&self) {}
5862
}

library/std/src/sys/sgx/rwlock.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
mod tests;
33

44
use crate::num::NonZeroUsize;
5+
use crate::sys_common::lazy_box::{LazyBox, LazyInit};
56

67
use super::waitqueue::{
78
try_lock_or_false, NotifiedTcs, SpinMutex, SpinMutexGuard, WaitQueue, WaitVariable,
@@ -13,7 +14,13 @@ pub struct RwLock {
1314
writer: SpinMutex<WaitVariable<bool>>,
1415
}
1516

16-
pub type MovableRwLock = Box<RwLock>;
17+
pub(crate) type MovableRwLock = LazyBox<RwLock>;
18+
19+
impl LazyInit for RwLock {
20+
fn init() -> Box<Self> {
21+
Box::new(Self::new())
22+
}
23+
}
1724

1825
// Check at compile time that RwLock size matches C definition (see test_c_rwlock_initializer below)
1926
//
@@ -168,9 +175,6 @@ impl RwLock {
168175
unsafe { self.__read_unlock(rguard, wguard) };
169176
}
170177
}
171-
172-
#[inline]
173-
pub unsafe fn destroy(&self) {}
174178
}
175179

176180
// The following functions are needed by libunwind. These symbols are named

library/std/src/sys/solid/rwlock.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,11 @@ impl RwLock {
8282
let rwl = self.raw();
8383
expect_success_aborting(unsafe { abi::rwl_unl_rwl(rwl) }, &"rwl_unl_rwl");
8484
}
85+
}
8586

87+
impl Drop for RwLock {
8688
#[inline]
87-
pub unsafe fn destroy(&self) {
89+
fn drop(&mut self) {
8890
if let Some(rwl) = self.rwl.get().map(|x| x.0) {
8991
expect_success_aborting(unsafe { abi::rwl_del_rwl(rwl) }, &"rwl_del_rwl");
9092
}

library/std/src/sys/unix/locks/futex.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@ impl Mutex {
2424
#[inline]
2525
pub unsafe fn init(&mut self) {}
2626

27-
#[inline]
28-
pub unsafe fn destroy(&self) {}
29-
3027
#[inline]
3128
pub unsafe fn try_lock(&self) -> bool {
3229
self.futex.compare_exchange(0, 1, Acquire, Relaxed).is_ok()
@@ -118,12 +115,6 @@ impl Condvar {
118115
Self { futex: AtomicU32::new(0) }
119116
}
120117

121-
#[inline]
122-
pub unsafe fn init(&mut self) {}
123-
124-
#[inline]
125-
pub unsafe fn destroy(&self) {}
126-
127118
// All the memory orderings here are `Relaxed`,
128119
// because synchronization is done by unlocking and locking the mutex.
129120

0 commit comments

Comments
 (0)