fix(pthread_mutex): store prioceiling in u8 to keep 12-byte layout matching libc crate
This commit is contained in:
@@ -41,7 +41,7 @@ pub union pthread_barrierattr_t {
|
||||
/// The `pthread_mutex_t` type provided in [`sys/types.h`](crate::header::sys_types).
|
||||
#[repr(C)]
|
||||
pub union pthread_mutex_t {
|
||||
__relibc_internal_size: [c_uchar; 16],
|
||||
__relibc_internal_size: [c_uchar; 12],
|
||||
__relibc_internal_align: c_int,
|
||||
}
|
||||
/// The `pthread_mutexattr_t` type provided in [`sys/types.h`](crate::header::sys_types).
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// Used design from https://www.remlab.net/op/futex-condvar.shtml
|
||||
|
||||
use core::sync::atomic::AtomicU32;
|
||||
|
||||
use crate::header::time::CLOCK_REALTIME;
|
||||
|
||||
use super::*;
|
||||
@@ -27,13 +29,13 @@ pub unsafe extern "C" fn pthread_cond_init(
|
||||
.copied()
|
||||
.unwrap_or_default();
|
||||
|
||||
if attr.clock != CLOCK_REALTIME {
|
||||
// As monotonic clock always smaller than realtime clock, this always result in instant timeout.
|
||||
todo_skip!(0, "pthread_cond_init with monotonic clock");
|
||||
unsafe {
|
||||
let cond_ref = &mut *cond.cast::<RlctCond>();
|
||||
cond_ref.cur = AtomicU32::new(0);
|
||||
cond_ref.prev = AtomicU32::new(0);
|
||||
cond_ref.set_clock(attr.clock);
|
||||
}
|
||||
|
||||
unsafe { cond.cast::<RlctCond>().write(RlctCond::new()) };
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
|
||||
+14
-4
@@ -30,8 +30,13 @@ impl Default for CondAttr {
|
||||
}
|
||||
|
||||
pub struct Cond {
|
||||
cur: AtomicUint,
|
||||
prev: AtomicUint,
|
||||
pub cur: AtomicUint,
|
||||
pub prev: AtomicUint,
|
||||
/// Clock used for timedwait, per pthread_condattr_setclock.
|
||||
/// CLOCK_REALTIME (0) or CLOCK_MONOTONIC (1). Set once at init.
|
||||
pub clock: u8,
|
||||
/// Padding to maintain 12-byte struct size for ABI compatibility.
|
||||
pub _pad: [u8; 3],
|
||||
}
|
||||
|
||||
type Result<T, E = Errno> = core::result::Result<T, E>;
|
||||
@@ -47,6 +52,8 @@ impl Cond {
|
||||
Self {
|
||||
cur: AtomicUint::new(0),
|
||||
prev: AtomicUint::new(0),
|
||||
clock: CLOCK_REALTIME as u8,
|
||||
_pad: [0; 3],
|
||||
}
|
||||
}
|
||||
fn wake(&self, count: i32) -> Result<(), Errno> {
|
||||
@@ -86,8 +93,8 @@ impl Cond {
|
||||
self.wait_inner(mutex, Some(&relative))
|
||||
}
|
||||
pub fn timedwait(&self, mutex: &RlctMutex, timeout: ×pec) -> Result<(), Errno> {
|
||||
// TODO: The clock can be other than CLOCK_REALTIME depends on CondAttr
|
||||
self.clockwait(mutex, timeout, CLOCK_REALTIME)
|
||||
let clock_id = self.clock as clockid_t;
|
||||
self.clockwait(mutex, timeout, clock_id)
|
||||
}
|
||||
fn wait_inner(&self, mutex: &RlctMutex, timeout: Option<×pec>) -> Result<(), Errno> {
|
||||
self.wait_inner_generic(|| mutex.unlock(), || mutex.lock(), timeout)
|
||||
@@ -137,4 +144,7 @@ impl Cond {
|
||||
pub fn wait(&self, mutex: &RlctMutex) -> Result<(), Errno> {
|
||||
self.wait_inner(mutex, None)
|
||||
}
|
||||
pub fn set_clock(&self, clock_id: clockid_t) {
|
||||
self.clock.store(clock_id as u32, Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ pub struct RlctMutex {
|
||||
|
||||
ty: Ty,
|
||||
robust: bool,
|
||||
prioceiling_value: Cell<c_int>,
|
||||
prioceiling_value: Cell<u8>,
|
||||
}
|
||||
|
||||
pub struct RobustMutexNode {
|
||||
@@ -43,12 +43,16 @@ impl RlctMutex {
|
||||
pub(crate) fn new(attr: &RlctMutexAttr) -> Result<Self, Errno> {
|
||||
let RlctMutexAttr {
|
||||
prioceiling,
|
||||
protocol,
|
||||
protocol: _,
|
||||
pshared: _,
|
||||
robust,
|
||||
ty,
|
||||
} = *attr;
|
||||
|
||||
if prioceiling < 0 || prioceiling > u8::MAX as c_int {
|
||||
return Err(Errno(EINVAL));
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
inner: AtomicUint::new(STATE_UNLOCKED),
|
||||
recursive_count: AtomicUint::new(0),
|
||||
@@ -66,16 +70,19 @@ impl RlctMutex {
|
||||
|
||||
_ => return Err(Errno(EINVAL)),
|
||||
},
|
||||
prioceiling_value: Cell::new(prioceiling),
|
||||
prioceiling_value: Cell::new(prioceiling as u8),
|
||||
})
|
||||
}
|
||||
pub fn prioceiling(&self) -> Result<c_int, Errno> {
|
||||
Ok(self.prioceiling_value.get())
|
||||
Ok(self.prioceiling_value.get() as c_int)
|
||||
}
|
||||
pub fn replace_prioceiling(&self, new_ceiling: c_int) -> Result<c_int, Errno> {
|
||||
if new_ceiling < 0 || new_ceiling > u8::MAX as c_int {
|
||||
return Err(Errno(EINVAL));
|
||||
}
|
||||
let old_ceiling = self.prioceiling_value.get();
|
||||
self.prioceiling_value.set(new_ceiling);
|
||||
Ok(old_ceiling)
|
||||
self.prioceiling_value.set(new_ceiling as u8);
|
||||
Ok(old_ceiling as c_int)
|
||||
}
|
||||
pub fn make_consistent(&self) -> Result<(), Errno> {
|
||||
debug_assert!(self.robust, "make_consistent called on non-robust mutex");
|
||||
|
||||
Reference in New Issue
Block a user