// FIXME(andypython): remove this when #![allow(warnings, unused_variables)] is // dropped from src/lib.rs. #![warn(warnings, unused_variables)] use super::*; pub use crate::sync::pthread_mutex::RlctMutex; use crate::{error::Errno, header::time::timespec_realtime_to_monotonic}; // PTHREAD_MUTEX_INITIALIZER is defined in bits_pthread/cbindgen.toml #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_mutex_consistent(mutex: *mut pthread_mutex_t) -> c_int { e((unsafe { &*mutex.cast::() }).make_consistent()) } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_mutex_destroy(mutex: *mut pthread_mutex_t) -> c_int { // No-op unsafe { core::ptr::drop_in_place(mutex.cast::()) }; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_mutex_getprioceiling( mutex: *const pthread_mutex_t, prioceiling: *mut c_int, ) -> c_int { match (unsafe { &*mutex.cast::() }).prioceiling() { Ok(value) => { unsafe { prioceiling.write(value) }; 0 } Err(Errno(errno)) => errno, } } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_mutex_init( mutex: *mut pthread_mutex_t, attr: *const pthread_mutexattr_t, ) -> c_int { let attr = unsafe { attr.cast::().as_ref() } .cloned() .unwrap_or_default(); match RlctMutex::new(&attr) { Ok(new) => { unsafe { mutex.cast::().write(new) }; 0 } Err(Errno(errno)) => errno, } } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_mutex_lock(mutex: *mut pthread_mutex_t) -> c_int { e((unsafe { &*mutex.cast::() }).lock()) } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_mutex_setprioceiling( mutex: *mut pthread_mutex_t, prioceiling: c_int, old_prioceiling: *mut c_int, ) -> c_int { match (unsafe { &*mutex.cast::() }).replace_prioceiling(prioceiling) { Ok(old) => { unsafe { old_prioceiling.write(old) }; 0 } Err(Errno(errno)) => errno, } } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_mutex_timedlock( mutex: *mut pthread_mutex_t, abstime: ×pec, ) -> c_int { let relative = match timespec_realtime_to_monotonic(abstime.clone()) { Ok(relative) => relative, Err(err) => return e(Err(err)), }; e((unsafe { &*mutex.cast::() }).lock_with_timeout(&relative)) } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_mutex_trylock(mutex: *mut pthread_mutex_t) -> c_int { e((unsafe { &*mutex.cast::() }).try_lock()) } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_mutex_unlock(mutex: *mut pthread_mutex_t) -> c_int { e((unsafe { &*mutex.cast::() }).unlock()) } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_mutexattr_destroy(attr: *mut pthread_mutexattr_t) -> c_int { // No-op unsafe { core::ptr::drop_in_place(attr.cast::()) }; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_mutexattr_getprioceiling( attr: *const pthread_mutexattr_t, prioceiling: &mut c_int, ) -> c_int { *prioceiling = unsafe { &*attr.cast::() }.prioceiling; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_mutexattr_getprotocol( attr: *const pthread_mutexattr_t, protocol: &mut c_int, ) -> c_int { *protocol = unsafe { &*attr.cast::() }.protocol; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_mutexattr_getpshared( attr: *const pthread_mutexattr_t, pshared: &mut c_int, ) -> c_int { *pshared = unsafe { &*attr.cast::() }.pshared; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_mutexattr_getrobust( attr: *const pthread_mutexattr_t, robust: &mut c_int, ) -> c_int { *robust = unsafe { &*attr.cast::() }.robust; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_mutexattr_gettype( attr: *const pthread_mutexattr_t, ty: &mut c_int, ) -> c_int { *ty = unsafe { &*attr.cast::() }.ty; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_mutexattr_init(attr: *mut pthread_mutexattr_t) -> c_int { unsafe { attr.cast::().write(RlctMutexAttr::default()) }; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_mutexattr_setprioceiling( attr: *mut pthread_mutexattr_t, prioceiling: c_int, ) -> c_int { unsafe { &mut *attr.cast::() }.prioceiling = prioceiling; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_mutexattr_setprotocol( attr: *mut pthread_mutexattr_t, protocol: c_int, ) -> c_int { unsafe { &mut *attr.cast::() }.protocol = protocol; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_mutexattr_setpshared( attr: *mut pthread_mutexattr_t, pshared: c_int, ) -> c_int { unsafe { &mut *attr.cast::() }.pshared = pshared; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_mutexattr_setrobust( attr: *mut pthread_mutexattr_t, robust: c_int, ) -> c_int { unsafe { &mut *attr.cast::() }.robust = robust; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_mutexattr_settype( attr: *mut pthread_mutexattr_t, ty: c_int, ) -> c_int { unsafe { &mut *attr.cast::() }.ty = ty; 0 } #[repr(C)] #[derive(Clone)] pub(crate) struct RlctMutexAttr { pub prioceiling: c_int, pub protocol: c_int, pub pshared: c_int, pub robust: c_int, pub ty: c_int, } impl Default for RlctMutexAttr { fn default() -> Self { Self { robust: PTHREAD_MUTEX_STALLED, pshared: PTHREAD_PROCESS_PRIVATE, protocol: PTHREAD_PRIO_NONE, // TODO prioceiling: 0, ty: PTHREAD_MUTEX_DEFAULT, } } }