Add needed functions for acid to link.
This commit is contained in:
+54
-18
@@ -1,5 +1,9 @@
|
||||
// Used design from https://www.remlab.net/op/futex-condvar.shtml
|
||||
|
||||
use super::*;
|
||||
|
||||
use core::sync::atomic::{AtomicI32 as AtomicInt, Ordering};
|
||||
|
||||
// PTHREAD_COND_INITIALIZER
|
||||
|
||||
#[repr(C)]
|
||||
@@ -10,36 +14,68 @@ pub struct CondAttr {
|
||||
|
||||
#[repr(C)]
|
||||
pub struct Cond {
|
||||
cur: AtomicInt,
|
||||
prev: AtomicInt,
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
pub extern "C" fn pthread_cond_broadcast(cond: *mut pthread_cond_t) -> c_int {
|
||||
todo!()
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn pthread_cond_broadcast(cond: *mut pthread_cond_t) -> c_int {
|
||||
wake(cond, i32::MAX)
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
pub extern "C" fn pthread_cond_destroy(cond: *mut pthread_cond_t) -> c_int {
|
||||
todo!()
|
||||
unsafe fn wake(cond: *mut pthread_cond_t, n: i32) -> c_int {
|
||||
let cond: &pthread_cond_t = &*cond;
|
||||
|
||||
// This is formally correct as long as we don't have more than u32::MAX threads.
|
||||
let prev = cond.prev.load(Ordering::SeqCst);
|
||||
cond.cur.store(prev.wrapping_add(1), Ordering::SeqCst);
|
||||
|
||||
crate::sync::futex_wake(&cond.cur, n);
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
pub extern "C" fn pthread_cond_init(cond: *mut pthread_cond_t, attr: *const pthread_condattr_t) -> c_int {
|
||||
todo!()
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn pthread_cond_destroy(cond: *mut pthread_cond_t) -> c_int {
|
||||
let _cond: &pthread_cond_t = &*cond;
|
||||
0
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
pub extern "C" fn pthread_cond_signal(cond: *mut pthread_cond_t) -> c_int {
|
||||
todo!()
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn pthread_cond_init(cond: *mut pthread_cond_t, _attr: *const pthread_condattr_t) -> c_int {
|
||||
cond.write(Cond {
|
||||
cur: AtomicInt::new(0),
|
||||
prev: AtomicInt::new(0),
|
||||
});
|
||||
0
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
pub extern "C" fn pthread_cond_timedwait(cond: *mut pthread_cond_t, mutex: *const pthread_mutex_t, timeout: *const timespec) -> c_int {
|
||||
todo!()
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn pthread_cond_signal(cond: *mut pthread_cond_t) -> c_int {
|
||||
wake(cond, 1)
|
||||
}
|
||||
|
||||
// #[no_mangle]
|
||||
pub extern "C" fn pthread_cond_wait(cond: *mut pthread_cond_t, mutex: *const pthread_mutex_t) -> c_int {
|
||||
todo!()
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn pthread_cond_timedwait(cond: *mut pthread_cond_t, mutex_ptr: *const pthread_mutex_t, timeout: *const timespec) -> c_int {
|
||||
// TODO: Error checking for certain types (i.e. robust and errorcheck) of mutexes, e.g. if the
|
||||
// mutex is not locked.
|
||||
let cond: &pthread_cond_t = &*cond;
|
||||
let mutex: &pthread_mutex_t = &*mutex_ptr;
|
||||
let timeout: Option<×pec> = timeout.as_ref();
|
||||
|
||||
let current = cond.cur.load(Ordering::Relaxed);
|
||||
cond.prev.store(current, Ordering::SeqCst);
|
||||
|
||||
mutex.inner.manual_unlock();
|
||||
crate::sync::futex_wait(&cond.cur, current, timeout);
|
||||
mutex.inner.manual_lock();
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn pthread_cond_wait(cond: *mut pthread_cond_t, mutex: *const pthread_mutex_t) -> c_int {
|
||||
pthread_cond_timedwait(cond, mutex, core::ptr::null())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
||||
Reference in New Issue
Block a user