Make pthread types opaque, and check against libc.
This commit is contained in:
@@ -7,75 +7,105 @@ use crate::header::sched::sched_param;
|
||||
use crate::sync::AtomicLock;
|
||||
use core::sync::atomic::{AtomicU32 as AtomicUint, AtomicI32 as AtomicInt};
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct pthread_attr_t {
|
||||
pub detachstate: c_uchar,
|
||||
pub inheritsched: c_uchar,
|
||||
pub schedpolicy: c_uchar,
|
||||
pub scope: c_uchar,
|
||||
pub guardsize: size_t,
|
||||
pub stacksize: size_t,
|
||||
pub stack: size_t,
|
||||
pub param: sched_param,
|
||||
}
|
||||
// XXX: https://github.com/eqrion/cbindgen/issues/685
|
||||
//
|
||||
// We need to write the opaque types ourselves, and apparently cbindgen doesn't even support
|
||||
// expanding macros! Instead, we rely on checking that the lengths are correct, when these headers
|
||||
// are parsed in the regular compilation phase.
|
||||
|
||||
#[repr(C)]
|
||||
pub struct pthread_rwlockattr_t {
|
||||
pub pshared: c_int,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct pthread_rwlock_t {
|
||||
pub state: AtomicInt,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct pthread_barrier_t {
|
||||
pub count: AtomicUint,
|
||||
pub original_count: c_uint,
|
||||
pub epoch: AtomicInt,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct pthread_barrierattr_t {
|
||||
pub pshared: c_int,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct pthread_mutex_t {
|
||||
pub inner: AtomicInt,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct pthread_mutexattr_t {
|
||||
pub prioceiling: c_int,
|
||||
pub protocol: c_int,
|
||||
pub pshared: c_int,
|
||||
pub robust: c_int,
|
||||
pub ty: c_int,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct pthread_condattr_t {
|
||||
pub clock: clockid_t,
|
||||
pub pshared: c_int,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct pthread_cond_t {
|
||||
pub cur: AtomicInt,
|
||||
pub prev: AtomicInt,
|
||||
pub union pthread_attr_t {
|
||||
__relibc_internal_size: [c_uchar; 32],
|
||||
__relibc_internal_align: c_long,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct pthread_spinlock_t {
|
||||
pub inner: AtomicInt,
|
||||
pub union pthread_rwlockattr_t {
|
||||
__relibc_internal_size: [c_uchar; 4],
|
||||
__relibc_internal_align: c_int,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct pthread_once_t {
|
||||
pub inner: AtomicInt,
|
||||
pub union pthread_rwlock_t {
|
||||
__relibc_internal_size: [c_uchar; 4],
|
||||
__relibc_internal_align: c_int,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub union pthread_barrier_t {
|
||||
__relibc_internal_size: [c_uchar; 12],
|
||||
__relibc_internal_align: c_int,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub union pthread_barrierattr_t {
|
||||
__relibc_internal_size: [c_uchar; 4],
|
||||
__relibc_internal_align: c_int,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub union pthread_mutex_t {
|
||||
__relibc_internal_size: [c_uchar; 4],
|
||||
__relibc_internal_align: c_int,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub union pthread_mutexattr_t {
|
||||
__relibc_internal_size: [c_uchar; 20],
|
||||
__relibc_internal_align: c_int,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub union pthread_cond_t {
|
||||
__relibc_internal_size: [c_uchar; 8],
|
||||
__relibc_internal_align: c_int,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub union pthread_condattr_t {
|
||||
__relibc_internal_size: [c_uchar; 8],
|
||||
__relibc_internal_align: c_int,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub union pthread_spinlock_t {
|
||||
__relibc_internal_size: [c_uchar; 4],
|
||||
__relibc_internal_align: c_int,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub union pthread_once_t {
|
||||
__relibc_internal_size: [c_uchar; 4],
|
||||
__relibc_internal_align: c_int,
|
||||
}
|
||||
|
||||
pub type pthread_t = *mut ();
|
||||
macro_rules! assert_equal_size(
|
||||
($export:ident, $wrapped:ident) => {
|
||||
const _: () = unsafe {
|
||||
type Wrapped = crate::header::pthread::$wrapped;
|
||||
|
||||
// Fail at compile-time if sizes differ.
|
||||
|
||||
// TODO: Is this UB?
|
||||
let export = $export { __relibc_internal_align: 0 };
|
||||
let _: Wrapped = core::mem::transmute(export.__relibc_internal_size);
|
||||
|
||||
// Fail at compile-time if alignments differ.
|
||||
let a = [0_u8; core::mem::align_of::<$export>()];
|
||||
let b: [u8; core::mem::align_of::<Wrapped>()] = core::mem::transmute(a);
|
||||
};
|
||||
#[cfg(feature = "check_against_libc_crate")]
|
||||
const _: () = unsafe {
|
||||
let export = $export { __relibc_internal_align: 0 };
|
||||
let _: libc::$export = core::mem::transmute(export.__relibc_internal_size);
|
||||
|
||||
let a = [0_u8; core::mem::align_of::<$export>()];
|
||||
let b: [u8; core::mem::align_of::<libc::$export>()] = core::mem::transmute(a);
|
||||
|
||||
};
|
||||
}
|
||||
);
|
||||
assert_equal_size!(pthread_attr_t, RlctAttr);
|
||||
assert_equal_size!(pthread_rwlock_t, RlctRwlock);
|
||||
assert_equal_size!(pthread_rwlock_t, RlctRwlockAttr);
|
||||
assert_equal_size!(pthread_barrier_t, RlctBarrier);
|
||||
assert_equal_size!(pthread_barrierattr_t, RlctBarrierAttr);
|
||||
assert_equal_size!(pthread_mutex_t, RlctMutex);
|
||||
assert_equal_size!(pthread_mutexattr_t, RlctMutexAttr);
|
||||
assert_equal_size!(pthread_cond_t, RlctCond);
|
||||
assert_equal_size!(pthread_condattr_t, RlctCondAttr);
|
||||
assert_equal_size!(pthread_spinlock_t, RlctSpinlock);
|
||||
assert_equal_size!(pthread_once_t, RlctOnce);
|
||||
|
||||
pub type pthread_t = *mut c_void;
|
||||
pub type pthread_key_t = c_ulong;
|
||||
|
||||
Reference in New Issue
Block a user