From 2593101ea752b4d5910f3bb580328e0b345eef37 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Sun, 5 Mar 2023 16:34:53 +0100 Subject: [PATCH] Get it to compile --- src/header/pthread/mod.rs | 13 ----------- src/header/sched/mod.rs | 2 +- src/platform/linux/mod.rs | 35 +++++++++++++++++++++------- src/platform/pal/mod.rs | 4 +++- src/platform/redox/mod.rs | 12 ++++++++-- src/pthread/mod.rs | 48 +++++++++++++++++++-------------------- src/sync/mod.rs | 2 +- 7 files changed, 65 insertions(+), 51 deletions(-) diff --git a/src/header/pthread/mod.rs b/src/header/pthread/mod.rs index fe1bac2110..5b7425f997 100644 --- a/src/header/pthread/mod.rs +++ b/src/header/pthread/mod.rs @@ -39,19 +39,6 @@ pub const PTHREAD_PROCESS_PRIVATE: c_int = 1; pub const PTHREAD_SCOPE_PROCESS: c_int = 0; pub const PTHREAD_SCOPE_SYSTEM: c_int = 1; -#[no_mangle] -pub unsafe extern "C" fn pthread_atfork(prepare: extern "C" fn(), parent: extern "C" fn(), child: extern "C" fn()) -> c_int { - let mut guard = pthread::FORK_HANDLERS.lock(); - - // TODO: try_reserve - - guard.prepare.push(prepare); - guard.child.push(child); - guard.parent.push(parent); - - 0 -} - pub mod attr; pub use self::attr::*; diff --git a/src/header/sched/mod.rs b/src/header/sched/mod.rs index a4fe3e32d1..142d6b0aa6 100644 --- a/src/header/sched/mod.rs +++ b/src/header/sched/mod.rs @@ -6,7 +6,7 @@ use crate::header::time::timespec; #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct sched_param { - sched_priority: c_int, + pub sched_priority: c_int, } pub const SCHED_FIFO: c_int = 0; diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index 722f238366..5ab129d5c3 100644 --- a/src/platform/linux/mod.rs +++ b/src/platform/linux/mod.rs @@ -49,14 +49,22 @@ struct linux_statfs { f_spare: [c_long; 4], } -pub fn e(sys: usize) -> usize { +pub fn e_raw(sys: usize) -> Result { if (sys as isize) < 0 && (sys as isize) >= -256 { - unsafe { - errno = -(sys as isize) as c_int; - } - !0 + Err(sys.wrapping_neg()) } else { - sys + Ok(sys) + } +} +pub fn e(sys: usize) -> usize { + match e_raw(sys) { + Ok(value) => value, + Err(errcode) => { + unsafe { + errno = errcode; + } + !0 + } } } @@ -380,7 +388,7 @@ impl Pal for Sys { } #[cfg(target_arch = "x86_64")] - unsafe fn pte_clone(stack: *mut usize) -> pid_t { + unsafe fn rlct_clone(stack: *mut usize) -> Result { let flags = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD; let pid; asm!(" @@ -429,7 +437,18 @@ impl Pal for Sys { out("r14") _, out("r15") _, ); - e(pid) as pid_t + let tid = e_raw(pid)?; + + Ok(crate::pthread::OsTid { thread_id: tid }) + } + unsafe fn rlct_kill(os_tid: crate::pthread::OsTid, signal: usize) -> Result<(), crate::pthread::Errno> { + let tgid = Self::getpid(); + e_raw(unsafe { syscall!(TGKILL, pid, os_tid.thread_id, signal) }) + } + fn current_os_tid() -> crate::pthread::OsTid { + crate::pthread::OsTid { + thread_id: unsafe { syscall!(GETTID) }, + } } fn read(fildes: c_int, buf: &mut [u8]) -> ssize_t { diff --git a/src/platform/pal/mod.rs b/src/platform/pal/mod.rs index 21a0f41383..37d1b34aba 100644 --- a/src/platform/pal/mod.rs +++ b/src/platform/pal/mod.rs @@ -157,7 +157,9 @@ pub trait Pal { fn pipe2(fildes: &mut [c_int], flags: c_int) -> c_int; - unsafe fn pte_clone(stack: *mut usize) -> crate::pthread::OsTid; + unsafe fn rlct_clone(stack: *mut usize) -> Result; + 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 f182211709..b4b423d9ab 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -758,8 +758,16 @@ impl Pal for Sys { res as c_int } - unsafe fn pte_clone(stack: *mut usize) -> pid_t { - e(clone::pte_clone_impl(stack)) as pid_t + unsafe fn rlct_clone(stack: *mut usize) -> Result { + clone::pte_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))?; + Ok(()) + } + fn current_os_tid() -> crate::pthread::OsTid { + // TODO + crate::pthread::OsTid { context_id: Self::getpid() as _ } } fn read(fd: c_int, buf: &mut [u8]) -> ssize_t { diff --git a/src/pthread/mod.rs b/src/pthread/mod.rs index 39649b1efd..df6c023873 100644 --- a/src/pthread/mod.rs +++ b/src/pthread/mod.rs @@ -1,3 +1,5 @@ +//! Relibc Threads, or RLCT. + use core::cell::{Cell, UnsafeCell}; use core::ptr::NonNull; use core::sync::atomic::{AtomicBool, Ordering}; @@ -11,30 +13,33 @@ use crate::header::sched::sched_param; use crate::header::errno::*; use crate::header::sys_mman; use crate::ld_so::{linker::Linker, tcb::{Master, Tcb}}; +use crate::ALLOCATOR; use crate::sync::{Mutex, waitval::Waitval}; +#[no_mangle] extern "C" fn pthread_init() { } +#[no_mangle] extern "C" fn pthread_terminate() { } -struct Pthread { +pub struct Pthread { waitval: Waitval, wants_cancel: AtomicBool, stack_base: *mut c_void, stack_size: usize, - os_tid: OsTid, + os_tid: UnsafeCell, } -#[derive(Clone, Copy, Debug, Ord, Eq, PartialOrd, PartialEq)] +#[derive(Clone, Copy, Debug, Default, Ord, Eq, PartialOrd, PartialEq)] pub struct OsTid { #[cfg(target_os = "redox")] - context_id: usize, + pub context_id: usize, #[cfg(target_os = "linux")] - thread_id: usize, + pub thread_id: usize, } unsafe impl Send for Pthread {} @@ -46,6 +51,7 @@ use crate::header::pthread::attr::Attr; #[derive(Debug)] 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 } @@ -84,7 +90,7 @@ pub unsafe fn create(attrs: Option<&pthread_attr_t>, start_routine: extern "C" f wants_cancel: AtomicBool::new(false), stack_base, stack_size, - os_tid, + os_tid: UnsafeCell::new(OsTid::default()), }; let ptr = Box::into_raw(Box::new(pthread)); @@ -124,13 +130,12 @@ pub unsafe fn create(attrs: Option<&pthread_attr_t>, start_routine: extern "C" f push(new_thread_shim as usize); } - let id = Sys::pte_clone(stack); - if id < 0 { + let Ok(os_tid) = Sys::rlct_clone(stack) else { return Err(Errno(EAGAIN)); - } + }; let _ = (&mut *synchronization_mutex).lock(); - CID_TO_PTHREAD.lock().insert(id, ForceSendSync(ptr.cast())); + OS_TID_TO_PTHREAD.lock().insert(os_tid, ForceSendSync(ptr.cast())); core::mem::forget(stack_raii); @@ -160,6 +165,8 @@ unsafe extern "C" fn new_thread_shim( } PTHREAD_SELF.set(pthread); + core::ptr::write((&*pthread).os_tid.get(), Sys::current_os_tid()); + (&*mutex).manual_unlock(); let retval = entry_point(arg); @@ -205,9 +212,14 @@ pub unsafe fn exit_current_thread(retval: Retval) -> ! { Sys::exit_thread() } +pub const SIGRT_RLCT_CANCEL: usize = 32; +pub const SIGRT_RLCT_TIMER: usize = 33; + pub unsafe fn cancel(thread: &Pthread) -> Result<(), Errno> { thread.wants_cancel.store(true, Ordering::SeqCst); - crate::header::signal + Sys::rlct_kill(thread.os_tid.get().read(), SIGRT_RLCT_CANCEL)?; + todo!(); + Ok(()) } // TODO: Hash map? @@ -219,17 +231,3 @@ unsafe impl Sync for ForceSendSync {} #[thread_local] static PTHREAD_SELF: Cell<*mut Pthread> = Cell::new(core::ptr::null_mut()); - -pub struct ForkHandlers { - pub prepare: Vec, - pub parent: Vec, - pub child: Vec, -} - -// TODO: Use fork handlers -// TODO: Append-only atomic queue, not because of performance, but because of atomicity. -pub static FORK_HANDLERS: Mutex = Mutex::new(ForkHandlers { - parent: Vec::new(), - child: Vec::new(), - prepare: Vec::new(), -}); diff --git a/src/sync/mod.rs b/src/sync/mod.rs index 9d0f92a609..853831d830 100644 --- a/src/sync/mod.rs +++ b/src/sync/mod.rs @@ -22,7 +22,7 @@ const FUTEX_WAIT: c_int = 0; const FUTEX_WAKE: c_int = 1; #[derive(Clone, Copy, PartialEq, Eq)] -enum AttemptStatus { +pub enum AttemptStatus { Desired, Waiting, Other,