Skip to content

Commit c1acccd

Browse files
committed
std: replace LazyBox with OnceBox
This PR replaces the `LazyBox` wrapper used to allocate the pthread primitives with `OnceBox`, which has a more familiar API mirroring that of `OnceLock`. This cleans up the code in preparation for larger changes like #128184 (from which this PR was split) and allows some neat optimizations, like avoid an acquire-load of the allocation pointer in `Mutex::unlock`, where the initialization of the allocation must have already been observed. Additionally, I've gotten rid of the TEEOS `Condvar` code, it's just a duplicate of the pthread one anyway and I didn't want to repeat myself.
1 parent 21aa500 commit c1acccd

12 files changed

Lines changed: 185 additions & 284 deletions

File tree

‎library/std/src/sys/sync/condvar/mod.rs‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ cfg_if::cfg_if! {
1212
))]{
1313
mod futex;
1414
pubuse futex::Condvar;
15-
} else if #[cfg(target_family = "unix")]{
15+
} else if #[cfg(any(
16+
target_family = "unix",
17+
target_os = "teeos",
18+
))]{
1619
mod pthread;
1720
pubuse pthread::Condvar;
1821
} else if #[cfg(all(target_os = "windows", target_vendor = "win7"))]{
@@ -24,9 +27,6 @@ cfg_if::cfg_if! {
2427
} else if #[cfg(target_os = "solid_asp3")]{
2528
mod itron;
2629
pubuse itron::Condvar;
27-
} else if #[cfg(target_os = "teeos")]{
28-
mod teeos;
29-
pubuse teeos::Condvar;
3030
} else if #[cfg(target_os = "xous")]{
3131
mod xous;
3232
pubuse xous::Condvar;

‎library/std/src/sys/sync/condvar/pthread.rs‎

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,25 @@ use crate::cell::UnsafeCell;
22
usecrate::ptr;
33
usecrate::sync::atomic::AtomicPtr;
44
usecrate::sync::atomic::Ordering::Relaxed;
5-
usecrate::sys::sync::{Mutex,mutex};
5+
usecrate::sys::sync::{Mutex,OnceBox};
66
#[cfg(not(target_os = "nto"))]
77
usecrate::sys::time::TIMESPEC_MAX;
88
#[cfg(target_os = "nto")]
99
usecrate::sys::time::TIMESPEC_MAX_CAPPED;
10-
usecrate::sys_common::lazy_box::{LazyBox,LazyInit};
1110
usecrate::time::Duration;
1211

1312
structAllocatedCondvar(UnsafeCell<libc::pthread_cond_t>);
1413

1514
pubstructCondvar{
16-
inner:LazyBox<AllocatedCondvar>,
15+
inner:OnceBox<AllocatedCondvar>,
1716
mutex:AtomicPtr<libc::pthread_mutex_t>,
1817
}
1918

20-
#[inline]
21-
fnraw(c:&Condvar) -> *mut libc::pthread_cond_t{
22-
c.inner.0.get()
23-
}
24-
2519
unsafeimplSendforAllocatedCondvar{}
2620
unsafeimplSyncforAllocatedCondvar{}
2721

28-
implLazyInitforAllocatedCondvar{
29-
fninit() -> Box<Self>{
22+
implAllocatedCondvar{
23+
fnnew() -> Box<Self>{
3024
let condvar = Box::new(AllocatedCondvar(UnsafeCell::new(libc::PTHREAD_COND_INITIALIZER)));
3125

3226
cfg_if::cfg_if! {
@@ -37,7 +31,7 @@ impl LazyInit for AllocatedCondvar {
3731
target_vendor = "apple",
3832
))]{
3933
// `pthread_condattr_setclock` is unfortunately not supported on these platforms.
40-
} else if #[cfg(any(target_os = "espidf", target_os = "horizon"))]{
34+
} else if #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "teeos"))]{
4135
// NOTE: ESP-IDF's PTHREAD_COND_INITIALIZER support is not released yet
4236
// So on that platform, init() should always be called
4337
// Moreover, that platform does not have pthread_condattr_setclock support,
@@ -82,7 +76,11 @@ impl Drop for AllocatedCondvar {
8276

8377
implCondvar{
8478
pubconstfnnew() -> Condvar{
85-
Condvar{inner:LazyBox::new(),mutex:AtomicPtr::new(ptr::null_mut())}
79+
Condvar{inner:OnceBox::new(),mutex:AtomicPtr::new(ptr::null_mut())}
80+
}
81+
82+
fnget(&self) -> *mut libc::pthread_cond_t{
83+
self.inner.get_or_init(AllocatedCondvar::new).0.get()
8684
}
8785

8886
#[inline]
@@ -98,21 +96,21 @@ impl Condvar {
9896

9997
#[inline]
10098
pubfnnotify_one(&self){
101-
let r = unsafe{ libc::pthread_cond_signal(raw(self))};
99+
let r = unsafe{ libc::pthread_cond_signal(self.get())};
102100
debug_assert_eq!(r,0);
103101
}
104102

105103
#[inline]
106104
pubfnnotify_all(&self){
107-
let r = unsafe{ libc::pthread_cond_broadcast(raw(self))};
105+
let r = unsafe{ libc::pthread_cond_broadcast(self.get())};
108106
debug_assert_eq!(r,0);
109107
}
110108

111109
#[inline]
112110
pubunsafefnwait(&self,mutex:&Mutex){
113-
let mutex = mutex::raw(mutex);
111+
let mutex = mutex.get_assert_locked();
114112
self.verify(mutex);
115-
let r = libc::pthread_cond_wait(raw(self), mutex);
113+
let r = libc::pthread_cond_wait(self.get(), mutex);
116114
debug_assert_eq!(r,0);
117115
}
118116

@@ -129,7 +127,7 @@ impl Condvar {
129127
pubunsafefnwait_timeout(&self,mutex:&Mutex,dur:Duration) -> bool{
130128
usecrate::sys::time::Timespec;
131129

132-
let mutex = mutex::raw(mutex);
130+
let mutex = mutex.get_assert_locked();
133131
self.verify(mutex);
134132

135133
#[cfg(not(target_os = "nto"))]
@@ -144,7 +142,7 @@ impl Condvar {
144142
.and_then(|t| t.to_timespec_capped())
145143
.unwrap_or(TIMESPEC_MAX_CAPPED);
146144

147-
let r = libc::pthread_cond_timedwait(raw(self), mutex,&timeout);
145+
let r = libc::pthread_cond_timedwait(self.get(), mutex,&timeout);
148146
assert!(r == libc::ETIMEDOUT || r == 0);
149147
r == 0
150148
}
@@ -162,7 +160,7 @@ impl Condvar {
162160
usecrate::sys::time::SystemTime;
163161
usecrate::time::Instant;
164162

165-
let mutex = mutex::raw(mutex);
163+
let mutex = mutex.get_assert_locked();
166164
self.verify(mutex);
167165

168166
// OSX implementation of `pthread_cond_timedwait` is buggy
@@ -188,7 +186,7 @@ impl Condvar {
188186
.and_then(|t| t.to_timespec())
189187
.unwrap_or(TIMESPEC_MAX);
190188

191-
let r = libc::pthread_cond_timedwait(raw(self), mutex,&timeout);
189+
let r = libc::pthread_cond_timedwait(self.get(), mutex,&timeout);
192190
debug_assert!(r == libc::ETIMEDOUT || r == 0);
193191

194192
// ETIMEDOUT is not a totally reliable method of determining timeout due

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

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,39 @@
11
usecrate::sys::pal::waitqueue::{SpinMutex,WaitQueue,WaitVariable};
2-
usecrate::sys::sync::Mutex;
3-
usecrate::sys_common::lazy_box::{LazyBox,LazyInit};
2+
usecrate::sys::sync::{Mutex,OnceBox};
43
usecrate::time::Duration;
54

6-
/// FIXME: `UnsafeList` is not movable.
7-
structAllocatedCondvar(SpinMutex<WaitVariable<()>>);
8-
95
pubstructCondvar{
10-
inner:LazyBox<AllocatedCondvar>,
11-
}
12-
13-
implLazyInitforAllocatedCondvar{
14-
fninit() -> Box<Self>{
15-
Box::new(AllocatedCondvar(SpinMutex::new(WaitVariable::new(()))))
16-
}
6+
// FIXME: `UnsafeList` is not movable.
7+
inner:OnceBox<SpinMutex<WaitVariable<()>>>,
178
}
189

1910
implCondvar{
2011
pubconstfnnew() -> Condvar{
21-
Condvar{inner:LazyBox::new()}
12+
Condvar{inner:OnceBox::new()}
13+
}
14+
15+
fnget(&self) -> &SpinMutex<WaitVariable<()>>{
16+
self.inner.get_or_init(|| Box::new(SpinMutex::new(WaitVariable::new(()))))
2217
}
2318

2419
#[inline]
2520
pubfnnotify_one(&self){
26-
let _ = WaitQueue::notify_one(self.inner.0.lock());
21+
let _ = WaitQueue::notify_one(self.get().lock());
2722
}
2823

2924
#[inline]
3025
pubfnnotify_all(&self){
31-
let _ = WaitQueue::notify_all(self.inner.0.lock());
26+
let _ = WaitQueue::notify_all(self.get().lock());
3227
}
3328

3429
pubunsafefnwait(&self,mutex:&Mutex){
35-
let guard = self.inner.0.lock();
30+
let guard = self.get().lock();
3631
WaitQueue::wait(guard, || unsafe{ mutex.unlock()});
3732
mutex.lock()
3833
}
3934

4035
pubunsafefnwait_timeout(&self,mutex:&Mutex,dur:Duration) -> bool{
41-
let success = WaitQueue::wait_timeout(&self.inner.0, dur, || unsafe{ mutex.unlock()});
36+
let success = WaitQueue::wait_timeout(self.get(), dur, || unsafe{ mutex.unlock()});
4237
mutex.lock();
4338
success
4439
}

‎library/std/src/sys/sync/condvar/teeos.rs‎

Lines changed: 0 additions & 101 deletions
This file was deleted.

‎library/std/src/sys/sync/mod.rs‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
mod condvar;
22
mod mutex;
33
mod once;
4+
mod once_box;
45
mod rwlock;
56
mod thread_parking;
67

78
pubuse condvar::Condvar;
89
pubuse mutex::Mutex;
910
pubuse once::{Once,OnceState};
11+
#[allow(unused)]// Only used on some platforms.
12+
use once_box::OnceBox;
1013
pubuse rwlock::RwLock;
1114
pubuse thread_parking::Parker;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ cfg_if::cfg_if! {
1919
target_os = "teeos",
2020
))]{
2121
mod pthread;
22-
pubuse pthread::{Mutex, raw};
22+
pubuse pthread::Mutex;
2323
} else if #[cfg(all(target_os = "windows", target_vendor = "win7"))]{
2424
mod windows7;
2525
pubuse windows7::{Mutex, raw};

0 commit comments

Comments
 (0)