Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup cloudabi mutexes and condvars #77657

Merged
merged 5 commits into from
Oct 16, 2020
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 13 additions & 22 deletions library/std/src/sys/cloudabi/condvar.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::cell::UnsafeCell;
use crate::mem;
use crate::sync::atomic::{AtomicU32, Ordering};
use crate::sys::cloudabi::abi;
@@ -12,37 +11,32 @@ extern "C" {
}

pub struct Condvar {
condvar: UnsafeCell<AtomicU32>,
condvar: AtomicU32,
}

pub type MovableCondvar = Condvar;

unsafe impl Send for Condvar {}
unsafe impl Sync for Condvar {}

const NEW: Condvar =
Condvar { condvar: UnsafeCell::new(AtomicU32::new(abi::CONDVAR_HAS_NO_WAITERS.0)) };

impl Condvar {
pub const fn new() -> Condvar {
NEW
Condvar { condvar: AtomicU32::new(abi::CONDVAR_HAS_NO_WAITERS.0) }
}

pub unsafe fn init(&mut self) {}

pub unsafe fn notify_one(&self) {
let condvar = self.condvar.get();
if (*condvar).load(Ordering::Relaxed) != abi::CONDVAR_HAS_NO_WAITERS.0 {
let ret = abi::condvar_signal(condvar as *mut abi::condvar, abi::scope::PRIVATE, 1);
if self.condvar.load(Ordering::Relaxed) != abi::CONDVAR_HAS_NO_WAITERS.0 {
let ret = abi::condvar_signal(&self.condvar as *const AtomicU32 as *mut abi::condvar, abi::scope::PRIVATE, 1);
assert_eq!(ret, abi::errno::SUCCESS, "Failed to signal on condition variable");
}
}

pub unsafe fn notify_all(&self) {
let condvar = self.condvar.get();
if (*condvar).load(Ordering::Relaxed) != abi::CONDVAR_HAS_NO_WAITERS.0 {
if self.condvar.load(Ordering::Relaxed) != abi::CONDVAR_HAS_NO_WAITERS.0 {
let ret = abi::condvar_signal(
condvar as *mut abi::condvar,
&self.condvar as *const AtomicU32 as *mut abi::condvar,
abi::scope::PRIVATE,
abi::nthreads::MAX,
);
@@ -53,20 +47,19 @@ impl Condvar {
pub unsafe fn wait(&self, mutex: &Mutex) {
let mutex = mutex::raw(mutex);
assert_eq!(
(*mutex).load(Ordering::Relaxed) & !abi::LOCK_KERNEL_MANAGED.0,
mutex.load(Ordering::Relaxed) & !abi::LOCK_KERNEL_MANAGED.0,
__pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
"This lock is not write-locked by this thread"
);

// Call into the kernel to wait on the condition variable.
let condvar = self.condvar.get();
let subscription = abi::subscription {
type_: abi::eventtype::CONDVAR,
union: abi::subscription_union {
condvar: abi::subscription_condvar {
condvar: condvar as *mut abi::condvar,
condvar: &self.condvar as *const AtomicU32 as *mut abi::condvar,
condvar_scope: abi::scope::PRIVATE,
lock: mutex as *mut abi::lock,
lock: mutex as *const AtomicU32 as *mut abi::lock,
lock_scope: abi::scope::PRIVATE,
},
},
@@ -86,23 +79,22 @@ impl Condvar {
pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
let mutex = mutex::raw(mutex);
assert_eq!(
(*mutex).load(Ordering::Relaxed) & !abi::LOCK_KERNEL_MANAGED.0,
mutex.load(Ordering::Relaxed) & !abi::LOCK_KERNEL_MANAGED.0,
__pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
"This lock is not write-locked by this thread"
);

// Call into the kernel to wait on the condition variable.
let condvar = self.condvar.get();
let timeout =
checked_dur2intervals(&dur).expect("overflow converting duration to nanoseconds");
let subscriptions = [
abi::subscription {
type_: abi::eventtype::CONDVAR,
union: abi::subscription_union {
condvar: abi::subscription_condvar {
condvar: condvar as *mut abi::condvar,
condvar: &self.condvar as *const AtomicU32 as *mut abi::condvar,
condvar_scope: abi::scope::PRIVATE,
lock: mutex as *mut abi::lock,
lock: mutex as *const AtomicU32 as *mut abi::lock,
lock_scope: abi::scope::PRIVATE,
},
},
@@ -144,9 +136,8 @@ impl Condvar {
}

pub unsafe fn destroy(&self) {
let condvar = self.condvar.get();
assert_eq!(
(*condvar).load(Ordering::Relaxed),
self.condvar.load(Ordering::Relaxed),
abi::CONDVAR_HAS_NO_WAITERS.0,
"Attempted to destroy a condition variable with blocked threads"
);
2 changes: 1 addition & 1 deletion library/std/src/sys/cloudabi/mutex.rs
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@ pub struct Mutex(RWLock);

pub type MovableMutex = Mutex;

pub unsafe fn raw(m: &Mutex) -> *mut AtomicU32 {
pub unsafe fn raw(m: &Mutex) -> &AtomicU32 {
rwlock::raw(&m.0)
}

4 changes: 2 additions & 2 deletions library/std/src/sys/cloudabi/rwlock.rs
Original file line number Diff line number Diff line change
@@ -15,8 +15,8 @@ pub struct RWLock {
lock: AtomicU32,
}

pub unsafe fn raw(r: &RWLock) -> *mut AtomicU32 {
&r.lock as *const AtomicU32 as *mut AtomicU32
pub unsafe fn raw(r: &RWLock) -> &AtomicU32 {
&r.lock
}

unsafe impl Send for RWLock {}