Add needed functions for acid to link.

This commit is contained in:
4lDO2
2023-03-05 18:28:56 +01:00
parent 2593101ea7
commit 6a658bc33d
13 changed files with 268 additions and 175 deletions
+54 -18
View File
@@ -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<&timespec> = 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]
+10 -24
View File
@@ -9,9 +9,9 @@ use crate::pthread;
pub const PTHREAD_BARRIER_SERIAL_THREAD: c_int = 1;
pub const PTHREAD_CANCEL_ASYNCHRONOUS: c_int = 0;
pub const PTHREAD_CANCEL_ENABLE: c_int = 0;
pub const PTHREAD_CANCEL_DEFERRED: c_int = 0;
pub const PTHREAD_CANCEL_DISABLE: c_int = 0;
pub const PTHREAD_CANCEL_ENABLE: c_int = 1;
pub const PTHREAD_CANCEL_DEFERRED: c_int = 2;
pub const PTHREAD_CANCEL_DISABLE: c_int = 3;
pub const PTHREAD_CANCELED: *mut c_void = core::ptr::null_mut();
pub const PTHREAD_CREATE_DETACHED: c_int = 0;
@@ -21,11 +21,12 @@ pub const PTHREAD_EXPLICIT_SCHED: c_int = 0;
pub const PTHREAD_INHERIT_SCHED: c_int = 1;
pub const PTHREAD_MUTEX_DEFAULT: c_int = 0;
pub const PTHREAD_MUTEX_ERRORCHECK: c_int = 0;
pub const PTHREAD_MUTEX_NORMAL: c_int = 0;
pub const PTHREAD_MUTEX_RECURSIVE: c_int = 0;
pub const PTHREAD_MUTEX_ERRORCHECK: c_int = 1;
pub const PTHREAD_MUTEX_NORMAL: c_int = 2;
pub const PTHREAD_MUTEX_RECURSIVE: c_int = 3;
pub const PTHREAD_MUTEX_ROBUST: c_int = 0;
pub const PTHREAD_MUTEX_STALLED: c_int = 0;
pub const PTHREAD_MUTEX_STALLED: c_int = 1;
pub const PTHREAD_PRIO_INHERIT: c_int = 0;
@@ -102,10 +103,8 @@ pub extern "C" fn pthread_getschedparam(thread: pthread_t, policy: *mut clockid_
todo!()
}
// #[no_mangle]
pub extern "C" fn pthread_getspecific(key: pthread_key_t) -> *mut c_void {
todo!()
}
pub mod tls;
pub use tls::*;
#[no_mangle]
pub unsafe extern "C" fn pthread_join(thread: pthread_t, retval: *mut *mut c_void) -> c_int {
@@ -118,16 +117,6 @@ pub unsafe extern "C" fn pthread_join(thread: pthread_t, retval: *mut *mut c_voi
}
}
// #[no_mangle]
pub extern "C" fn pthread_key_create(key: *mut pthread_key_t, destructor: extern "C" fn(value: *mut c_void)) -> c_int {
todo!()
}
// #[no_mangle]
pub extern "C" fn pthread_key_delete(key: pthread_key_t) -> c_int {
todo!()
}
pub mod mutex;
pub use self::mutex::*;
@@ -157,9 +146,6 @@ pub extern "C" fn pthread_setschedparam(thread: pthread_t, policy: c_int, param:
pub extern "C" fn pthread_setschedprio(thread: pthread_t, prio: c_int) -> c_int {
todo!();
}
pub extern "C" fn pthread_setspecific(key: pthread_key_t, value: *const c_void) -> c_int {
todo!();
}
pub mod spin;
pub use self::spin::*;
+96 -38
View File
@@ -1,88 +1,146 @@
use super::*;
use crate::header::errno::EBUSY;
// PTHREAD_MUTEX_INITIALIZER
#[repr(C)]
pub struct Mutex {
pub(crate) inner: crate::sync::Mutex<()>,
}
#[repr(C)]
pub struct MutexAttr {
prioceiling: c_int,
protocol: c_int,
pshared: c_int,
robust: c_int,
ty: c_int,
}
// #[no_mangle]
pub extern "C" fn pthread_mutex_consistent(mutex: *mut pthread_mutex_t) -> c_int {
todo!();
}
pub extern "C" fn pthread_mutex_destroy(mutex: *mut pthread_mutex_t) -> c_int {
todo!();
#[no_mangle]
pub unsafe extern "C" fn pthread_mutex_destroy(mutex: *mut pthread_mutex_t) -> c_int {
let _mutex: &pthread_mutex_t = &*mutex;
0
}
// #[no_mangle]
pub extern "C" fn pthread_mutex_getprioceiling(mutex: *const pthread_mutex_t, prioceiling: *mut c_int) -> c_int {
todo!();
}
pub extern "C" fn pthread_mutex_init(mutex: *mut pthread_mutex_t, attr: *const pthread_mutexattr_t) -> c_int {
todo!();
#[no_mangle]
pub unsafe extern "C" fn pthread_mutex_init(mutex: *mut pthread_mutex_t, _attr: *const pthread_mutexattr_t) -> c_int {
// TODO: attr
mutex.write(Mutex {
inner: crate::sync::Mutex::new(()),
});
0
}
pub extern "C" fn pthread_mutex_lock(mutex: *mut pthread_mutex_t) -> c_int {
todo!();
#[no_mangle]
pub unsafe extern "C" fn pthread_mutex_lock(mutex: *mut pthread_mutex_t) -> c_int {
(&*mutex).inner.manual_lock();
0
}
// #[no_mangle]
pub extern "C" fn pthread_mutex_setprioceiling(mutex: *mut pthread_mutex_t, prioceiling: c_int, old_prioceiling: *mut c_int) -> c_int {
todo!();
}
// #[no_mangle]
pub extern "C" fn pthread_mutex_timedlock(mutex: *mut pthread_mutex_t, timespec: *const timespec) -> c_int {
todo!();
}
pub extern "C" fn pthread_mutex_trylock(mutex: *mut pthread_mutex_t) -> c_int {
todo!();
#[no_mangle]
pub unsafe extern "C" fn pthread_mutex_trylock(mutex: *mut pthread_mutex_t) -> c_int {
match (&*mutex).inner.manual_try_lock() {
Ok(_) => 0,
Err(_) => EBUSY,
}
}
pub extern "C" fn pthread_mutex_unlock(mutex: *mut pthread_mutex_t) -> c_int {
todo!();
}
pub extern "C" fn pthread_mutexattr_destroy(attr: *mut pthread_mutexattr_t) -> c_int {
todo!();
#[no_mangle]
pub unsafe extern "C" fn pthread_mutex_unlock(mutex: *mut pthread_mutex_t) -> c_int {
(&*mutex).inner.manual_unlock();
0
}
pub extern "C" fn pthread_mutexattr_getprioceiling(attr: *const pthread_mutexattr_t, prioceiling: *mut c_int) -> c_int {
todo!();
#[no_mangle]
pub extern "C" fn pthread_mutexattr_destroy(_attr: *mut pthread_mutexattr_t) -> c_int {
0
}
pub extern "C" fn pthread_mutexattr_getprotocol(attr: *const pthread_mutexattr_t, protocol: *mut c_int) -> c_int {
todo!();
#[no_mangle]
pub unsafe extern "C" fn pthread_mutexattr_getprioceiling(attr: *const pthread_mutexattr_t, prioceiling: *mut c_int) -> c_int {
prioceiling.write((*attr).prioceiling);
0
}
pub extern "C" fn pthread_mutexattr_getpshared(attr: *const pthread_mutexattr_t, pshared: *mut c_int) -> c_int {
todo!();
#[no_mangle]
pub unsafe extern "C" fn pthread_mutexattr_getprotocol(attr: *const pthread_mutexattr_t, protocol: *mut c_int) -> c_int {
protocol.write((*attr).protocol);
0
}
pub extern "C" fn pthread_mutexattr_getrobust(attr: *const pthread_mutexattr_t, robust: *mut c_int) -> c_int {
todo!();
}
pub extern "C" fn pthread_mutexattr_gettype(attr: *const pthread_mutexattr_t, ty: *mut c_int) -> c_int {
todo!();
}
pub extern "C" fn pthread_mutexattr_init(attr: *mut pthread_mutexattr_t) -> c_int {
todo!();
#[no_mangle]
pub unsafe extern "C" fn pthread_mutexattr_getpshared(attr: *const pthread_mutexattr_t, pshared: *mut c_int) -> c_int {
pshared.write((*attr).pshared);
0
}
pub extern "C" fn pthread_mutexattr_setprioceiling(attr: *mut pthread_mutexattr_t, prioceiling: c_int) -> c_int {
todo!();
#[no_mangle]
pub unsafe extern "C" fn pthread_mutexattr_getrobust(attr: *const pthread_mutexattr_t, robust: *mut c_int) -> c_int {
robust.write((*attr).robust);
0
}
#[no_mangle]
pub unsafe extern "C" fn pthread_mutexattr_gettype(attr: *const pthread_mutexattr_t, ty: *mut c_int) -> c_int {
ty.write((*attr).ty);
0
}
#[no_mangle]
pub unsafe extern "C" fn pthread_mutexattr_init(attr: *mut pthread_mutexattr_t) -> c_int {
attr.write(MutexAttr {
robust: PTHREAD_MUTEX_STALLED,
pshared: PTHREAD_PROCESS_PRIVATE,
protocol: PTHREAD_PRIO_NONE,
// TODO
prioceiling: 0,
ty: PTHREAD_MUTEX_DEFAULT,
});
0
}
pub extern "C" fn pthread_mutexattr_setprotocol(attr: *mut pthread_mutexattr_t, protocol: c_int) -> c_int {
todo!();
#[no_mangle]
pub unsafe extern "C" fn pthread_mutexattr_setprioceiling(attr: *mut pthread_mutexattr_t, prioceiling: c_int) -> c_int {
(*attr).prioceiling = prioceiling;
0
}
pub extern "C" fn pthread_mutexattr_setpshared(attr: *mut pthread_mutexattr_t, pshared: c_int) -> c_int {
todo!();
#[no_mangle]
pub unsafe extern "C" fn pthread_mutexattr_setprotocol(attr: *mut pthread_mutexattr_t, protocol: c_int) -> c_int {
(*attr).protocol = protocol;
0
}
pub extern "C" fn pthread_mutexattr_setrobust(attr: *mut pthread_mutexattr_t, robust: c_int) -> c_int {
todo!();
#[no_mangle]
pub unsafe extern "C" fn pthread_mutexattr_setpshared(attr: *mut pthread_mutexattr_t, pshared: c_int) -> c_int {
(*attr).pshared = pshared;
0
}
pub extern "C" fn pthread_mutexattr_settype(attr: *mut pthread_mutexattr_t, ty: c_int) -> c_int {
todo!();
#[no_mangle]
pub unsafe extern "C" fn pthread_mutexattr_setrobust(attr: *mut pthread_mutexattr_t, robust: c_int) -> c_int {
(*attr).robust = robust;
0
}
#[no_mangle]
pub unsafe extern "C" fn pthread_mutexattr_settype(attr: *mut pthread_mutexattr_t, ty: c_int) -> c_int {
(*attr).ty = ty;
0
}
+2 -2
View File
@@ -46,7 +46,7 @@ pub unsafe extern "C" fn pthread_rwlock_rdlock(rwlock: *mut pthread_rwlock_t) ->
#[no_mangle]
pub unsafe extern "C" fn pthread_rwlock_timedrdlock(rwlock: *mut pthread_rwlock_t, timeout: *const timespec) -> c_int {
let rwlock: &pthread_rwlock_t = &*rwlock;
let timeout = NonNull::new(timeout as *mut _).map(|n| n.as_ref());
let timeout = timeout.as_ref();
loop {
if pthread_rwlock_tryrdlock(rwlock as *const _ as *mut _) == EBUSY {
@@ -58,7 +58,7 @@ pub unsafe extern "C" fn pthread_rwlock_timedrdlock(rwlock: *mut pthread_rwlock_
#[no_mangle]
pub unsafe extern "C" fn pthread_rwlock_timedwrlock(rwlock: *mut pthread_rwlock_t, timeout: *const timespec) -> c_int {
let rwlock: &pthread_rwlock_t = &*rwlock;
let timeout = NonNull::new(timeout as *mut _).map(|n| n.as_ref());
let timeout = timeout.as_ref();
loop {
if pthread_rwlock_trywrlock(rwlock as *const _ as *mut _) == EBUSY {
+73
View File
@@ -0,0 +1,73 @@
use super::*;
// TODO: Hashmap?
use alloc::collections::BTreeMap;
use core::cell::{Cell, RefCell};
use crate::header::errno::EINVAL;
// TODO: What should this limit be?
pub const PTHREAD_KEYS_MAX: u32 = 4096 * 32;
#[no_mangle]
pub unsafe extern "C" fn pthread_getspecific(key: pthread_key_t) -> *mut c_void {
let Some(&Record { data, .. }) = DICT.borrow_mut().get(&key) else {
return core::ptr::null_mut();
};
data
}
#[no_mangle]
pub unsafe extern "C" fn pthread_key_create(key_ptr: *mut pthread_key_t, destructor: extern "C" fn(value: *mut c_void)) -> c_int {
let key = NEXTKEY.get();
NEXTKEY.set(key + 1);
// TODO
//if key >= PTHREAD_KEYS_MAX {
//}
DICT.borrow_mut().insert(key, Record {
data: core::ptr::null_mut(),
destructor,
});
key_ptr.write(key);
0
}
#[no_mangle]
pub unsafe extern "C" fn pthread_key_delete(key: pthread_key_t) -> c_int {
if DICT.borrow_mut().remove(&key).is_none() {
// We don't have to return anything, but it's not less expensive to ignore it.
return EINVAL;
}
0
}
#[no_mangle]
pub unsafe extern "C" fn pthread_setspecific(key: pthread_key_t, value: *const c_void) -> c_int {
let mut guard = DICT.borrow_mut();
let Some(Record { data, .. }) = guard.get_mut(&key) else {
// We don't have to return anything, but it's not less expensive to ignore it.
return EINVAL;
};
*data = value as *mut c_void;
0
}
#[thread_local]
static DICT: RefCell<BTreeMap<u32, Record>> = RefCell::new(BTreeMap::new());
struct Record {
data: *mut c_void,
destructor: extern "C" fn(value: *mut c_void),
}
#[thread_local]
static NEXTKEY: Cell<u32> = Cell::new(1);