use core::{ptr, sync::atomic::Ordering}; use super::*; use crate::{ header::bits_pthread::{pthread_attr_t, pthread_t}, pthread::{Pthread, PthreadFlags}, }; impl Default for RlctAttr { fn default() -> Self { Self { // Default according to POSIX. detachstate: PTHREAD_CREATE_JOINABLE as _, // Default according to POSIX. inheritsched: PTHREAD_INHERIT_SCHED as _, // TODO: Linux // Redox uses a round-robin scheduler schedpolicy: SCHED_RR as _, // TODO: Linux uses this one. scope: PTHREAD_SCOPE_SYSTEM as _, guardsize: Sys::getpagesize(), // TODO stack: 0, // TODO stacksize: 1024 * 1024, param: sched_param { // TODO sched_priority: 0, }, #[cfg(target_pointer_width = "32")] _pad: [0; 12], } } } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_attr_destroy(attr: *mut pthread_attr_t) -> c_int { unsafe { core::ptr::drop_in_place(attr) }; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_attr_getdetachstate( attr: *const pthread_attr_t, detachstate: *mut c_int, ) -> c_int { unsafe { core::ptr::write(detachstate, (*attr.cast::()).detachstate as _) }; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_attr_getguardsize( attr: *const pthread_attr_t, size: *mut size_t, ) -> c_int { unsafe { core::ptr::write(size, (*attr.cast::()).guardsize) }; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_attr_getinheritsched( attr: *const pthread_attr_t, inheritsched: *mut c_int, ) -> c_int { unsafe { core::ptr::write(inheritsched, (*attr.cast::()).inheritsched as _) }; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_attr_getschedparam( attr: *const pthread_attr_t, param: *mut sched_param, ) -> c_int { unsafe { param.write((*attr.cast::()).param) }; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_attr_getschedpolicy( attr: *const pthread_attr_t, policy: *mut c_int, ) -> c_int { unsafe { core::ptr::write(policy, (*attr.cast::()).schedpolicy as _) }; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_attr_getscope( attr: *const pthread_attr_t, scope: *mut c_int, ) -> c_int { unsafe { core::ptr::write(scope, (*attr.cast::()).scope as _) }; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_attr_getstack( attr: *const pthread_attr_t, stackaddr: *mut *mut c_void, stacksize: *mut size_t, ) -> c_int { unsafe { core::ptr::write(stackaddr, (*attr.cast::()).stack as _) }; unsafe { core::ptr::write(stacksize, (*attr.cast::()).stacksize as _) }; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_attr_getstacksize( attr: *const pthread_attr_t, stacksize: *mut size_t, ) -> c_int { unsafe { core::ptr::write(stacksize, (*attr.cast::()).stacksize as _) }; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_attr_init(attr: *mut pthread_attr_t) -> c_int { unsafe { core::ptr::write(attr.cast::(), RlctAttr::default()) }; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_attr_setdetachstate( attr: *mut pthread_attr_t, detachstate: c_int, ) -> c_int { (unsafe { *attr.cast::() }).detachstate = detachstate as _; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_attr_setguardsize( attr: *mut pthread_attr_t, guardsize: c_int, ) -> c_int { (unsafe { *attr.cast::() }).guardsize = guardsize as _; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_attr_setinheritsched( attr: *mut pthread_attr_t, inheritsched: c_int, ) -> c_int { (unsafe { *attr.cast::() }).inheritsched = inheritsched as _; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_attr_setschedparam( attr: *mut pthread_attr_t, param: *const sched_param, ) -> c_int { (unsafe { *attr.cast::() }).param = unsafe { param.read() }; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_attr_setschedpolicy( attr: *mut pthread_attr_t, policy: c_int, ) -> c_int { (unsafe { *attr.cast::() }).schedpolicy = policy as u8; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_attr_setscope(attr: *mut pthread_attr_t, scope: c_int) -> c_int { (unsafe { *attr.cast::() }).scope = scope as u8; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_attr_setstack( attr: *mut pthread_attr_t, stackaddr: *mut c_void, stacksize: size_t, ) -> c_int { (unsafe { *attr.cast::() }).stack = stackaddr as usize; (unsafe { *attr.cast::() }).stacksize = stacksize; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_attr_setstacksize( attr: *mut pthread_attr_t, stacksize: size_t, ) -> c_int { (unsafe { *attr.cast::() }).stacksize = stacksize; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_getattr_np( thread_ptr: pthread_t, attr_ptr: *mut pthread_attr_t, ) -> c_int { let thread = unsafe { &*thread_ptr.cast::() }; let attr_ptr = attr_ptr.cast::(); unsafe { ptr::write(attr_ptr, RlctAttr::default()) }; let attr = unsafe { &mut *attr_ptr }; if thread.flags.load(Ordering::Acquire) & PthreadFlags::DETACHED.bits() != 0 { attr.detachstate = PTHREAD_CREATE_DETACHED as _; } attr.stack = thread.stack_base as usize; attr.stacksize = thread.stack_size; //TODO: more values? 0 }