Get it to compile
This commit is contained in:
@@ -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::*;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<usize, usize> {
|
||||
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<crate::pthread::OsTid, crate::pthread::Errno> {
|
||||
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 {
|
||||
|
||||
@@ -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<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;
|
||||
|
||||
|
||||
@@ -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<crate::pthread::OsTid, crate::pthread::Errno> {
|
||||
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 {
|
||||
|
||||
+23
-25
@@ -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<Retval>,
|
||||
wants_cancel: AtomicBool,
|
||||
|
||||
stack_base: *mut c_void,
|
||||
stack_size: usize,
|
||||
|
||||
os_tid: OsTid,
|
||||
os_tid: UnsafeCell<OsTid>,
|
||||
}
|
||||
|
||||
#[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<T> Sync for ForceSendSync<T> {}
|
||||
|
||||
#[thread_local]
|
||||
static PTHREAD_SELF: Cell<*mut Pthread> = Cell::new(core::ptr::null_mut());
|
||||
|
||||
pub struct ForkHandlers {
|
||||
pub prepare: Vec<extern "C" fn()>,
|
||||
pub parent: Vec<extern "C" fn()>,
|
||||
pub child: Vec<extern "C" fn()>,
|
||||
}
|
||||
|
||||
// TODO: Use fork handlers
|
||||
// TODO: Append-only atomic queue, not because of performance, but because of atomicity.
|
||||
pub static FORK_HANDLERS: Mutex<ForkHandlers> = Mutex::new(ForkHandlers {
|
||||
parent: Vec::new(),
|
||||
child: Vec::new(),
|
||||
prepare: Vec::new(),
|
||||
});
|
||||
|
||||
+1
-1
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user