diff --git a/src/header/assert/mod.rs b/src/header/assert/mod.rs index 95131f12df0a29b3ee59526c93edc3531d0de9dc..2b65a328922a5e262fccae50194ddd76332f3ca3 100644 --- a/src/header/assert/mod.rs +++ b/src/header/assert/mod.rs @@ -17,13 +17,7 @@ pub unsafe extern "C" fn __assert_fail( let file = CStr::from_ptr(file).to_str().unwrap(); let cond = CStr::from_ptr(cond).to_str().unwrap(); - eprintln!( - "{}: {}:{}: Assertion `{}` failed.", - func, - file, - line, - cond - ); + eprintln!("{}: {}:{}: Assertion `{}` failed.", func, file, line, cond); core::intrinsics::abort(); } diff --git a/src/header/bits_pthread/mod.rs b/src/header/bits_pthread/mod.rs index af4d166b0326e8368ddbbbf765ad064d6f84a647..27446c010e4b9006c65480b16111c4872e820685 100644 --- a/src/header/bits_pthread/mod.rs +++ b/src/header/bits_pthread/mod.rs @@ -5,7 +5,7 @@ use crate::platform::types::*; use crate::header::sched::sched_param; use crate::sync::AtomicLock; -use core::sync::atomic::{AtomicU32 as AtomicUint, AtomicI32 as AtomicInt}; +use core::sync::atomic::{AtomicI32 as AtomicInt, AtomicU32 as AtomicUint}; // XXX: https://github.com/eqrion/cbindgen/issues/685 // diff --git a/src/header/poll/mod.rs b/src/header/poll/mod.rs index 265f30321856b3df2f30f6e66531616614e75372..887402ceafa0961034115da9a85ab71f8d1a21e1 100644 --- a/src/header/poll/mod.rs +++ b/src/header/poll/mod.rs @@ -6,7 +6,8 @@ use crate::{ fs::File, header::sys_epoll::{ epoll_create1, epoll_ctl, epoll_data, epoll_event, epoll_wait, EPOLLERR, EPOLLHUP, EPOLLIN, - EPOLLNVAL, EPOLLOUT, EPOLLPRI, EPOLLRDBAND, EPOLLRDNORM, EPOLLWRBAND, EPOLLWRNORM, EPOLL_CLOEXEC, EPOLL_CTL_ADD, + EPOLLNVAL, EPOLLOUT, EPOLLPRI, EPOLLRDBAND, EPOLLRDNORM, EPOLLWRBAND, EPOLLWRNORM, + EPOLL_CLOEXEC, EPOLL_CTL_ADD, }, platform::types::*, }; diff --git a/src/header/pthread/attr.rs b/src/header/pthread/attr.rs index 732704f3321315eaf650a24869a637d5aa2e45a7..00984f472be04f33ea9e8372a58c507805eb0419 100644 --- a/src/header/pthread/attr.rs +++ b/src/header/pthread/attr.rs @@ -36,50 +36,75 @@ pub unsafe extern "C" fn pthread_attr_destroy(attr: *mut pthread_attr_t) -> c_in } #[no_mangle] -pub unsafe extern "C" fn pthread_attr_getdetachstate(attr: *const pthread_attr_t, detachstate: *mut c_int) -> c_int { +pub unsafe extern "C" fn pthread_attr_getdetachstate( + attr: *const pthread_attr_t, + detachstate: *mut c_int, +) -> c_int { core::ptr::write(detachstate, (*attr.cast::<RlctAttr>()).detachstate as _); 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_attr_getguardsize(attr: *const pthread_attr_t, size: *mut size_t) -> c_int { +pub unsafe extern "C" fn pthread_attr_getguardsize( + attr: *const pthread_attr_t, + size: *mut size_t, +) -> c_int { core::ptr::write(size, (*attr.cast::<RlctAttr>()).guardsize); 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_attr_getinheritsched(attr: *const pthread_attr_t, inheritsched: *mut c_int) -> c_int { +pub unsafe extern "C" fn pthread_attr_getinheritsched( + attr: *const pthread_attr_t, + inheritsched: *mut c_int, +) -> c_int { core::ptr::write(inheritsched, (*attr.cast::<RlctAttr>()).inheritsched as _); 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_attr_getschedparam(attr: *const pthread_attr_t, param: *mut sched_param) -> c_int { +pub unsafe extern "C" fn pthread_attr_getschedparam( + attr: *const pthread_attr_t, + param: *mut sched_param, +) -> c_int { param.write((*attr.cast::<RlctAttr>()).param); 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_attr_getschedpolicy(attr: *const pthread_attr_t, policy: *mut c_int) -> c_int { +pub unsafe extern "C" fn pthread_attr_getschedpolicy( + attr: *const pthread_attr_t, + policy: *mut c_int, +) -> c_int { core::ptr::write(policy, (*attr.cast::<RlctAttr>()).schedpolicy as _); 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_attr_getscope(attr: *const pthread_attr_t, scope: *mut c_int) -> c_int { +pub unsafe extern "C" fn pthread_attr_getscope( + attr: *const pthread_attr_t, + scope: *mut c_int, +) -> c_int { core::ptr::write(scope, (*attr.cast::<RlctAttr>()).scope as _); 0 } #[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 { +pub unsafe extern "C" fn pthread_attr_getstack( + attr: *const pthread_attr_t, + stackaddr: *mut *mut c_void, + stacksize: *mut size_t, +) -> c_int { core::ptr::write(stackaddr, (*attr.cast::<RlctAttr>()).stack as _); core::ptr::write(stacksize, (*attr.cast::<RlctAttr>()).stacksize as _); 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_attr_getstacksize(attr: *const pthread_attr_t, stacksize: *mut c_int) -> c_int { +pub unsafe extern "C" fn pthread_attr_getstacksize( + attr: *const pthread_attr_t, + stacksize: *mut c_int, +) -> c_int { core::ptr::write(stacksize, (*attr.cast::<RlctAttr>()).stacksize as _); 0 } @@ -91,31 +116,46 @@ pub unsafe extern "C" fn pthread_attr_init(attr: *mut pthread_attr_t) -> c_int { } #[no_mangle] -pub unsafe extern "C" fn pthread_attr_setdetachstate(attr: *mut pthread_attr_t, detachstate: c_int) -> c_int { +pub unsafe extern "C" fn pthread_attr_setdetachstate( + attr: *mut pthread_attr_t, + detachstate: c_int, +) -> c_int { (*attr.cast::<RlctAttr>()).detachstate = detachstate as _; 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_attr_setguardsize(attr: *mut pthread_attr_t, guardsize: c_int) -> c_int { +pub unsafe extern "C" fn pthread_attr_setguardsize( + attr: *mut pthread_attr_t, + guardsize: c_int, +) -> c_int { (*attr.cast::<RlctAttr>()).guardsize = guardsize as _; 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_attr_setinheritsched(attr: *mut pthread_attr_t, inheritsched: c_int) -> c_int { +pub unsafe extern "C" fn pthread_attr_setinheritsched( + attr: *mut pthread_attr_t, + inheritsched: c_int, +) -> c_int { (*attr.cast::<RlctAttr>()).inheritsched = inheritsched as _; 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_attr_setschedparam(attr: *mut pthread_attr_t, param: *const sched_param) -> c_int { +pub unsafe extern "C" fn pthread_attr_setschedparam( + attr: *mut pthread_attr_t, + param: *const sched_param, +) -> c_int { (*attr.cast::<RlctAttr>()).param = param.read(); 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_attr_setschedpolicy(attr: *mut pthread_attr_t, policy: c_int) -> c_int { +pub unsafe extern "C" fn pthread_attr_setschedpolicy( + attr: *mut pthread_attr_t, + policy: c_int, +) -> c_int { (*attr.cast::<RlctAttr>()).schedpolicy = policy as u8; 0 } @@ -127,14 +167,21 @@ pub unsafe extern "C" fn pthread_attr_setscope(attr: *mut pthread_attr_t, scope: } #[no_mangle] -pub unsafe extern "C" fn pthread_attr_setstack(attr: *mut pthread_attr_t, stackaddr: *mut c_void, stacksize: size_t) -> c_int { +pub unsafe extern "C" fn pthread_attr_setstack( + attr: *mut pthread_attr_t, + stackaddr: *mut c_void, + stacksize: size_t, +) -> c_int { (*attr.cast::<RlctAttr>()).stack = stackaddr as usize; (*attr.cast::<RlctAttr>()).stacksize = stacksize; 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_attr_setstacksize(attr: *mut pthread_attr_t, stacksize: size_t) -> c_int { +pub unsafe extern "C" fn pthread_attr_setstacksize( + attr: *mut pthread_attr_t, + stacksize: size_t, +) -> c_int { (*attr.cast::<RlctAttr>()).stacksize = stacksize; 0 } diff --git a/src/header/pthread/barrier.rs b/src/header/pthread/barrier.rs index e4c6905d21970736776542f9078f94ad1ae8288b..962121abffaea6d4f0c49c9132f61dbc4012ec3b 100644 --- a/src/header/pthread/barrier.rs +++ b/src/header/pthread/barrier.rs @@ -15,7 +15,9 @@ pub(crate) struct RlctBarrierAttr { impl Default for RlctBarrierAttr { fn default() -> Self { // pshared = PTHREAD_PROCESS_PRIVATE is default according to POSIX. - Self { pshared: PTHREAD_PROCESS_PRIVATE } + Self { + pshared: PTHREAD_PROCESS_PRIVATE, + } } } @@ -32,8 +34,16 @@ pub unsafe extern "C" fn pthread_barrier_destroy(barrier: *mut pthread_barrier_t // Not async-signal-safe. #[no_mangle] -pub unsafe extern "C" fn pthread_barrier_init(barrier: *mut pthread_barrier_t, attr: *const pthread_barrierattr_t, count: c_uint) -> c_int { - let attr = attr.cast::<RlctBarrierAttr>().as_ref().copied().unwrap_or_default(); +pub unsafe extern "C" fn pthread_barrier_init( + barrier: *mut pthread_barrier_t, + attr: *const pthread_barrierattr_t, + count: c_uint, +) -> c_int { + let attr = attr + .cast::<RlctBarrierAttr>() + .as_ref() + .copied() + .unwrap_or_default(); let Some(count) = NonZeroU32::new(count) else { return EINVAL; @@ -43,7 +53,9 @@ pub unsafe extern "C" fn pthread_barrier_init(barrier: *mut pthread_barrier_t, a 0 } -fn unlikely(condition: bool) -> bool { condition } +fn unlikely(condition: bool) -> bool { + condition +} // Not async-signal-safe. #[no_mangle] @@ -66,14 +78,20 @@ pub unsafe extern "C" fn pthread_barrierattr_init(attr: *mut pthread_barrierattr // Not async-signal-safe. #[no_mangle] -pub unsafe extern "C" fn pthread_barrierattr_setpshared(attr: *mut pthread_barrierattr_t, pshared: c_int) -> c_int { +pub unsafe extern "C" fn pthread_barrierattr_setpshared( + attr: *mut pthread_barrierattr_t, + pshared: c_int, +) -> c_int { (*attr.cast::<RlctBarrierAttr>()).pshared = pshared; 0 } // Not async-signal-safe. #[no_mangle] -pub unsafe extern "C" fn pthread_barrierattr_getpshared(attr: *const pthread_barrierattr_t, pshared: *mut c_int) -> c_int { +pub unsafe extern "C" fn pthread_barrierattr_getpshared( + attr: *const pthread_barrierattr_t, + pshared: *mut c_int, +) -> c_int { core::ptr::write(pshared, (*attr.cast::<RlctBarrierAttr>()).pshared); 0 } diff --git a/src/header/pthread/cond.rs b/src/header/pthread/cond.rs index e91edac356628431111de25f9cf78a8c395890a6..064ce6a66137208735359cbc41b720dc26f87462 100644 --- a/src/header/pthread/cond.rs +++ b/src/header/pthread/cond.rs @@ -17,7 +17,10 @@ pub unsafe extern "C" fn pthread_cond_destroy(cond: *mut pthread_cond_t) -> c_in } #[no_mangle] -pub unsafe extern "C" fn pthread_cond_init(cond: *mut pthread_cond_t, _attr: *const pthread_condattr_t) -> c_int { +pub unsafe extern "C" fn pthread_cond_init( + cond: *mut pthread_cond_t, + _attr: *const pthread_condattr_t, +) -> c_int { cond.cast::<RlctCond>().write(RlctCond::new()); 0 @@ -29,12 +32,19 @@ pub unsafe extern "C" fn pthread_cond_signal(cond: *mut pthread_cond_t) -> c_int } #[no_mangle] -pub unsafe extern "C" fn pthread_cond_timedwait(cond: *mut pthread_cond_t, mutex: *mut pthread_mutex_t, timeout: *const timespec) -> c_int { +pub unsafe extern "C" fn pthread_cond_timedwait( + cond: *mut pthread_cond_t, + mutex: *mut pthread_mutex_t, + timeout: *const timespec, +) -> c_int { e((&*cond.cast::<RlctCond>()).timedwait(&*mutex.cast::<RlctMutex>(), &*timeout)) } #[no_mangle] -pub unsafe extern "C" fn pthread_cond_wait(cond: *mut pthread_cond_t, mutex: *mut pthread_mutex_t) -> c_int { +pub unsafe extern "C" fn pthread_cond_wait( + cond: *mut pthread_cond_t, + mutex: *mut pthread_mutex_t, +) -> c_int { e((&*cond.cast::<RlctCond>()).wait(&*mutex.cast::<RlctMutex>())) } @@ -46,32 +56,46 @@ pub unsafe extern "C" fn pthread_condattr_destroy(condattr: *mut pthread_condatt } #[no_mangle] -pub unsafe extern "C" fn pthread_condattr_getclock(condattr: *const pthread_condattr_t, clock: *mut clockid_t) -> c_int { +pub unsafe extern "C" fn pthread_condattr_getclock( + condattr: *const pthread_condattr_t, + clock: *mut clockid_t, +) -> c_int { core::ptr::write(clock, (*condattr.cast::<RlctCondAttr>()).clock); 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_condattr_getpshared(condattr: *const pthread_condattr_t, pshared: *mut c_int) -> c_int { +pub unsafe extern "C" fn pthread_condattr_getpshared( + condattr: *const pthread_condattr_t, + pshared: *mut c_int, +) -> c_int { core::ptr::write(pshared, (*condattr.cast::<RlctCondAttr>()).pshared); 0 } #[no_mangle] pub unsafe extern "C" fn pthread_condattr_init(condattr: *mut pthread_condattr_t) -> c_int { - condattr.cast::<RlctCondAttr>().write(RlctCondAttr::default()); + condattr + .cast::<RlctCondAttr>() + .write(RlctCondAttr::default()); 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_condattr_setclock(condattr: *mut pthread_condattr_t, clock: clockid_t) -> c_int { +pub unsafe extern "C" fn pthread_condattr_setclock( + condattr: *mut pthread_condattr_t, + clock: clockid_t, +) -> c_int { (*condattr.cast::<RlctCondAttr>()).clock = clock; 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_condattr_setpshared(condattr: *mut pthread_condattr_t, pshared: c_int) -> c_int { +pub unsafe extern "C" fn pthread_condattr_setpshared( + condattr: *mut pthread_condattr_t, + pshared: c_int, +) -> c_int { (*condattr.cast::<RlctCondAttr>()).pshared = pshared; 0 } diff --git a/src/header/pthread/mod.rs b/src/header/pthread/mod.rs index 7e7ae5c1c829668f47a03821cb5cc71520f90468..253dd656b3e3317c0406fb5ca6bdb66a0d0ea814 100644 --- a/src/header/pthread/mod.rs +++ b/src/header/pthread/mod.rs @@ -1,11 +1,12 @@ //! pthread.h implementation for Redox, following https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/pthread.h.html -use core::ptr::NonNull; -use core::cell::Cell; +use core::{cell::Cell, ptr::NonNull}; -use crate::platform::{self, Pal, Sys, types::*}; -use crate::header::{sched::*, time::timespec}; -use crate::pthread; +use crate::{ + header::{sched::*, time::timespec}, + platform::{self, types::*, Pal, Sys}, + pthread, +}; pub fn e(result: Result<(), pthread::Errno>) -> i32 { match result { @@ -82,7 +83,12 @@ pub mod cond; pub use self::cond::*; #[no_mangle] -pub unsafe extern "C" fn pthread_create(pthread: *mut pthread_t, attr: *const pthread_attr_t, start_routine: extern "C" fn(arg: *mut c_void) -> *mut c_void, arg: *mut c_void) -> c_int { +pub unsafe extern "C" fn pthread_create( + pthread: *mut pthread_t, + attr: *const pthread_attr_t, + start_routine: extern "C" fn(arg: *mut c_void) -> *mut c_void, + arg: *mut c_void, +) -> c_int { let attr = attr.cast::<RlctAttr>().as_ref(); match pthread::create(attr, start_routine, arg) { @@ -119,7 +125,10 @@ pub unsafe extern "C" fn pthread_getconcurrency() -> c_int { } #[no_mangle] -pub unsafe extern "C" fn pthread_getcpuclockid(thread: pthread_t, clock_out: *mut clockid_t) -> c_int { +pub unsafe extern "C" fn pthread_getcpuclockid( + thread: pthread_t, + clock_out: *mut clockid_t, +) -> c_int { match pthread::get_cpu_clkid(&*thread.cast()) { Ok(clock) => { clock_out.write(clock); @@ -130,7 +139,11 @@ pub unsafe extern "C" fn pthread_getcpuclockid(thread: pthread_t, clock_out: *mu } #[no_mangle] -pub unsafe extern "C" fn pthread_getschedparam(thread: pthread_t, policy_out: *mut c_int, param_out: *mut sched_param) -> c_int { +pub unsafe extern "C" fn pthread_getschedparam( + thread: pthread_t, + policy_out: *mut c_int, + param_out: *mut sched_param, +) -> c_int { match pthread::get_sched_param(&*thread.cast()) { Ok((policy, param)) => { policy_out.write(policy); @@ -199,7 +212,11 @@ pub extern "C" fn pthread_setconcurrency(concurrency: c_int) -> c_int { } #[no_mangle] -pub unsafe extern "C" fn pthread_setschedparam(thread: pthread_t, policy: c_int, param: *const sched_param) -> c_int { +pub unsafe extern "C" fn pthread_setschedparam( + thread: pthread_t, + policy: c_int, + param: *const sched_param, +) -> c_int { e(pthread::set_sched_param(&*thread.cast(), policy, &*param)) } #[no_mangle] @@ -224,7 +241,8 @@ pub(crate) struct CleanupLinkedListEntry { } #[thread_local] -pub(crate) static CLEANUP_LL_HEAD: Cell<*const CleanupLinkedListEntry> = Cell::new(core::ptr::null()); +pub(crate) static CLEANUP_LL_HEAD: Cell<*const CleanupLinkedListEntry> = + Cell::new(core::ptr::null()); // TODO: unwind? setjmp/longjmp? diff --git a/src/header/pthread/mutex.rs b/src/header/pthread/mutex.rs index a8b9a13c1ac1173989d940bbda73c0f52f9700c1..d24f6b7ccde46d7cefccfae63902b47270cff3a7 100644 --- a/src/header/pthread/mutex.rs +++ b/src/header/pthread/mutex.rs @@ -1,7 +1,6 @@ use super::*; -use crate::header::errno::*; -use crate::pthread::Errno; +use crate::{header::errno::*, pthread::Errno}; use core::sync::atomic::AtomicI32 as AtomicInt; @@ -19,7 +18,10 @@ pub unsafe extern "C" fn pthread_mutex_destroy(mutex: *mut pthread_mutex_t) -> c } #[no_mangle] -pub unsafe extern "C" fn pthread_mutex_getprioceiling(mutex: *const pthread_mutex_t, prioceiling: *mut c_int) -> c_int { +pub unsafe extern "C" fn pthread_mutex_getprioceiling( + mutex: *const pthread_mutex_t, + prioceiling: *mut c_int, +) -> c_int { match (&*mutex.cast::<RlctMutex>()).prioceiling() { Ok(value) => { prioceiling.write(value); @@ -30,8 +32,15 @@ pub unsafe extern "C" fn pthread_mutex_getprioceiling(mutex: *const pthread_mute } #[no_mangle] -pub unsafe extern "C" fn pthread_mutex_init(mutex: *mut pthread_mutex_t, attr: *const pthread_mutexattr_t) -> c_int { - let attr = attr.cast::<RlctMutexAttr>().as_ref().copied().unwrap_or_default(); +pub unsafe extern "C" fn pthread_mutex_init( + mutex: *mut pthread_mutex_t, + attr: *const pthread_mutexattr_t, +) -> c_int { + let attr = attr + .cast::<RlctMutexAttr>() + .as_ref() + .copied() + .unwrap_or_default(); match RlctMutex::new(&attr) { Ok(new) => { @@ -48,7 +57,11 @@ pub unsafe extern "C" fn pthread_mutex_lock(mutex: *mut pthread_mutex_t) -> c_in } #[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 { +pub unsafe extern "C" fn pthread_mutex_setprioceiling( + mutex: *mut pthread_mutex_t, + prioceiling: c_int, + old_prioceiling: *mut c_int, +) -> c_int { match (&*mutex.cast::<RlctMutex>()).replace_prioceiling(prioceiling) { Ok(old) => { old_prioceiling.write(old); @@ -59,7 +72,10 @@ pub unsafe extern "C" fn pthread_mutex_setprioceiling(mutex: *mut pthread_mutex_ } #[no_mangle] -pub unsafe extern "C" fn pthread_mutex_timedlock(mutex: *mut pthread_mutex_t, timespec: *const timespec) -> c_int { +pub unsafe extern "C" fn pthread_mutex_timedlock( + mutex: *mut pthread_mutex_t, + timespec: *const timespec, +) -> c_int { e((&*mutex.cast::<RlctMutex>()).lock_with_timeout(&*timespec)) } #[no_mangle] @@ -79,30 +95,45 @@ pub unsafe extern "C" fn pthread_mutexattr_destroy(attr: *mut pthread_mutexattr_ } #[no_mangle] -pub unsafe extern "C" fn pthread_mutexattr_getprioceiling(attr: *const pthread_mutexattr_t, prioceiling: *mut c_int) -> c_int { +pub unsafe extern "C" fn pthread_mutexattr_getprioceiling( + attr: *const pthread_mutexattr_t, + prioceiling: *mut c_int, +) -> c_int { prioceiling.write((*attr.cast::<RlctMutexAttr>()).prioceiling); 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_mutexattr_getprotocol(attr: *const pthread_mutexattr_t, protocol: *mut c_int) -> c_int { +pub unsafe extern "C" fn pthread_mutexattr_getprotocol( + attr: *const pthread_mutexattr_t, + protocol: *mut c_int, +) -> c_int { protocol.write((*attr.cast::<RlctMutexAttr>()).protocol); 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_mutexattr_getpshared(attr: *const pthread_mutexattr_t, pshared: *mut c_int) -> c_int { +pub unsafe extern "C" fn pthread_mutexattr_getpshared( + attr: *const pthread_mutexattr_t, + pshared: *mut c_int, +) -> c_int { pshared.write((*attr.cast::<RlctMutexAttr>()).pshared); 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_mutexattr_getrobust(attr: *const pthread_mutexattr_t, robust: *mut c_int) -> c_int { +pub unsafe extern "C" fn pthread_mutexattr_getrobust( + attr: *const pthread_mutexattr_t, + robust: *mut c_int, +) -> c_int { robust.write((*attr.cast::<RlctMutexAttr>()).robust); 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_mutexattr_gettype(attr: *const pthread_mutexattr_t, ty: *mut c_int) -> c_int { +pub unsafe extern "C" fn pthread_mutexattr_gettype( + attr: *const pthread_mutexattr_t, + ty: *mut c_int, +) -> c_int { ty.write((*attr.cast::<RlctMutexAttr>()).ty); 0 } @@ -113,30 +144,45 @@ pub unsafe extern "C" fn pthread_mutexattr_init(attr: *mut pthread_mutexattr_t) } #[no_mangle] -pub unsafe extern "C" fn pthread_mutexattr_setprioceiling(attr: *mut pthread_mutexattr_t, prioceiling: c_int) -> c_int { +pub unsafe extern "C" fn pthread_mutexattr_setprioceiling( + attr: *mut pthread_mutexattr_t, + prioceiling: c_int, +) -> c_int { (*attr.cast::<RlctMutexAttr>()).prioceiling = prioceiling; 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_mutexattr_setprotocol(attr: *mut pthread_mutexattr_t, protocol: c_int) -> c_int { +pub unsafe extern "C" fn pthread_mutexattr_setprotocol( + attr: *mut pthread_mutexattr_t, + protocol: c_int, +) -> c_int { (*attr.cast::<RlctMutexAttr>()).protocol = protocol; 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_mutexattr_setpshared(attr: *mut pthread_mutexattr_t, pshared: c_int) -> c_int { +pub unsafe extern "C" fn pthread_mutexattr_setpshared( + attr: *mut pthread_mutexattr_t, + pshared: c_int, +) -> c_int { (*attr.cast::<RlctMutexAttr>()).pshared = pshared; 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_mutexattr_setrobust(attr: *mut pthread_mutexattr_t, robust: c_int) -> c_int { +pub unsafe extern "C" fn pthread_mutexattr_setrobust( + attr: *mut pthread_mutexattr_t, + robust: c_int, +) -> c_int { (*attr.cast::<RlctMutexAttr>()).robust = robust; 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_mutexattr_settype(attr: *mut pthread_mutexattr_t, ty: c_int) -> c_int { +pub unsafe extern "C" fn pthread_mutexattr_settype( + attr: *mut pthread_mutexattr_t, + ty: c_int, +) -> c_int { (*attr.cast::<RlctMutexAttr>()).ty = ty; 0 } diff --git a/src/header/pthread/once.rs b/src/header/pthread/once.rs index 28400ae6c06ac0b065cf1f30621bedafdbf66991..43d1672a7fe8ae6bc53ed83d0b8ebf80e2251445 100644 --- a/src/header/pthread/once.rs +++ b/src/header/pthread/once.rs @@ -3,7 +3,10 @@ use super::*; // PTHREAD_ONCE_INIT #[no_mangle] -pub unsafe extern "C" fn pthread_once(once: *mut pthread_once_t, constructor: extern "C" fn()) -> c_int { +pub unsafe extern "C" fn pthread_once( + once: *mut pthread_once_t, + constructor: extern "C" fn(), +) -> c_int { let once = &*once.cast::<RlctOnce>(); // TODO: Cancellation points diff --git a/src/header/pthread/rwlock.rs b/src/header/pthread/rwlock.rs index 54ebabbe43540e90983c4b2c574b5a1675b3875a..e11ea881282ce4207067d75772d0f139da78e4af 100644 --- a/src/header/pthread/rwlock.rs +++ b/src/header/pthread/rwlock.rs @@ -5,10 +5,19 @@ use crate::header::errno::EBUSY; use crate::pthread::Pshared; #[no_mangle] -pub unsafe extern "C" fn pthread_rwlock_init(rwlock: *mut pthread_rwlock_t, attr: *const pthread_rwlockattr_t) -> c_int { - let attr = attr.cast::<RlctRwlockAttr>().as_ref().copied().unwrap_or_default(); - - rwlock.cast::<RlctRwlock>().write(RlctRwlock::new(attr.pshared)); +pub unsafe extern "C" fn pthread_rwlock_init( + rwlock: *mut pthread_rwlock_t, + attr: *const pthread_rwlockattr_t, +) -> c_int { + let attr = attr + .cast::<RlctRwlockAttr>() + .as_ref() + .copied() + .unwrap_or_default(); + + rwlock + .cast::<RlctRwlock>() + .write(RlctRwlock::new(attr.pshared)); 0 } @@ -19,13 +28,19 @@ pub unsafe extern "C" fn pthread_rwlock_rdlock(rwlock: *mut pthread_rwlock_t) -> 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_rwlock_timedrdlock(rwlock: *mut pthread_rwlock_t, timeout: *const timespec) -> c_int { +pub unsafe extern "C" fn pthread_rwlock_timedrdlock( + rwlock: *mut pthread_rwlock_t, + timeout: *const timespec, +) -> c_int { get(rwlock).acquire_read_lock(Some(&*timeout)); 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_rwlock_timedwrlock(rwlock: *mut pthread_rwlock_t, timeout: *const timespec) -> c_int { +pub unsafe extern "C" fn pthread_rwlock_timedwrlock( + rwlock: *mut pthread_rwlock_t, + timeout: *const timespec, +) -> c_int { get(rwlock).acquire_write_lock(Some(&*timeout)); 0 @@ -59,21 +74,29 @@ pub unsafe extern "C" fn pthread_rwlock_wrlock(rwlock: *mut pthread_rwlock_t) -> #[no_mangle] pub unsafe extern "C" fn pthread_rwlockattr_init(attr: *mut pthread_rwlockattr_t) -> c_int { - attr.cast::<RlctRwlockAttr>().write(RlctRwlockAttr::default()); + attr.cast::<RlctRwlockAttr>() + .write(RlctRwlockAttr::default()); 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_rwlockattr_getpshared(attr: *const pthread_rwlockattr_t, pshared_out: *mut c_int) -> c_int { +pub unsafe extern "C" fn pthread_rwlockattr_getpshared( + attr: *const pthread_rwlockattr_t, + pshared_out: *mut c_int, +) -> c_int { core::ptr::write(pshared_out, (*attr.cast::<RlctRwlockAttr>()).pshared.raw()); 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_rwlockattr_setpshared(attr: *mut pthread_rwlockattr_t, pshared: c_int) -> c_int { - (*attr.cast::<RlctRwlockAttr>()).pshared = Pshared::from_raw(pshared).expect("invalid pshared in pthread_rwlockattr_setpshared"); +pub unsafe extern "C" fn pthread_rwlockattr_setpshared( + attr: *mut pthread_rwlockattr_t, + pshared: c_int, +) -> c_int { + (*attr.cast::<RlctRwlockAttr>()).pshared = + Pshared::from_raw(pshared).expect("invalid pshared in pthread_rwlockattr_setpshared"); 0 } diff --git a/src/header/pthread/spin.rs b/src/header/pthread/spin.rs index c847ee340522cee068c92fcedc5c30e6c90f9111..d22e988260c28c5a34dd73dcf124c8e96fe4147d 100644 --- a/src/header/pthread/spin.rs +++ b/src/header/pthread/spin.rs @@ -15,11 +15,16 @@ pub unsafe extern "C" fn pthread_spin_destroy(spinlock: *mut pthread_spinlock_t) 0 } #[no_mangle] -pub unsafe extern "C" fn pthread_spin_init(spinlock: *mut pthread_spinlock_t, _pshared: c_int) -> c_int { +pub unsafe extern "C" fn pthread_spin_init( + spinlock: *mut pthread_spinlock_t, + _pshared: c_int, +) -> c_int { // TODO: pshared doesn't matter in most situations, as memory is just memory, but this may be // different on some architectures... - spinlock.cast::<RlctSpinlock>().write(RlctSpinlock { inner: AtomicInt::new(UNLOCKED) }); + spinlock.cast::<RlctSpinlock>().write(RlctSpinlock { + inner: AtomicInt::new(UNLOCKED), + }); 0 } @@ -28,7 +33,12 @@ pub unsafe extern "C" fn pthread_spin_lock(spinlock: *mut pthread_spinlock_t) -> let spinlock = &*spinlock.cast::<RlctSpinlock>(); loop { - match spinlock.inner.compare_exchange_weak(UNLOCKED, LOCKED, Ordering::Acquire, Ordering::Relaxed) { + match spinlock.inner.compare_exchange_weak( + UNLOCKED, + LOCKED, + Ordering::Acquire, + Ordering::Relaxed, + ) { Ok(_) => break, Err(_) => core::hint::spin_loop(), } @@ -40,7 +50,10 @@ pub unsafe extern "C" fn pthread_spin_lock(spinlock: *mut pthread_spinlock_t) -> pub unsafe extern "C" fn pthread_spin_trylock(spinlock: *mut pthread_spinlock_t) -> c_int { let spinlock = &*spinlock.cast::<RlctSpinlock>(); - match spinlock.inner.compare_exchange(UNLOCKED, LOCKED, Ordering::Acquire, Ordering::Relaxed) { + match spinlock + .inner + .compare_exchange(UNLOCKED, LOCKED, Ordering::Acquire, Ordering::Relaxed) + { Ok(_) => (), Err(_) => return EBUSY, } diff --git a/src/header/pthread/tls.rs b/src/header/pthread/tls.rs index 57c7c354586dbb2b78a8ce9f6ff8606208c389bb..3d8b3027f79dcc601027fb41064ea3498553e65c 100644 --- a/src/header/pthread/tls.rs +++ b/src/header/pthread/tls.rs @@ -5,8 +5,7 @@ use alloc::collections::BTreeMap; use core::cell::{Cell, RefCell}; -use crate::header::errno::EINVAL; -use crate::sync::Mutex; +use crate::{header::errno::EINVAL, sync::Mutex}; // TODO: What should this limit be? pub const PTHREAD_KEYS_MAX: u32 = 4096 * 32; @@ -30,7 +29,10 @@ pub unsafe extern "C" fn pthread_getspecific(key: pthread_key_t) -> *mut c_void data } #[no_mangle] -pub unsafe extern "C" fn pthread_key_create(key_ptr: *mut pthread_key_t, destructor: Option<extern "C" fn(value: *mut c_void)>) -> c_int { +pub unsafe extern "C" fn pthread_key_create( + key_ptr: *mut pthread_key_t, + destructor: Option<extern "C" fn(value: *mut c_void)>, +) -> c_int { let key = NEXTKEY.get(); NEXTKEY.set(key + 1); //println!("pthread_key_create new key {:#0x}, dtor {:p}", key, destructor); @@ -41,9 +43,12 @@ pub unsafe extern "C" fn pthread_key_create(key_ptr: *mut pthread_key_t, destruc KEYS.lock().insert(key, Dtor { destructor }); - VALUES.borrow_mut().insert(key, Record { - data: core::ptr::null_mut(), - }); + VALUES.borrow_mut().insert( + key, + Record { + data: core::ptr::null_mut(), + }, + ); key_ptr.write(key); @@ -61,7 +66,7 @@ pub unsafe extern "C" fn pthread_key_delete(key: pthread_key_t) -> c_int { 0 } - #[no_mangle] +#[no_mangle] pub unsafe extern "C" fn pthread_setspecific(key: pthread_key_t, value: *const c_void) -> c_int { if !KEYS.lock().contains_key(&key) { // We don't have to return anything, but it's not less expensive to ignore it. @@ -71,7 +76,9 @@ pub unsafe extern "C" fn pthread_setspecific(key: pthread_key_t, value: *const c let mut guard = VALUES.borrow_mut(); - let Record { ref mut data, .. } = guard.entry(key).or_insert(Record { data: core::ptr::null_mut() }); + let Record { ref mut data, .. } = guard.entry(key).or_insert(Record { + data: core::ptr::null_mut(), + }); //println!("Valid key for pthread_setspecific key {:#0x} value {:p} (was {:p})", key, value, *data); *data = value as *mut c_void; diff --git a/src/header/sched/mod.rs b/src/header/sched/mod.rs index b1c485b3664a166ee86cc98c34289b292a5843b4..a2f48b5753c4fc9b7bc54056ee02131436ca517e 100644 --- a/src/header/sched/mod.rs +++ b/src/header/sched/mod.rs @@ -1,7 +1,9 @@ //! sched.h implementation for Redox, following https://pubs.opengroup.org/onlinepubs/7908799/xsh/sched.h.html -use crate::platform::{Pal, Sys, types::*}; -use crate::header::time::timespec; +use crate::{ + header::time::timespec, + platform::{types::*, Pal, Sys}, +}; #[derive(Clone, Copy, Debug)] pub struct sched_param { @@ -33,7 +35,11 @@ pub unsafe extern "C" fn sched_setparam(pid: pid_t, param: *const sched_param) - todo!() } // #[no_mangle] -pub extern "C" fn sched_setscheduler(pid: pid_t, policy: c_int, param: *const sched_param) -> c_int { +pub extern "C" fn sched_setscheduler( + pid: pid_t, + policy: c_int, + param: *const sched_param, +) -> c_int { todo!() } #[no_mangle] diff --git a/src/header/semaphore/mod.rs b/src/header/semaphore/mod.rs index 5ad4c3c787f7d7438d8d4d1bfb9e361fa8d1f8dd..737ff609d8fa0946b9e1a7665e983afca37b82d8 100644 --- a/src/header/semaphore/mod.rs +++ b/src/header/semaphore/mod.rs @@ -22,10 +22,12 @@ pub unsafe extern "C" fn sem_destroy(sem: *mut sem_t) -> c_int { 0 } - // TODO: va_list // #[no_mangle] -pub unsafe extern "C" fn sem_open(name: *const c_char, oflag: c_int, /* (va_list) value: c_uint */) -> *mut sem_t { +pub unsafe extern "C" fn sem_open( + name: *const c_char, + oflag: c_int, /* (va_list) value: c_uint */ +) -> *mut sem_t { todo!("named semaphores") } diff --git a/src/header/signal/mod.rs b/src/header/signal/mod.rs index 5e06fae058990666eb8df2a9838044500710e5b2..a80ae0d4321e80803b8dda5e2aafdb80f406a987 100644 --- a/src/header/signal/mod.rs +++ b/src/header/signal/mod.rs @@ -5,10 +5,7 @@ use core::{mem, ptr}; use cbitset::BitSet; use crate::{ - header::{ - errno, - time::timespec, - }, + header::{errno, time::timespec}, platform::{self, types::*, Pal, PalSignal, Sys}, pthread, }; @@ -81,9 +78,7 @@ pub unsafe extern "C" fn pthread_kill(thread: pthread_t, sig: c_int) -> c_int { let pthread = &*(thread as *const pthread::Pthread); pthread.os_tid.get().read() }; - crate::header::pthread::e( - Sys::rlct_kill(os_tid, sig as usize) - ) + crate::header::pthread::e(Sys::rlct_kill(os_tid, sig as usize)) } #[no_mangle] @@ -276,10 +271,19 @@ const STANDARD_SIG_MASK: sigset_t = (1 << 32) - 1; const RLCT_SIGNAL_MASK: sigset_t = BELOW_SIGRTMIN_MASK & !STANDARD_SIG_MASK; #[no_mangle] -pub unsafe extern "C" fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int { +pub unsafe extern "C" fn sigprocmask( + how: c_int, + set: *const sigset_t, + oset: *mut sigset_t, +) -> c_int { let set = set.as_ref().map(|&block| block & !RLCT_SIGNAL_MASK); - Sys::sigprocmask(how, set.as_ref().map_or(core::ptr::null(), |r| r as *const sigset_t), oset) + Sys::sigprocmask( + how, + set.as_ref() + .map_or(core::ptr::null(), |r| r as *const sigset_t), + oset, + ) } #[no_mangle] @@ -296,7 +300,7 @@ pub unsafe extern "C" fn sigrelse(sig: c_int) -> c_int { #[no_mangle] pub unsafe extern "C" fn sigset( sig: c_int, - func: Option<extern "C" fn(c_int)> + func: Option<extern "C" fn(c_int)>, ) -> Option<extern "C" fn(c_int)> { let mut old_sa = mem::MaybeUninit::uninit(); let mut pset = mem::MaybeUninit::<sigset_t>::uninit(); @@ -308,10 +312,11 @@ pub unsafe extern "C" fn sigset( return sig_err; } else { if func == sig_hold { - if sigaction(sig, ptr::null_mut(), old_sa.as_mut_ptr()) < 0 || - sigprocmask(SIG_BLOCK, &mut set, &mut set) < 0 { - mem::forget(old_sa); - return sig_err; + if sigaction(sig, ptr::null_mut(), old_sa.as_mut_ptr()) < 0 + || sigprocmask(SIG_BLOCK, &mut set, &mut set) < 0 + { + mem::forget(old_sa); + return sig_err; } } else { let mut sa = sigaction { @@ -321,10 +326,11 @@ pub unsafe extern "C" fn sigset( sa_mask: sigset_t::default(), }; sigemptyset(&mut sa.sa_mask); - if sigaction(sig, &sa, old_sa.as_mut_ptr()) < 0 || - sigprocmask(SIG_UNBLOCK, &mut set, &mut set) < 0 { - mem::forget(old_sa); - return sig_err; + if sigaction(sig, &sa, old_sa.as_mut_ptr()) < 0 + || sigprocmask(SIG_UNBLOCK, &mut set, &mut set) < 0 + { + mem::forget(old_sa); + return sig_err; } } } @@ -353,7 +359,11 @@ pub extern "C" fn sigwait(set: *const sigset_t, sig: *mut c_int) -> c_int { } #[no_mangle] -pub extern "C" fn sigtimedwait(set: *const sigset_t, sig: *mut siginfo_t, tp: *const timespec) -> c_int { +pub extern "C" fn sigtimedwait( + set: *const sigset_t, + sig: *mut siginfo_t, + tp: *const timespec, +) -> c_int { Sys::sigtimedwait(set, sig, tp) } diff --git a/src/header/stdio/mod.rs b/src/header/stdio/mod.rs index 79d7a1be7cdf5de5f69d86fd1591e332cd338e54..6148e6fb15b043f2c29fa41a781a91af453d79b7 100644 --- a/src/header/stdio/mod.rs +++ b/src/header/stdio/mod.rs @@ -20,7 +20,7 @@ use crate::{ fs::File, header::{ errno::{self, STR_ERROR}, - fcntl, stdlib, pwd, + fcntl, pwd, stdlib, string::{self, strlen, strncpy}, unistd, }, @@ -286,7 +286,13 @@ pub unsafe extern "C" fn cuserid(s: *mut c_char) -> *mut c_char { if s != ptr::null_mut() { *s.add(0) = 0; } - pwd::getpwuid_r(unistd::geteuid(), &mut pwd, buf.as_mut_ptr(), buf.len(), &mut pwdbuf); + pwd::getpwuid_r( + unistd::geteuid(), + &mut pwd, + buf.as_mut_ptr(), + buf.len(), + &mut pwdbuf, + ); if pwdbuf == ptr::null_mut() { return s; } @@ -521,7 +527,7 @@ pub unsafe extern "C" fn fopen(filename: *const c_char, mode: *const c_char) -> /// itself. #[no_mangle] pub unsafe extern "C" fn __fpurge(stream: *mut FILE) { - if ! stream.is_null() { + if !stream.is_null() { let mut stream = (*stream).lock(); stream.purge(); } @@ -596,7 +602,11 @@ pub unsafe extern "C" fn freopen( if filename.is_null() { // Reopen stream in new mode if flags & fcntl::O_CLOEXEC > 0 { - fcntl::sys_fcntl(*stream.file, fcntl::F_SETFD, fcntl::FD_CLOEXEC as c_ulonglong); + fcntl::sys_fcntl( + *stream.file, + fcntl::F_SETFD, + fcntl::FD_CLOEXEC as c_ulonglong, + ); } flags &= !(fcntl::O_CREAT | fcntl::O_EXCL | fcntl::O_CLOEXEC); if fcntl::sys_fcntl(*stream.file, fcntl::F_SETFL, flags as c_ulonglong) < 0 { @@ -615,7 +625,11 @@ pub unsafe extern "C" fn freopen( if *new.file == *stream.file { new.file.fd = -1; } else if Sys::dup2(*new.file, *stream.file) < 0 - || fcntl::sys_fcntl(*stream.file, fcntl::F_SETFL, (flags & fcntl::O_CLOEXEC) as c_ulonglong) < 0 + || fcntl::sys_fcntl( + *stream.file, + fcntl::F_SETFL, + (flags & fcntl::O_CLOEXEC) as c_ulonglong, + ) < 0 { funlockfile(stream); fclose(new); diff --git a/src/header/stdlib/mod.rs b/src/header/stdlib/mod.rs index 86b2416a87beaa9cbf1050b33f4f420a4d78e30e..bf290f693deaa5d81d473afbfbfebc3ead5bec3c 100644 --- a/src/header/stdlib/mod.rs +++ b/src/header/stdlib/mod.rs @@ -842,14 +842,11 @@ pub unsafe extern "C" fn realloc(ptr: *mut c_void, size: size_t) -> *mut c_void pub unsafe extern "C" fn reallocarray(ptr: *mut c_void, m: size_t, n: size_t) -> *mut c_void { //Handle possible integer overflow in size calculation match m.checked_mul(n) { - Some(size) => { - realloc(ptr, size) - } + Some(size) => realloc(ptr, size), None => { // For overflowing multiplication, we have to set errno here platform::errno = ENOMEM; ptr::null_mut() - } } } diff --git a/src/header/strings/mod.rs b/src/header/strings/mod.rs index dcf6266685f8f789027240c89d52ea3eb9dea80a..e501861fea1389357a9a63599e5efca009fb796c 100644 --- a/src/header/strings/mod.rs +++ b/src/header/strings/mod.rs @@ -1,7 +1,6 @@ //! strings implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/strings.h.html -use core::ptr; -use core::arch; +use core::{arch, ptr}; use crate::{ header::{ctype, string}, diff --git a/src/header/sys_ioctl/redox.rs b/src/header/sys_ioctl/redox.rs index a62dff15a78eaa0347291d638545d78f2148235f..856dd63c84888e4d0b0466daad7c85f063491950 100644 --- a/src/header/sys_ioctl/redox.rs +++ b/src/header/sys_ioctl/redox.rs @@ -135,12 +135,8 @@ pub unsafe extern "C" fn ioctl(fd: c_int, request: c_ulong, out: *mut c_void) -> 0 } } - TIOCGPTLCK => { - 0 - }, - TIOCSPTLCK => { - 0 - }, + TIOCGPTLCK => 0, + TIOCSPTLCK => 0, TCSBRK => { // TODO 0 diff --git a/src/header/sys_resource/mod.rs b/src/header/sys_resource/mod.rs index ffe4d2a60806684f579cd8e4e533105df69b6f26..e62bb67eabc8efa032c3d837b8fd8c90bf59d4f3 100644 --- a/src/header/sys_resource/mod.rs +++ b/src/header/sys_resource/mod.rs @@ -67,16 +67,16 @@ pub const PRIO_USER: c_int = 2; #[no_mangle] pub unsafe extern "C" fn getpriority(which: c_int, who: id_t) -> c_int { - let r = Sys::getpriority(which, who); - if r < 0 { - return r - } - 20-r + let r = Sys::getpriority(which, who); + if r < 0 { + return r; + } + 20 - r } #[no_mangle] pub unsafe extern "C" fn setpriority(which: c_int, who: id_t, nice: c_int) -> c_int { - Sys::setpriority(which, who, nice) + Sys::setpriority(which, who, nice) } #[no_mangle] diff --git a/src/header/termios/mod.rs b/src/header/termios/mod.rs index 9c8bb7bd36d426caa56b35dd36599e102f804c93..d8fd118e508deb21098d52ac18e9a50dc91f18a6 100644 --- a/src/header/termios/mod.rs +++ b/src/header/termios/mod.rs @@ -180,10 +180,10 @@ pub unsafe extern "C" fn tcflow(fd: c_int, action: c_int) -> c_int { #[no_mangle] pub unsafe extern "C" fn cfmakeraw(termios_p: *mut termios) { - (*termios_p).c_iflag &= !(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|IXON) as u32; + (*termios_p).c_iflag &= !(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | IXON) as u32; (*termios_p).c_oflag &= !OPOST as u32; - (*termios_p).c_lflag &= !(ECHO|ECHONL|ICANON|ISIG|IEXTEN) as u32; - (*termios_p).c_cflag &= !(CSIZE|PARENB) as u32; + (*termios_p).c_lflag &= !(ECHO | ECHONL | ICANON | ISIG | IEXTEN) as u32; + (*termios_p).c_cflag &= !(CSIZE | PARENB) as u32; (*termios_p).c_cflag |= CS8 as u32; (*termios_p).c_cc[VMIN] = 1; (*termios_p).c_cc[VTIME] = 0; diff --git a/src/header/time/mod.rs b/src/header/time/mod.rs index 8074dc9140b08cc0a02c4544e62300137a8915db..9767584065daea71c6a10c1848ac8c8afe0c7ec6 100644 --- a/src/header/time/mod.rs +++ b/src/header/time/mod.rs @@ -94,16 +94,34 @@ pub struct TzName { unsafe impl Sync for TzName {} -static mut TZ_STD: [c_char; 8] = [b'U' as c_char, b'T' as c_char, b'C' as c_char, 0, 0, 0, 0, 0]; -static mut TZ_DST: [c_char; 8] = [b'U' as c_char, b'T' as c_char, b'C' as c_char, 0, 0, 0, 0, 0]; +static mut TZ_STD: [c_char; 8] = [ + b'U' as c_char, + b'T' as c_char, + b'C' as c_char, + 0, + 0, + 0, + 0, + 0, +]; +static mut TZ_DST: [c_char; 8] = [ + b'U' as c_char, + b'T' as c_char, + b'C' as c_char, + 0, + 0, + 0, + 0, + 0, +]; #[allow(non_upper_case_globals)] #[no_mangle] pub static mut tzname: TzName = TzName { - tz: [ - unsafe { TZ_DST.as_mut_ptr() }, - unsafe { TZ_DST.as_mut_ptr() }, - ] }; + tz: [unsafe { TZ_DST.as_mut_ptr() }, unsafe { + TZ_DST.as_mut_ptr() + }], +}; #[allow(non_upper_case_globals)] #[no_mangle] diff --git a/src/header/unistd/mod.rs b/src/header/unistd/mod.rs index cfe2fc53ceefbc6fbc7176fc7d369e9a3dfbfa88..67b8370031e31a13b3eda4d7d2f81b0da01db983 100644 --- a/src/header/unistd/mod.rs +++ b/src/header/unistd/mod.rs @@ -5,8 +5,8 @@ use core::{convert::TryFrom, mem, ptr, slice}; use crate::{ c_str::CStr, header::{ - errno, fcntl, limits, stdlib::getenv, sys_ioctl, sys_resource, sys_time, sys_utsname, termios, - time::timespec, + errno, fcntl, limits, stdlib::getenv, sys_ioctl, sys_resource, sys_time, sys_utsname, + termios, time::timespec, }, platform::{self, types::*, Pal, Sys}, }; @@ -290,12 +290,17 @@ pub extern "C" fn getcwd(mut buf: *mut c_char, mut size: size_t) -> *mut c_char #[no_mangle] pub extern "C" fn getdtablesize() -> c_int { let mut lim = mem::MaybeUninit::<sys_resource::rlimit>::uninit(); - let r = unsafe { sys_resource::getrlimit(sys_resource::RLIMIT_NOFILE as c_int, lim.as_mut_ptr() as *mut sys_resource::rlimit) }; + let r = unsafe { + sys_resource::getrlimit( + sys_resource::RLIMIT_NOFILE as c_int, + lim.as_mut_ptr() as *mut sys_resource::rlimit, + ) + }; if r == 0 { let cur = unsafe { lim.assume_init() }.rlim_cur; match cur { c if c < i32::MAX as u64 => c as i32, - _ => i32::MAX + _ => i32::MAX, }; } -1 @@ -472,21 +477,21 @@ pub unsafe extern "C" fn lockf(fildes: c_int, function: c_int, size: off_t) -> c } platform::errno = errno::EACCES; return -1; - }, + } fcntl::F_ULOCK => { fl.l_type = fcntl::F_UNLCK as c_short; return fcntl::sys_fcntl(fildes, fcntl::F_SETLK, &mut fl as *mut _ as c_ulonglong); - }, + } fcntl::F_TLOCK => { return fcntl::sys_fcntl(fildes, fcntl::F_SETLK, &mut fl as *mut _ as c_ulonglong); - }, + } fcntl::F_LOCK => { return fcntl::sys_fcntl(fildes, fcntl::F_SETLKW, &mut fl as *mut _ as c_ulonglong); - }, + } _ => { platform::errno = errno::EINVAL; return -1; - }, + } }; } diff --git a/src/header/wchar/mod.rs b/src/header/wchar/mod.rs index 072f2b5f2cb9b3521778922087f025b8f751f99d..cc8eb4f7bf62adaeba68e41d7137c53a2e938a3a 100644 --- a/src/header/wchar/mod.rs +++ b/src/header/wchar/mod.rs @@ -245,7 +245,7 @@ pub unsafe extern "C" fn ungetwc(wc: wint_t, stream: &mut FILE) -> wint_t { for i in 0..amount { ungetc(bytes[i] as c_int, &mut *stream); } - + wc } @@ -340,7 +340,6 @@ pub unsafe extern "C" fn wcsrtombs( s = s.offset(l as isize); n = n.wrapping_sub(l); } else { - let new_s = s; s = s.offset(1); *new_s = **ws as c_char; diff --git a/src/ld_so/src/lib.rs b/src/ld_so/src/lib.rs index 1339e5846b8e2d76509dfaddf580597ba06740ef..748f337da8076b359c2ce4e0df0d23fb518c63e6 100644 --- a/src/ld_so/src/lib.rs +++ b/src/ld_so/src/lib.rs @@ -4,17 +4,20 @@ use core::arch::global_asm; #[cfg(target_arch = "aarch64")] -global_asm!(" +global_asm!( + " .globl _start _start: mov x0, sp bl relibc_ld_so_start # TODO: aarch64 udf #0 -"); +" +); #[cfg(target_arch = "x86")] -global_asm!(" +global_asm!( + " .globl _start _start: push esp @@ -22,10 +25,12 @@ _start: pop esp # TODO: x86 ud2 -"); +" +); #[cfg(target_arch = "x86_64")] -global_asm!(" +global_asm!( + " .globl _start _start: # rsi = _start + 5 @@ -53,7 +58,8 @@ _start: xor r11, r11 fninit jmp rax -"); +" +); #[no_mangle] pub unsafe extern "C" fn main(_argc: isize, _argv: *const *const i8) -> usize { diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index fa5e770b23966b3be4ad8656bc85a790f280da25..857cda4544fb22114630c9f445307601153c90b0 100644 --- a/src/platform/linux/mod.rs +++ b/src/platform/linux/mod.rs @@ -234,8 +234,15 @@ impl Pal for Sys { e(unsafe { syscall!(FTRUNCATE, fildes, length) }) as c_int } - fn futex(addr: *mut c_int, op: c_int, val: c_int, val2: usize) -> Result<c_long, crate::pthread::Errno> { - e_raw(unsafe { syscall!(FUTEX, addr, op, val, val2, 0, 0)}).map(|r| r as c_long).map_err(|e| crate::pthread::Errno(e as c_int)) + fn futex( + addr: *mut c_int, + op: c_int, + val: c_int, + val2: usize, + ) -> Result<c_long, crate::pthread::Errno> { + e_raw(unsafe { syscall!(FUTEX, addr, op, val, val2, 0, 0) }) + .map(|r| r as c_long) + .map_err(|e| crate::pthread::Errno(e as c_int)) } fn futimens(fd: c_int, times: *const timespec) -> c_int { @@ -403,7 +410,9 @@ impl Pal for Sys { } #[cfg(target_arch = "x86_64")] - unsafe fn rlct_clone(stack: *mut usize) -> Result<crate::pthread::OsTid, crate::pthread::Errno> { + unsafe fn rlct_clone( + stack: *mut usize, + ) -> Result<crate::pthread::OsTid, crate::pthread::Errno> { let flags = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD; let pid; asm!(" @@ -456,9 +465,14 @@ impl Pal for Sys { Ok(crate::pthread::OsTid { thread_id: tid }) } - unsafe fn rlct_kill(os_tid: crate::pthread::OsTid, signal: usize) -> Result<(), crate::pthread::Errno> { + unsafe fn rlct_kill( + os_tid: crate::pthread::OsTid, + signal: usize, + ) -> Result<(), crate::pthread::Errno> { let tgid = Self::getpid(); - e_raw(unsafe { syscall!(TGKILL, tgid, os_tid.thread_id, signal) }).map(|_| ()).map_err(|err| crate::pthread::Errno(err as c_int)) + e_raw(unsafe { syscall!(TGKILL, tgid, os_tid.thread_id, signal) }) + .map(|_| ()) + .map_err(|err| crate::pthread::Errno(err as c_int)) } fn current_os_tid() -> crate::pthread::OsTid { crate::pthread::OsTid { diff --git a/src/platform/linux/signal.rs b/src/platform/linux/signal.rs index d12cf8b800c1f0433b5d00c8561aa9ee11b34370..3be256bba7b1d639ecb3d0e7df537d9df0a5a7df 100644 --- a/src/platform/linux/signal.rs +++ b/src/platform/linux/signal.rs @@ -5,7 +5,7 @@ use super::{ e, Sys, }; use crate::header::{ - signal::{NSIG, sigaction, siginfo_t, sigset_t, stack_t}, + signal::{sigaction, siginfo_t, sigset_t, stack_t, NSIG}, sys_time::itimerval, time::timespec, }; @@ -53,7 +53,7 @@ impl PalSignal for Sys { } fn sigpending(set: *mut sigset_t) -> c_int { - e(unsafe { syscall!(RT_SIGPENDING, set, NSIG/8) }) as c_int + e(unsafe { syscall!(RT_SIGPENDING, set, NSIG / 8) }) as c_int } fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int { @@ -61,10 +61,10 @@ impl PalSignal for Sys { } fn sigsuspend(set: *const sigset_t) -> c_int { - e(unsafe { syscall!(RT_SIGSUSPEND, set, NSIG/8) }) as c_int + e(unsafe { syscall!(RT_SIGSUSPEND, set, NSIG / 8) }) as c_int } fn sigtimedwait(set: *const sigset_t, sig: *mut siginfo_t, tp: *const timespec) -> c_int { - e(unsafe { syscall!(RT_SIGTIMEDWAIT, set, sig, tp, NSIG/8) }) as c_int + e(unsafe { syscall!(RT_SIGTIMEDWAIT, set, sig, tp, NSIG / 8) }) as c_int } } diff --git a/src/platform/pal/mod.rs b/src/platform/pal/mod.rs index 2f78c777190eaac1e7f7d718066b6d0c961923e2..3d6a690454cb4f0b3a4d3ab71f22bf1b9dabc2ee 100644 --- a/src/platform/pal/mod.rs +++ b/src/platform/pal/mod.rs @@ -77,7 +77,12 @@ pub trait Pal { fn ftruncate(fildes: c_int, length: off_t) -> c_int; - fn futex(addr: *mut c_int, op: c_int, val: c_int, val2: usize) -> Result<c_long, crate::pthread::Errno>; + fn futex( + addr: *mut c_int, + op: c_int, + val: c_int, + val2: usize, + ) -> Result<c_long, crate::pthread::Errno>; fn futimens(fd: c_int, times: *const timespec) -> c_int; @@ -161,8 +166,12 @@ pub trait Pal { fn pipe2(fildes: &mut [c_int], flags: c_int) -> c_int; - unsafe fn rlct_clone(stack: *mut usize) -> Result<crate::pthread::OsTid, crate::pthread::Errno>; - unsafe fn rlct_kill(os_tid: crate::pthread::OsTid, signal: usize) -> Result<(), crate::pthread::Errno>; + unsafe fn rlct_clone(stack: *mut usize) + -> Result<crate::pthread::OsTid, crate::pthread::Errno>; + unsafe fn rlct_kill( + os_tid: crate::pthread::OsTid, + signal: usize, + ) -> Result<(), crate::pthread::Errno>; fn current_os_tid() -> crate::pthread::OsTid; fn read(fildes: c_int, buf: &mut [u8]) -> ssize_t; diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index 5e09657f7868e89292775c704907f55626165719..767b94b72dd64f2492b29f9ba2c55e60f419fd68 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -345,7 +345,12 @@ impl Pal for Sys { e(syscall::ftruncate(fd as usize, len as usize)) as c_int } - fn futex(addr: *mut c_int, op: c_int, val: c_int, val2: usize) -> Result<c_long, crate::pthread::Errno> { + fn futex( + addr: *mut c_int, + op: c_int, + val: c_int, + val2: usize, + ) -> Result<c_long, crate::pthread::Errno> { match unsafe { syscall::futex( addr as *mut i32, @@ -770,16 +775,26 @@ impl Pal for Sys { res as c_int } - unsafe fn rlct_clone(stack: *mut usize) -> Result<crate::pthread::OsTid, crate::pthread::Errno> { - clone::rlct_clone_impl(stack).map(|context_id| crate::pthread::OsTid { context_id }).map_err(|error| crate::pthread::Errno(error.errno)) + unsafe fn rlct_clone( + stack: *mut usize, + ) -> Result<crate::pthread::OsTid, crate::pthread::Errno> { + clone::rlct_clone_impl(stack) + .map(|context_id| crate::pthread::OsTid { context_id }) + .map_err(|error| crate::pthread::Errno(error.errno)) } - unsafe fn rlct_kill(os_tid: crate::pthread::OsTid, signal: usize) -> Result<(), crate::pthread::Errno> { - syscall::kill(os_tid.context_id, signal).map_err(|error| crate::pthread::Errno(error.errno))?; + unsafe fn rlct_kill( + os_tid: crate::pthread::OsTid, + signal: usize, + ) -> Result<(), crate::pthread::Errno> { + syscall::kill(os_tid.context_id, signal) + .map_err(|error| crate::pthread::Errno(error.errno))?; Ok(()) } fn current_os_tid() -> crate::pthread::OsTid { // TODO - crate::pthread::OsTid { context_id: Self::getpid() as _ } + crate::pthread::OsTid { + context_id: Self::getpid() as _, + } } fn read(fd: c_int, buf: &mut [u8]) -> ssize_t { diff --git a/src/platform/redox/redox-exec/src/arch/aarch64.rs b/src/platform/redox/redox-exec/src/arch/aarch64.rs index 274d07bfcdcab9dc7fd57f3218ff28367d0ac0b8..db88101128e9ceaec569bee95b5933eab787a505 100644 --- a/src/platform/redox/redox-exec/src/arch/aarch64.rs +++ b/src/platform/redox/redox-exec/src/arch/aarch64.rs @@ -1,6 +1,6 @@ use syscall::error::*; -use crate::{FdGuard, fork_inner}; +use crate::{fork_inner, FdGuard}; // Setup a stack starting from the very end of the address space, and then growing downwards. pub(crate) const STACK_TOP: usize = 1 << 47; @@ -44,7 +44,8 @@ unsafe extern "C" fn __relibc_internal_fork_hook(cur_filetable_fd: usize, new_pi let _ = syscall::close(new_pid_fd); } -core::arch::global_asm!(" +core::arch::global_asm!( + " .p2align 6 .globl __relibc_internal_fork_wrapper .type __relibc_internal_fork_wrapper, @function diff --git a/src/platform/redox/redox-exec/src/arch/x86.rs b/src/platform/redox/redox-exec/src/arch/x86.rs index 0f84b8e05690c1e69b30157a70e502cd5930db09..c6addedb38e0a50b2ba692b3adbdc19c321dd1b9 100644 --- a/src/platform/redox/redox-exec/src/arch/x86.rs +++ b/src/platform/redox/redox-exec/src/arch/x86.rs @@ -1,6 +1,6 @@ use syscall::error::*; -use crate::{FdGuard, fork_inner}; +use crate::{fork_inner, FdGuard}; // Setup a stack starting from the very end of the address space, and then growing downwards. pub(crate) const STACK_TOP: usize = 1 << 31; @@ -46,7 +46,8 @@ unsafe extern "cdecl" fn __relibc_internal_fork_hook(cur_filetable_fd: usize, ne } //TODO: x86 -core::arch::global_asm!(" +core::arch::global_asm!( + " .p2align 6 .globl __relibc_internal_fork_wrapper .type __relibc_internal_fork_wrapper, @function diff --git a/src/platform/redox/redox-exec/src/arch/x86_64.rs b/src/platform/redox/redox-exec/src/arch/x86_64.rs index 69e61aa7bb0bd673f1193935f07ec6ad81116f6d..17aef4568134fac53d2b35be8368efad7920d928 100644 --- a/src/platform/redox/redox-exec/src/arch/x86_64.rs +++ b/src/platform/redox/redox-exec/src/arch/x86_64.rs @@ -1,6 +1,6 @@ use syscall::error::*; -use crate::{FdGuard, fork_inner}; +use crate::{fork_inner, FdGuard}; // Setup a stack starting from the very end of the address space, and then growing downwards. pub(crate) const STACK_TOP: usize = 1 << 47; @@ -45,7 +45,8 @@ unsafe extern "sysv64" fn __relibc_internal_fork_hook(cur_filetable_fd: usize, n let _ = syscall::close(new_pid_fd); } -core::arch::global_asm!(" +core::arch::global_asm!( + " .p2align 6 .globl __relibc_internal_fork_wrapper .type __relibc_internal_fork_wrapper, @function diff --git a/src/platform/redox/redox-exec/src/lib.rs b/src/platform/redox/redox-exec/src/lib.rs index a62e5017c54ee24f168107e13d95d9d845f65f90..768dfa681410ef51179f3c97158e11f12c2ba2e9 100644 --- a/src/platform/redox/redox-exec/src/lib.rs +++ b/src/platform/redox/redox-exec/src/lib.rs @@ -1,36 +1,43 @@ #![no_std] - #![feature(array_chunks, map_first_last)] extern crate alloc; use core::mem::size_of; -use alloc::{ - boxed::Box, - collections::BTreeMap, - vec, -}; +use alloc::{boxed::Box, collections::BTreeMap, vec}; //TODO: allow use of either 32-bit or 64-bit programs #[cfg(target_pointer_width = "32")] -use goblin::elf32::{header::Header, program_header::program_header32::{ProgramHeader, PT_LOAD, PT_INTERP, PF_W, PF_X}}; +use goblin::elf32::{ + header::Header, + program_header::program_header32::{ProgramHeader, PF_W, PF_X, PT_INTERP, PT_LOAD}, +}; #[cfg(target_pointer_width = "64")] -use goblin::elf64::{header::Header, program_header::program_header64::{ProgramHeader, PT_LOAD, PT_INTERP, PF_W, PF_X}}; - +use goblin::elf64::{ + header::Header, + program_header::program_header64::{ProgramHeader, PF_W, PF_X, PT_INTERP, PT_LOAD}, +}; use syscall::{ - PAGE_SIZE, error::*, flag::{MapFlags, SEEK_SET}, + PAGE_SIZE, }; pub use self::arch::*; mod arch; pub enum FexecResult { - Normal { addrspace_handle: FdGuard }, - Interp { path: Box<[u8]>, image_file: FdGuard, open_via_dup: FdGuard, interp_override: InterpOverride }, + Normal { + addrspace_handle: FdGuard, + }, + Interp { + path: Box<[u8]>, + image_file: FdGuard, + open_via_dup: FdGuard, + interp_override: InterpOverride, + }, } pub struct InterpOverride { phs: Box<[u8]>, @@ -45,7 +52,17 @@ pub struct ExtraInfo<'a> { pub cwd: Option<&'a [u8]>, } -pub fn fexec_impl<A, E>(image_file: FdGuard, open_via_dup: FdGuard, memory_scheme_fd: &FdGuard, path: &[u8], args: A, envs: E, total_args_envs_size: usize, extrainfo: &ExtraInfo, mut interp_override: Option<InterpOverride>) -> Result<FexecResult> +pub fn fexec_impl<A, E>( + image_file: FdGuard, + open_via_dup: FdGuard, + memory_scheme_fd: &FdGuard, + path: &[u8], + args: A, + envs: E, + total_args_envs_size: usize, + extrainfo: &ExtraInfo, + mut interp_override: Option<InterpOverride>, +) -> Result<FexecResult> where A: IntoIterator, E: IntoIterator, @@ -71,28 +88,33 @@ where const MAX_PH_SIZE: usize = 1024 * 1024; let phentsize = u64::from(header.e_phentsize) as usize; let phnum = u64::from(header.e_phnum) as usize; - let pheaders_size = phentsize.saturating_mul(phnum).saturating_add(size_of::<Header>()); + let pheaders_size = phentsize + .saturating_mul(phnum) + .saturating_add(size_of::<Header>()); if pheaders_size > MAX_PH_SIZE { return Err(Error::new(E2BIG)); } - let mut phs_raw = vec! [0_u8; pheaders_size]; + let mut phs_raw = vec![0_u8; pheaders_size]; phs_raw[..size_of::<Header>()].copy_from_slice(&header_bytes); let phs = &mut phs_raw[size_of::<Header>()..]; // TODO: Remove clone, but this would require more as_refs and as_muts - let mut tree = interp_override.as_mut().map_or_else(|| { - core::iter::once((0, PAGE_SIZE)).collect::<BTreeMap<_, _>>() - }, |o| core::mem::take(&mut o.tree)); + let mut tree = interp_override.as_mut().map_or_else( + || core::iter::once((0, PAGE_SIZE)).collect::<BTreeMap<_, _>>(), + |o| core::mem::take(&mut o.tree), + ); const BUFSZ: usize = 1024 * 256; - let mut buf = vec! [0_u8; BUFSZ]; + let mut buf = vec![0_u8; BUFSZ]; - read_all(*image_file as usize, Some(header.e_phoff as u64), phs).map_err(|_| Error::new(EIO))?; + read_all(*image_file as usize, Some(header.e_phoff as u64), phs) + .map_err(|_| Error::new(EIO))?; for ph_idx in 0..phnum { let ph_bytes = &phs[ph_idx * phentsize..(ph_idx + 1) * phentsize]; - let segment: &ProgramHeader = plain::from_bytes(ph_bytes).map_err(|_| Error::new(EINVAL))?; + let segment: &ProgramHeader = + plain::from_bytes(ph_bytes).map_err(|_| Error::new(EINVAL))?; let mut flags = syscall::PROT_READ; // W ^ X. If it is executable, do not allow it to be writable, even if requested @@ -104,8 +126,7 @@ where let voff = segment.p_vaddr as usize % PAGE_SIZE; let vaddr = segment.p_vaddr as usize - voff; - let size = - (segment.p_memsz as usize + voff + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE; + let size = (segment.p_memsz as usize + voff + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE; if segment.p_filesz > segment.p_memsz { return Err(Error::new(ENOEXEC)); @@ -114,8 +135,12 @@ where match segment.p_type { // PT_INTERP must come before any PT_LOAD, so we don't have to iterate twice. PT_INTERP => { - let mut interp = vec! [0_u8; segment.p_filesz as usize]; - read_all(*image_file as usize, Some(segment.p_offset as u64), &mut interp)?; + let mut interp = vec![0_u8; segment.p_filesz as usize]; + read_all( + *image_file as usize, + Some(segment.p_offset as u64), + &mut interp, + )?; return Ok(FexecResult::Interp { path: interp.into_boxed_slice(), @@ -128,21 +153,39 @@ where phs: phs_raw.into_boxed_slice(), name: path.into(), tree, - } + }, }); } PT_LOAD => { - allocate_remote(&grants_fd, memory_scheme_fd, vaddr, size, syscall::PROT_READ | syscall::PROT_WRITE)?; - syscall::lseek(*image_file as usize, segment.p_offset as isize, SEEK_SET).map_err(|_| Error::new(EIO))?; - syscall::lseek(*memory_fd, segment.p_vaddr as isize, SEEK_SET).map_err(|_| Error::new(EIO))?; - - for size in core::iter::repeat(buf.len()).take((segment.p_filesz as usize) / buf.len()).chain(Some((segment.p_filesz as usize) % buf.len())) { - read_all(*image_file as usize, None, &mut buf[..size]).map_err(|_| Error::new(EIO))?; - let _ = syscall::write(*memory_fd, &buf[..size]).map_err(|_| Error::new(EIO))?; + allocate_remote( + &grants_fd, + memory_scheme_fd, + vaddr, + size, + syscall::PROT_READ | syscall::PROT_WRITE, + )?; + syscall::lseek(*image_file as usize, segment.p_offset as isize, SEEK_SET) + .map_err(|_| Error::new(EIO))?; + syscall::lseek(*memory_fd, segment.p_vaddr as isize, SEEK_SET) + .map_err(|_| Error::new(EIO))?; + + for size in core::iter::repeat(buf.len()) + .take((segment.p_filesz as usize) / buf.len()) + .chain(Some((segment.p_filesz as usize) % buf.len())) + { + read_all(*image_file as usize, None, &mut buf[..size]) + .map_err(|_| Error::new(EIO))?; + let _ = + syscall::write(*memory_fd, &buf[..size]).map_err(|_| Error::new(EIO))?; } mprotect_remote(&grants_fd, vaddr, size, flags)?; - if !tree.range(..=vaddr).next_back().filter(|(start, size)| **start + **size > vaddr).is_some() { + if !tree + .range(..=vaddr) + .next_back() + .filter(|(start, size)| **start + **size > vaddr) + .is_some() + { tree.insert(vaddr, size); } } @@ -150,7 +193,13 @@ where } } - allocate_remote(&grants_fd, memory_scheme_fd, STACK_TOP - STACK_SIZE, STACK_SIZE, MapFlags::PROT_READ | MapFlags::PROT_WRITE)?; + allocate_remote( + &grants_fd, + memory_scheme_fd, + STACK_TOP - STACK_SIZE, + STACK_SIZE, + MapFlags::PROT_READ | MapFlags::PROT_WRITE, + )?; tree.insert(STACK_TOP - STACK_SIZE, STACK_SIZE); let mut sp = STACK_TOP - 256; @@ -165,12 +214,23 @@ where } else { &*phs_raw }; - let pheaders_size_aligned = (pheaders_to_convey.len()+PAGE_SIZE-1)/PAGE_SIZE*PAGE_SIZE; + let pheaders_size_aligned = (pheaders_to_convey.len() + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE; let pheaders = find_free_target_addr(&tree, pheaders_size_aligned).ok_or(Error::new(ENOMEM))?; tree.insert(pheaders, pheaders_size_aligned); - allocate_remote(&grants_fd, memory_scheme_fd, pheaders, pheaders_size_aligned, MapFlags::PROT_READ | MapFlags::PROT_WRITE)?; + allocate_remote( + &grants_fd, + memory_scheme_fd, + pheaders, + pheaders_size_aligned, + MapFlags::PROT_READ | MapFlags::PROT_WRITE, + )?; write_all(*memory_fd, Some(pheaders as u64), &pheaders_to_convey)?; - mprotect_remote(&grants_fd, pheaders, pheaders_size_aligned, MapFlags::PROT_READ)?; + mprotect_remote( + &grants_fd, + pheaders, + pheaders_size_aligned, + MapFlags::PROT_READ, + )?; push(0)?; push(AT_NULL)?; @@ -182,15 +242,32 @@ where push(AT_ENTRY)?; push(pheaders + size_of::<Header>())?; push(AT_PHDR)?; - push(interp_override.as_ref().map_or(header.e_phnum as usize, |o| o.at_phnum))?; + push( + interp_override + .as_ref() + .map_or(header.e_phnum as usize, |o| o.at_phnum), + )?; push(AT_PHNUM)?; - push(interp_override.as_ref().map_or(header.e_phentsize as usize, |o| o.at_phent))?; + push( + interp_override + .as_ref() + .map_or(header.e_phentsize as usize, |o| o.at_phent), + )?; push(AT_PHENT)?; - let total_args_envs_auxvpointee_size = total_args_envs_size + extrainfo.cwd.map_or(0, |s| s.len() + 1); - let args_envs_size_aligned = (total_args_envs_auxvpointee_size+PAGE_SIZE-1)/PAGE_SIZE*PAGE_SIZE; - let target_args_env_address = find_free_target_addr(&tree, args_envs_size_aligned).ok_or(Error::new(ENOMEM))?; - allocate_remote(&grants_fd, memory_scheme_fd, target_args_env_address, args_envs_size_aligned, MapFlags::PROT_READ | MapFlags::PROT_WRITE)?; + let total_args_envs_auxvpointee_size = + total_args_envs_size + extrainfo.cwd.map_or(0, |s| s.len() + 1); + let args_envs_size_aligned = + (total_args_envs_auxvpointee_size + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE; + let target_args_env_address = + find_free_target_addr(&tree, args_envs_size_aligned).ok_or(Error::new(ENOMEM))?; + allocate_remote( + &grants_fd, + memory_scheme_fd, + target_args_env_address, + args_envs_size_aligned, + MapFlags::PROT_READ | MapFlags::PROT_WRITE, + )?; tree.insert(target_args_env_address, args_envs_size_aligned); let mut offset = 0; @@ -228,14 +305,20 @@ where push(argc)?; - unsafe { deactivate_tcb(*open_via_dup)?; } + unsafe { + deactivate_tcb(*open_via_dup)?; + } { let current_sigaction_fd = FdGuard::new(syscall::dup(*open_via_dup, b"sigactions")?); let empty_sigaction_fd = FdGuard::new(syscall::dup(*current_sigaction_fd, b"empty")?); - let sigaction_selection_fd = FdGuard::new(syscall::dup(*open_via_dup, b"current-sigactions")?); + let sigaction_selection_fd = + FdGuard::new(syscall::dup(*open_via_dup, b"current-sigactions")?); - let _ = syscall::write(*sigaction_selection_fd, &usize::to_ne_bytes(*empty_sigaction_fd))?; + let _ = syscall::write( + *sigaction_selection_fd, + &usize::to_ne_bytes(*empty_sigaction_fd), + )?; } // TODO: Restore old name if exec failed? @@ -251,70 +334,112 @@ where let addrspace_selection_fd = FdGuard::new(syscall::dup(*open_via_dup, b"current-addrspace")?); - let _ = syscall::write(*addrspace_selection_fd, &create_set_addr_space_buf(*grants_fd, header.e_entry as usize, sp)); + let _ = syscall::write( + *addrspace_selection_fd, + &create_set_addr_space_buf(*grants_fd, header.e_entry as usize, sp), + ); - Ok(FexecResult::Normal { addrspace_handle: addrspace_selection_fd }) + Ok(FexecResult::Normal { + addrspace_handle: addrspace_selection_fd, + }) } fn write_usizes<const N: usize>(fd: &FdGuard, usizes: [usize; N]) -> Result<()> { let _ = syscall::write(**fd, unsafe { plain::as_bytes(&usizes) }); Ok(()) } -fn allocate_remote(addrspace_fd: &FdGuard, memory_scheme_fd: &FdGuard, dst_addr: usize, len: usize, flags: MapFlags) -> Result<()> { +fn allocate_remote( + addrspace_fd: &FdGuard, + memory_scheme_fd: &FdGuard, + dst_addr: usize, + len: usize, + flags: MapFlags, +) -> Result<()> { mmap_remote(addrspace_fd, memory_scheme_fd, 0, dst_addr, len, flags) } -pub fn mmap_remote(addrspace_fd: &FdGuard, fd: &FdGuard, offset: usize, dst_addr: usize, len: usize, flags: MapFlags) -> Result<()> { - write_usizes(addrspace_fd, [ - // op - syscall::flag::ADDRSPACE_OP_MMAP, - // fd - **fd, - // "offset" - offset, - // address - dst_addr, - // size - len, - // flags - (flags | MapFlags::MAP_FIXED_NOREPLACE).bits(), - ]) +pub fn mmap_remote( + addrspace_fd: &FdGuard, + fd: &FdGuard, + offset: usize, + dst_addr: usize, + len: usize, + flags: MapFlags, +) -> Result<()> { + write_usizes( + addrspace_fd, + [ + // op + syscall::flag::ADDRSPACE_OP_MMAP, + // fd + **fd, + // "offset" + offset, + // address + dst_addr, + // size + len, + // flags + (flags | MapFlags::MAP_FIXED_NOREPLACE).bits(), + ], + ) } -pub fn mprotect_remote(addrspace_fd: &FdGuard, addr: usize, len: usize, flags: MapFlags) -> Result<()> { - write_usizes(addrspace_fd, [ - // op - syscall::flag::ADDRSPACE_OP_MPROTECT, - // address - addr, - // size - len, - // flags - flags.bits(), - ]) +pub fn mprotect_remote( + addrspace_fd: &FdGuard, + addr: usize, + len: usize, + flags: MapFlags, +) -> Result<()> { + write_usizes( + addrspace_fd, + [ + // op + syscall::flag::ADDRSPACE_OP_MPROTECT, + // address + addr, + // size + len, + // flags + flags.bits(), + ], + ) } pub fn munmap_remote(addrspace_fd: &FdGuard, addr: usize, len: usize) -> Result<()> { - write_usizes(addrspace_fd, [ - // op - syscall::flag::ADDRSPACE_OP_MUNMAP, - // address - addr, - // size - len, - ]) + write_usizes( + addrspace_fd, + [ + // op + syscall::flag::ADDRSPACE_OP_MUNMAP, + // address + addr, + // size + len, + ], + ) } -pub fn munmap_transfer(src: &FdGuard, dst: &FdGuard, src_addr: usize, dst_addr: usize, len: usize, flags: MapFlags) -> Result<()> { - write_usizes(dst, [ - // op - syscall::flag::ADDRSPACE_OP_TRANSFER, - // fd - **src, - // "offset" (source address) - src_addr, - // address - dst_addr, - // size - len, - // flags - (flags | MapFlags::MAP_FIXED_NOREPLACE).bits(), - ]) +pub fn munmap_transfer( + src: &FdGuard, + dst: &FdGuard, + src_addr: usize, + dst_addr: usize, + len: usize, + flags: MapFlags, +) -> Result<()> { + write_usizes( + dst, + [ + // op + syscall::flag::ADDRSPACE_OP_TRANSFER, + // fd + **src, + // "offset" (source address) + src_addr, + // address + dst_addr, + // size + len, + // flags + (flags | MapFlags::MAP_FIXED_NOREPLACE).bits(), + ], + ) } fn read_all(fd: usize, offset: Option<u64>, buf: &mut [u8]) -> Result<()> { if let Some(offset) = offset { @@ -374,9 +499,7 @@ pub struct FdGuard { } impl FdGuard { pub fn new(fd: usize) -> Self { - Self { - fd, taken: false, - } + Self { fd, taken: false } } pub fn take(&mut self) -> usize { self.taken = true; @@ -398,9 +521,13 @@ impl Drop for FdGuard { } } } -pub fn create_set_addr_space_buf(space: usize, ip: usize, sp: usize) -> [u8; size_of::<usize>() * 3] { +pub fn create_set_addr_space_buf( + space: usize, + ip: usize, + sp: usize, +) -> [u8; size_of::<usize>() * 3] { let mut buf = [0_u8; 3 * size_of::<usize>()]; - let mut chunks = buf.array_chunks_mut::<{size_of::<usize>()}>(); + let mut chunks = buf.array_chunks_mut::<{ size_of::<usize>() }>(); *chunks.next().unwrap() = usize::to_ne_bytes(space); *chunks.next().unwrap() = usize::to_ne_bytes(sp); *chunks.next().unwrap() = usize::to_ne_bytes(ip); @@ -416,16 +543,17 @@ use auxv_defs::*; /// descriptors from other schemes are reobtained with `dup`, and grants referencing such file /// descriptors are reobtained through `fmap`. Other mappings are kept but duplicated using CoW. pub fn fork_impl() -> Result<usize> { - unsafe { - Error::demux(__relibc_internal_fork_wrapper()) - } + unsafe { Error::demux(__relibc_internal_fork_wrapper()) } } fn fork_inner(initial_rsp: *mut usize) -> Result<usize> { let (cur_filetable_fd, new_pid_fd, new_pid); { - let cur_pid_fd = FdGuard::new(syscall::open("thisproc:current/open_via_dup", syscall::O_CLOEXEC)?); + let cur_pid_fd = FdGuard::new(syscall::open( + "thisproc:current/open_via_dup", + syscall::O_CLOEXEC, + )?); (new_pid_fd, new_pid) = new_context()?; // Do not allocate new signal stack, but copy existing address (all memory will be re-mapped @@ -445,9 +573,13 @@ fn fork_inner(initial_rsp: *mut usize) -> Result<usize> { { let cur_sigaction_fd = FdGuard::new(syscall::dup(*cur_pid_fd, b"sigactions")?); let new_sigaction_fd = FdGuard::new(syscall::dup(*cur_sigaction_fd, b"copy")?); - let new_sigaction_sel_fd = FdGuard::new(syscall::dup(*new_pid_fd, b"current-sigactions")?); + let new_sigaction_sel_fd = + FdGuard::new(syscall::dup(*new_pid_fd, b"current-sigactions")?); - let _ = syscall::write(*new_sigaction_sel_fd, &usize::to_ne_bytes(*new_sigaction_fd))?; + let _ = syscall::write( + *new_sigaction_sel_fd, + &usize::to_ne_bytes(*new_sigaction_fd), + )?; } // Copy existing files into new file table, but do not reuse the same file table (i.e. new @@ -470,20 +602,25 @@ fn fork_inner(initial_rsp: *mut usize) -> Result<usize> { let new_addr_space_fd = FdGuard::new(syscall::dup(*cur_addr_space_fd, b"exclusive")?); - let mut buf = vec! [0_u8; 4096]; + let mut buf = vec![0_u8; 4096]; let mut bytes_read = 0; loop { let new_bytes_read = syscall::read(*cur_addr_space_fd, &mut buf[bytes_read..])?; - if new_bytes_read == 0 { break } + if new_bytes_read == 0 { + break; + } bytes_read += new_bytes_read; } let bytes = &buf[..bytes_read]; - for struct_bytes in bytes.array_chunks::<{size_of::<usize>() * 4}>() { - let mut words = struct_bytes.array_chunks::<{size_of::<usize>()}>().copied().map(usize::from_ne_bytes); + for struct_bytes in bytes.array_chunks::<{ size_of::<usize>() * 4 }>() { + let mut words = struct_bytes + .array_chunks::<{ size_of::<usize>() }>() + .copied() + .map(usize::from_ne_bytes); let addr = words.next().unwrap(); let size = words.next().unwrap(); @@ -495,12 +632,20 @@ fn fork_inner(initial_rsp: *mut usize) -> Result<usize> { } let map_flags = MapFlags::from_bits_truncate(flags); - let grant_fd = FdGuard::new(syscall::dup(*cur_addr_space_fd, alloc::format!("grant-{:x}", addr).as_bytes())?); + let grant_fd = FdGuard::new(syscall::dup( + *cur_addr_space_fd, + alloc::format!("grant-{:x}", addr).as_bytes(), + )?); mmap_remote(&new_addr_space_fd, &grant_fd, offset, addr, size, map_flags)?; } - let new_addr_space_sel_fd = FdGuard::new(syscall::dup(*new_pid_fd, b"current-addrspace")?); - - let buf = create_set_addr_space_buf(*new_addr_space_fd, __relibc_internal_fork_ret as usize, initial_rsp as usize); + let new_addr_space_sel_fd = + FdGuard::new(syscall::dup(*new_pid_fd, b"current-addrspace")?); + + let buf = create_set_addr_space_buf( + *new_addr_space_fd, + __relibc_internal_fork_ret as usize, + initial_rsp as usize, + ); let _ = syscall::write(*new_addr_space_sel_fd, &buf)?; } copy_env_regs(*cur_pid_fd, *new_pid_fd)?; @@ -513,7 +658,10 @@ fn fork_inner(initial_rsp: *mut usize) -> Result<usize> { // kernel. let new_filetable_fd = FdGuard::new(syscall::dup(*cur_filetable_fd, b"copy")?); let new_filetable_sel_fd = FdGuard::new(syscall::dup(*new_pid_fd, b"current-filetable")?); - let _ = syscall::write(*new_filetable_sel_fd, &usize::to_ne_bytes(*new_filetable_fd)); + let _ = syscall::write( + *new_filetable_sel_fd, + &usize::to_ne_bytes(*new_filetable_fd), + ); } // Unblock context. @@ -530,16 +678,29 @@ fn fork_inner(initial_rsp: *mut usize) -> Result<usize> { pub fn new_context() -> Result<(FdGuard, usize)> { // Create a new context (fields such as uid/gid will be inherited from the current context). - let fd = FdGuard::new(syscall::open("thisproc:new/open_via_dup", syscall::O_CLOEXEC)?); + let fd = FdGuard::new(syscall::open( + "thisproc:new/open_via_dup", + syscall::O_CLOEXEC, + )?); // Extract pid. let mut buffer = [0_u8; 64]; let len = syscall::fpath(*fd, &mut buffer)?; let buffer = buffer.get(..len).ok_or(Error::new(ENAMETOOLONG))?; - let colon_idx = buffer.iter().position(|c| *c == b':').ok_or(Error::new(EINVAL))?; - let slash_idx = buffer.iter().skip(colon_idx).position(|c| *c == b'/').ok_or(Error::new(EINVAL))? + colon_idx; - let pid_bytes = buffer.get(colon_idx + 1..slash_idx).ok_or(Error::new(EINVAL))?; + let colon_idx = buffer + .iter() + .position(|c| *c == b':') + .ok_or(Error::new(EINVAL))?; + let slash_idx = buffer + .iter() + .skip(colon_idx) + .position(|c| *c == b'/') + .ok_or(Error::new(EINVAL))? + + colon_idx; + let pid_bytes = buffer + .get(colon_idx + 1..slash_idx) + .ok_or(Error::new(EINVAL))?; let pid_str = core::str::from_utf8(pid_bytes).map_err(|_| Error::new(EINVAL))?; let pid = pid_str.parse::<usize>().map_err(|_| Error::new(EINVAL))?; diff --git a/src/platform/types.rs b/src/platform/types.rs index 3a42753b0e8da594f3502f5daadd712bff504357..b7bfa510fe2f1232ec8e70c581deb7cb4a3a72e6 100644 --- a/src/platform/types.rs +++ b/src/platform/types.rs @@ -77,5 +77,4 @@ pub type clock_t = c_long; pub type clockid_t = c_int; pub type timer_t = *mut c_void; -pub use crate::header::bits_pthread::*; -pub use crate::header::bits_sched::*; +pub use crate::header::{bits_pthread::*, bits_sched::*}; diff --git a/src/pthread/mod.rs b/src/pthread/mod.rs index 56b7ec1d55cace65539a15e00f27a7c055c9dc92..99a36251e4c86e3055e826ed00576a2254292f47 100644 --- a/src/pthread/mod.rs +++ b/src/pthread/mod.rs @@ -1,22 +1,24 @@ //! Relibc Threads, or RLCT. -use core::cell::{Cell, UnsafeCell}; -use core::ptr::NonNull; -use core::sync::atomic::{AtomicBool, AtomicU32, AtomicUsize, Ordering}; - -use alloc::boxed::Box; -use alloc::collections::BTreeMap; -use alloc::vec::Vec; - -use crate::platform::{Pal, Sys, types::*}; -use crate::header::sched::sched_param; -use crate::header::errno::*; -use crate::header::sys_mman; -use crate::header::pthread as header; -use crate::ld_so::{linker::Linker, tcb::{Master, Tcb}}; -use crate::ALLOCATOR; - -use crate::sync::{Mutex, waitval::Waitval}; +use core::{ + cell::{Cell, UnsafeCell}, + ptr::NonNull, + sync::atomic::{AtomicBool, AtomicU32, AtomicUsize, Ordering}, +}; + +use alloc::{boxed::Box, collections::BTreeMap, vec::Vec}; + +use crate::{ + header::{errno::*, pthread as header, sched::sched_param, sys_mman}, + ld_so::{ + linker::Linker, + tcb::{Master, Tcb}, + }, + platform::{types::*, Pal, Sys}, + ALLOCATOR, +}; + +use crate::sync::{waitval::Waitval, Mutex}; const MAIN_PTHREAD_ID: usize = 1; @@ -65,7 +67,6 @@ pub struct Pthread { // so it starts from one. The 31st bit is reserved. Only for process-private mutexes, which we // currently don't handle separately. //index: u32, - stack_base: *mut c_void, stack_size: usize, @@ -93,7 +94,10 @@ pub struct Errno(pub c_int); #[derive(Clone, Copy)] pub struct Retval(pub *mut c_void); -struct MmapGuard { page_start: *mut c_void, mmap_size: usize } +struct MmapGuard { + page_start: *mut c_void, + mmap_size: usize, +} impl Drop for MmapGuard { fn drop(&mut self) { unsafe { @@ -102,7 +106,11 @@ impl Drop for MmapGuard { } } -pub(crate) unsafe fn create(attrs: Option<&header::RlctAttr>, start_routine: extern "C" fn(arg: *mut c_void) -> *mut c_void, arg: *mut c_void) -> Result<pthread_t, Errno> { +pub(crate) unsafe fn create( + attrs: Option<&header::RlctAttr>, + start_routine: extern "C" fn(arg: *mut c_void) -> *mut c_void, + arg: *mut c_void, +) -> Result<pthread_t, Errno> { let attrs = attrs.copied().unwrap_or_default(); // Create a locked mutex, unlocked by the thread after it has started. @@ -148,7 +156,10 @@ pub(crate) unsafe fn create(attrs: Option<&header::RlctAttr>, start_routine: ext }; let ptr = Box::into_raw(Box::new(pthread)); - let stack_raii = MmapGuard { page_start: stack_base, mmap_size: stack_size }; + let stack_raii = MmapGuard { + page_start: stack_base, + mmap_size: stack_size, + }; let stack_end = stack_base.add(stack_size); let mut stack = stack_end as *mut usize; @@ -191,7 +202,9 @@ pub(crate) unsafe fn create(attrs: Option<&header::RlctAttr>, start_routine: ext let _ = (&*synchronization_mutex).lock(); - OS_TID_TO_PTHREAD.lock().insert(os_tid, ForceSendSync(ptr.cast())); + OS_TID_TO_PTHREAD + .lock() + .insert(os_tid, ForceSendSync(ptr.cast())); Ok(ptr.cast()) } @@ -229,7 +242,10 @@ unsafe extern "C" fn new_thread_shim( pub unsafe fn join(thread: &Pthread) -> Result<Retval, Errno> { // We don't have to return EDEADLK, but unlike e.g. pthread_t lifetime checking, it's a // relatively easy check. - if core::ptr::eq(thread, current_thread().expect("current thread not present")) { + if core::ptr::eq( + thread, + current_thread().expect("current thread not present"), + ) { return Err(Errno(EDEADLK)); } @@ -248,22 +264,24 @@ pub unsafe fn join(thread: &Pthread) -> Result<Retval, Errno> { } pub unsafe fn detach(thread: &Pthread) -> Result<(), Errno> { - thread.flags.fetch_or(PthreadFlags::DETACHED.bits(), Ordering::Release); + thread + .flags + .fetch_or(PthreadFlags::DETACHED.bits(), Ordering::Release); Ok(()) } // Returns option because that's a no-op, but PTHREAD_SELF should always be initialized except in // early init code. pub fn current_thread() -> Option<&'static Pthread> { - unsafe { - NonNull::new(PTHREAD_SELF.get()).map(|p| p.as_ref()) - } + unsafe { NonNull::new(PTHREAD_SELF.get()).map(|p| p.as_ref()) } } pub unsafe fn testcancel() { let this_thread = current_thread().expect("current thread not present"); - if this_thread.has_queued_cancelation.load(Ordering::Acquire) && this_thread.has_enabled_cancelation.load(Ordering::Acquire) { + if this_thread.has_queued_cancelation.load(Ordering::Acquire) + && this_thread.has_enabled_cancelation.load(Ordering::Acquire) + { cancel_current_thread(); } } @@ -319,7 +337,11 @@ pub unsafe fn cancel(thread: &Pthread) -> Result<(), Errno> { Ok(()) } -pub fn set_sched_param(_thread: &Pthread, _policy: c_int, _param: &sched_param) -> Result<(), Errno> { +pub fn set_sched_param( + _thread: &Pthread, + _policy: c_int, + _param: &sched_param, +) -> Result<(), Errno> { // TODO Ok(()) } @@ -332,14 +354,20 @@ pub fn set_cancel_state(state: c_int) -> Result<c_int, Errno> { let was_cancelable = match state { header::PTHREAD_CANCEL_ENABLE => { - let old = this_thread.has_enabled_cancelation.swap(true, Ordering::Release); + let old = this_thread + .has_enabled_cancelation + .swap(true, Ordering::Release); if this_thread.has_queued_cancelation.load(Ordering::Acquire) { - unsafe { cancel_current_thread(); } + unsafe { + cancel_current_thread(); + } } old - }, - header::PTHREAD_CANCEL_DISABLE => this_thread.has_enabled_cancelation.swap(false, Ordering::Release), + } + header::PTHREAD_CANCEL_DISABLE => this_thread + .has_enabled_cancelation + .swap(false, Ordering::Release), _ => return Err(Errno(EINVAL)), }; @@ -371,7 +399,8 @@ pub fn get_sched_param(thread: &Pthread) -> Result<(clockid_t, sched_param), Err // TODO: Hash map? // TODO: RwLock to improve perf? -static OS_TID_TO_PTHREAD: Mutex<BTreeMap<OsTid, ForceSendSync<*mut Pthread>>> = Mutex::new(BTreeMap::new()); +static OS_TID_TO_PTHREAD: Mutex<BTreeMap<OsTid, ForceSendSync<*mut Pthread>>> = + Mutex::new(BTreeMap::new()); #[derive(Clone, Copy)] struct ForceSendSync<T>(T); diff --git a/src/sync/barrier.rs b/src/sync/barrier.rs index 48d761432c5085468838a66ebc849500331056f8..6e027364a90400576db9a4f92e73ca929540efbd 100644 --- a/src/sync/barrier.rs +++ b/src/sync/barrier.rs @@ -1,6 +1,8 @@ -use core::cmp; -use core::num::NonZeroU32; -use core::sync::atomic::{AtomicU32 as AtomicUint, Ordering}; +use core::{ + cmp, + num::NonZeroU32, + sync::atomic::{AtomicU32 as AtomicUint, Ordering}, +}; pub struct Barrier { original_count: NonZeroU32, @@ -26,7 +28,10 @@ impl Barrier { pub fn new(count: NonZeroU32) -> Self { Self { original_count: count, - lock: crate::sync::Mutex::new(Inner { count: 0, gen_id: 0 }), + lock: crate::sync::Mutex::new(Inner { + count: 0, + gen_id: 0, + }), cvar: crate::header::pthread::RlctCond::new(), } } diff --git a/src/sync/cond.rs b/src/sync/cond.rs index 17e30780356a55cddfda1b3339fb887b024595b5..43b620fee81748d0ae5c826f49645f43bb5a0795 100644 --- a/src/sync/cond.rs +++ b/src/sync/cond.rs @@ -1,9 +1,9 @@ // Used design from https://www.remlab.net/op/futex-condvar.shtml -use crate::header::pthread::*; -use crate::header::bits_pthread::*; -use crate::header::time::timespec; -use crate::pthread::Errno; +use crate::{ + header::{bits_pthread::*, pthread::*, time::timespec}, + pthread::Errno, +}; use core::sync::atomic::{AtomicU32 as AtomicUint, Ordering}; @@ -16,7 +16,7 @@ type Result<T, E = crate::pthread::Errno> = core::result::Result<T, E>; impl Cond { pub fn new() -> Self { - Self{ + Self { cur: AtomicUint::new(0), prev: AtomicUint::new(0), } @@ -40,22 +40,42 @@ impl Cond { self.wait_inner(mutex, Some(timeout)) } fn wait_inner(&self, mutex: &RlctMutex, timeout: Option<×pec>) -> Result<(), Errno> { - self.wait_inner_generic(|| mutex.unlock(), || mutex.lock(), |timeout| mutex.lock_with_timeout(timeout), timeout) + self.wait_inner_generic( + || mutex.unlock(), + || mutex.lock(), + |timeout| mutex.lock_with_timeout(timeout), + timeout, + ) } - pub fn wait_inner_typedmutex<'lock, T>(&self, guard: crate::sync::MutexGuard<'lock, T>) -> crate::sync::MutexGuard<'lock, T> { + pub fn wait_inner_typedmutex<'lock, T>( + &self, + guard: crate::sync::MutexGuard<'lock, T>, + ) -> crate::sync::MutexGuard<'lock, T> { let mut newguard = None; let lock = guard.mutex; - self.wait_inner_generic(move || { - drop(guard); - Ok(()) - }, || { - newguard = Some(lock.lock()); - Ok(()) - }, |_| unreachable!(), None).unwrap(); + self.wait_inner_generic( + move || { + drop(guard); + Ok(()) + }, + || { + newguard = Some(lock.lock()); + Ok(()) + }, + |_| unreachable!(), + None, + ) + .unwrap(); newguard.unwrap() } // TODO: FUTEX_REQUEUE - fn wait_inner_generic(&self, unlock: impl FnOnce() -> Result<()>, lock: impl FnOnce() -> Result<()>, lock_with_timeout: impl FnOnce(×pec) -> Result<()>, timeout: Option<×pec>) -> Result<(), Errno> { + fn wait_inner_generic( + &self, + unlock: impl FnOnce() -> Result<()>, + lock: impl FnOnce() -> Result<()>, + lock_with_timeout: impl FnOnce(×pec) -> Result<()>, + timeout: Option<×pec>, + ) -> Result<(), Errno> { // TODO: Error checking for certain types (i.e. robust and errorcheck) of mutexes, e.g. if the // mutex is not locked. let current = self.cur.load(Ordering::Relaxed); @@ -65,7 +85,11 @@ impl Cond { match timeout { Some(timeout) => { - crate::sync::futex_wait(&self.cur, current, timespec::subtract(*timeout, crate::sync::rttime()).as_ref()); + crate::sync::futex_wait( + &self.cur, + current, + timespec::subtract(*timeout, crate::sync::rttime()).as_ref(), + ); lock_with_timeout(timeout); } None => { diff --git a/src/sync/mod.rs b/src/sync/mod.rs index 8651228aaad86cf1dd6665dd68f9b6b6f9183432..e3cd32c73461f87cf9e823ceb857c9b05735b248 100644 --- a/src/sync/mod.rs +++ b/src/sync/mod.rs @@ -22,7 +22,7 @@ use crate::{ use core::{ mem::MaybeUninit, ops::Deref, - sync::atomic::{self, AtomicI32, AtomicU32, AtomicI32 as AtomicInt}, + sync::atomic::{self, AtomicI32, AtomicI32 as AtomicInt, AtomicU32}, }; const FUTEX_WAIT: c_int = 0; @@ -93,14 +93,27 @@ pub unsafe fn futex_wake_ptr(ptr: *mut impl FutexTy, n: i32) -> usize { // TODO: unwrap_unchecked? Sys::futex(ptr.cast(), FUTEX_WAKE, n, 0).unwrap() as usize } -pub unsafe fn futex_wait_ptr<T: FutexTy>(ptr: *mut T, value: T, timeout_opt: Option<×pec>) -> bool { +pub unsafe fn futex_wait_ptr<T: FutexTy>( + ptr: *mut T, + value: T, + timeout_opt: Option<×pec>, +) -> bool { // TODO: unwrap_unchecked? - Sys::futex(ptr.cast(), FUTEX_WAIT, value.conv(), timeout_opt.map_or(0, |t| t as *const _ as usize)) == Ok(0) + Sys::futex( + ptr.cast(), + FUTEX_WAIT, + value.conv(), + timeout_opt.map_or(0, |t| t as *const _ as usize), + ) == Ok(0) } pub fn futex_wake(atomic: &impl FutexAtomicTy, n: i32) -> usize { unsafe { futex_wake_ptr(atomic.ptr(), n) } } -pub fn futex_wait<T: FutexAtomicTy>(atomic: &T, value: T::Ty, timeout_opt: Option<×pec>) -> bool { +pub fn futex_wait<T: FutexAtomicTy>( + atomic: &T, + value: T::Ty, + timeout_opt: Option<×pec>, +) -> bool { unsafe { futex_wait_ptr(atomic.ptr(), value, timeout_opt) } } diff --git a/src/sync/mutex.rs b/src/sync/mutex.rs index b4e5b1e998680bf0a9661eef513bc6e11d5580b6..bac9d11a69e8cdf66eb4d0f00978022d518a9361 100644 --- a/src/sync/mutex.rs +++ b/src/sync/mutex.rs @@ -18,7 +18,8 @@ unsafe impl<T: Send> Send for Mutex<T> {} unsafe impl<T: Send> Sync for Mutex<T> {} pub(crate) unsafe fn manual_try_lock_generic(word: &AtomicInt) -> bool { - word.compare_exchange(UNLOCKED, LOCKED, Ordering::Acquire, Ordering::Relaxed).is_ok() + word.compare_exchange(UNLOCKED, LOCKED, Ordering::Acquire, Ordering::Relaxed) + .is_ok() } pub(crate) unsafe fn manual_lock_generic(word: &AtomicInt) { crate::sync::wait_until_generic( @@ -32,7 +33,7 @@ pub(crate) unsafe fn manual_lock_generic(word: &AtomicInt) { }) }, |lock| match lock - // TODO: Ordering + // TODO: Ordering .compare_exchange_weak(LOCKED, WAITING, Ordering::SeqCst, Ordering::SeqCst) .unwrap_or_else(|e| e) { diff --git a/src/sync/once.rs b/src/sync/once.rs index 5e8341645bcd0510cf82382d91ef2ac03dd7aea9..b554f24bc90247c441a5ab0160f2e008697eed49 100644 --- a/src/sync/once.rs +++ b/src/sync/once.rs @@ -1,7 +1,10 @@ use super::{AtomicLock, AttemptStatus}; use crate::platform::types::*; -use core::{cell::UnsafeCell, mem::MaybeUninit}; -use core::sync::atomic::{AtomicI32 as AtomicInt, Ordering}; +use core::{ + cell::UnsafeCell, + mem::MaybeUninit, + sync::atomic::{AtomicI32 as AtomicInt, Ordering}, +}; const UNINITIALIZED: c_int = 0; const INITIALIZING: c_int = 1; @@ -51,8 +54,7 @@ impl<T> Once<T> { // then Relaxed is sufficient, as it will have to be Acquire-loaded again later. If // INITIALIZED is encountered however, it will nonatomically read the value in the // Cell, which necessitates Acquire. - Ordering::Acquire - // TODO: On archs where this matters, use Relaxed and core::sync::atomic::fence? + Ordering::Acquire, // TODO: On archs where this matters, use Relaxed and core::sync::atomic::fence? ) { Ok(_must_be_uninit) => { // We now have exclusive access to the cell, let's initiate things! @@ -77,7 +79,12 @@ impl<T> Once<T> { // it was INITIALIZED, the nonatomic write by the constructor thread, must be // visible. |status| match status - .compare_exchange_weak(INITIALIZING, WAITING, Ordering::Acquire, Ordering::Acquire) + .compare_exchange_weak( + INITIALIZING, + WAITING, + Ordering::Acquire, + Ordering::Acquire, + ) .unwrap_or_else(|e| e) { WAITING => AttemptStatus::Waiting, diff --git a/src/sync/pthread_mutex.rs b/src/sync/pthread_mutex.rs index 93eea912a64867d8e5e0881af27fd57e895babdc..05d75daccc2bb96a1847f5d4919e6e35d955a52a 100644 --- a/src/sync/pthread_mutex.rs +++ b/src/sync/pthread_mutex.rs @@ -1,14 +1,14 @@ -use core::cell::Cell; -use core::sync::atomic::{AtomicU32 as AtomicUint, Ordering}; +use core::{ + cell::Cell, + sync::atomic::{AtomicU32 as AtomicUint, Ordering}, +}; -use crate::header::pthread::*; -use crate::pthread::*; -use crate::header::time::timespec; -use crate::header::errno::*; -use crate::header::sys_wait::*; +use crate::{ + header::{errno::*, pthread::*, sys_wait::*, time::timespec}, + pthread::*, +}; -use crate::platform::types::*; -use crate::platform::{Pal, Sys}; +use crate::platform::{types::*, Pal, Sys}; pub struct RlctMutex { // Actual locking word. @@ -31,7 +31,13 @@ const SPIN_COUNT: usize = 0; impl RlctMutex { pub(crate) fn new(attr: &RlctMutexAttr) -> Result<Self, Errno> { - let RlctMutexAttr { prioceiling, protocol, pshared: _, robust, ty } = *attr; + let RlctMutexAttr { + prioceiling, + protocol, + pshared: _, + robust, + ty, + } = *attr; Ok(Self { inner: AtomicUint::new(STATE_UNLOCKED), @@ -49,7 +55,7 @@ impl RlctMutex { PTHREAD_MUTEX_NORMAL => Ty::Normal, _ => return Err(Errno(EINVAL)), - } + }, }) } pub fn prioceiling(&self) -> Result<c_int, Errno> { @@ -70,7 +76,12 @@ impl RlctMutex { let mut spins_left = SPIN_COUNT; loop { - let result = self.inner.compare_exchange_weak(STATE_UNLOCKED, this_thread, Ordering::Acquire, Ordering::Relaxed); + let result = self.inner.compare_exchange_weak( + STATE_UNLOCKED, + this_thread, + Ordering::Acquire, + Ordering::Relaxed, + ); match result { // CAS succeeded @@ -79,7 +90,7 @@ impl RlctMutex { self.increment_recursive_count()?; } return Ok(()); - }, + } // CAS failed, but the mutex was recursive and we already own the lock. Err(thread) if thread & INDEX_MASK == this_thread && self.ty == Ty::Recursive => { self.increment_recursive_count()?; @@ -136,7 +147,8 @@ impl RlctMutex { return Err(Errno(EAGAIN)); } - self.recursive_count.store(prev_recursive_count + 1, Ordering::Relaxed); + self.recursive_count + .store(prev_recursive_count + 1, Ordering::Relaxed); Ok(()) } @@ -144,7 +156,12 @@ impl RlctMutex { let this_thread = os_tid_invalid_after_fork(); // TODO: If recursive, omitting CAS may be faster if it is already owned by this thread. - let result = self.inner.compare_exchange(STATE_UNLOCKED, this_thread, Ordering::Acquire, Ordering::Relaxed); + let result = self.inner.compare_exchange( + STATE_UNLOCKED, + this_thread, + Ordering::Acquire, + Ordering::Relaxed, + ); if self.ty == Ty::Recursive { match result { @@ -159,7 +176,9 @@ impl RlctMutex { match result { Ok(_) => Ok(()), - Err(index) if index & INDEX_MASK == this_thread && self.ty == Ty::Errck => Err(Errno(EDEADLK)), + Err(index) if index & INDEX_MASK == this_thread && self.ty == Ty::Errck => { + Err(Errno(EDEADLK)) + } Err(_) => Err(Errno(EBUSY)), } } @@ -178,7 +197,9 @@ impl RlctMutex { let next = self.recursive_count.load(Ordering::Relaxed) - 1; self.recursive_count.store(next, Ordering::Relaxed); - if next > 0 { return Ok(()) } + if next > 0 { + return Ok(()); + } } self.inner.store(STATE_UNLOCKED, Ordering::Release); @@ -215,7 +236,7 @@ fn os_tid_invalid_after_fork() -> u32 { // TODO: Coordinate better if using shared == PTHREAD_PROCESS_SHARED, with up to 2^32 separate // threads within possibly distinct processes, using the mutex. OS thread IDs on Redox are // pointer-sized, but relibc and POSIX uses int everywhere. - + let value = CACHED_OS_TID_INVALID_AFTER_FORK.get(); if value == 0 { diff --git a/src/sync/rwlock.rs b/src/sync/rwlock.rs index e424936599a3efe105046a875536fac0c3c8fa29..cc77fd92b64401887bf06925177f4d8fb043acef 100644 --- a/src/sync/rwlock.rs +++ b/src/sync/rwlock.rs @@ -1,7 +1,6 @@ use core::sync::atomic::{AtomicU32, Ordering}; -use crate::header::time::timespec; -use crate::pthread::Pshared; +use crate::{header::time::timespec, pthread::Pshared}; pub struct Rwlock { state: AtomicU32, @@ -44,7 +43,12 @@ impl Rwlock { // TODO: Return with error code instead? assert_ne!(new, EXCLUSIVE, "maximum number of rwlock readers reached"); - match self.state.compare_exchange_weak(cached, new, Ordering::Acquire, Ordering::Relaxed) { + match self.state.compare_exchange_weak( + cached, + new, + Ordering::Acquire, + Ordering::Relaxed, + ) { Ok(_) => return Ok(()), Err(value) if value == EXCLUSIVE => return Err(EXCLUSIVE), @@ -57,7 +61,9 @@ impl Rwlock { } } pub fn try_acquire_write_lock(&self) -> Result<(), u32> { - self.state.compare_exchange(0, EXCLUSIVE, Ordering::Acquire, Ordering::Relaxed).map(|_| ()) + self.state + .compare_exchange(0, EXCLUSIVE, Ordering::Acquire, Ordering::Relaxed) + .map(|_| ()) } pub fn unlock(&self) { diff --git a/src/sync/semaphore.rs b/src/sync/semaphore.rs index 708acafca9ed919622cf58ca4ce211f37d99594d..1bad9e30a5b04c7cb4aecb6703a1214feff622ca 100644 --- a/src/sync/semaphore.rs +++ b/src/sync/semaphore.rs @@ -32,7 +32,9 @@ impl Semaphore { loop { let value = self.count.load(Ordering::SeqCst); - if value == 0 { return 0 } + if value == 0 { + return 0; + } match self.count.compare_exchange_weak( value, diff --git a/src/sync/waitval.rs b/src/sync/waitval.rs index f6ba84f1ac82579accfdfa293baf306ec466332a..f8054402dd64b5ccc9c7b3d58270c1ff6e80ccc6 100644 --- a/src/sync/waitval.rs +++ b/src/sync/waitval.rs @@ -1,6 +1,8 @@ -use core::cell::UnsafeCell; -use core::mem::MaybeUninit; -use core::sync::atomic::{AtomicU32 as AtomicUint, Ordering}; +use core::{ + cell::UnsafeCell, + mem::MaybeUninit, + sync::atomic::{AtomicU32 as AtomicUint, Ordering}, +}; use super::*;