feature: thread::current() using tpidr_el0
This commit is contained in:
parent
6eac5287a2
commit
7c622a78f8
@ -32,27 +32,6 @@ __aa64_ctx_enter_kernel:
|
|||||||
eret
|
eret
|
||||||
|
|
||||||
__aa64_ctx_enter_from_fork:
|
__aa64_ctx_enter_from_fork:
|
||||||
// stack.push(frame.x[18]);
|
|
||||||
// stack.push(frame.x[17]);
|
|
||||||
// stack.push(frame.x[16]);
|
|
||||||
// stack.push(frame.x[15]);
|
|
||||||
// stack.push(frame.x[14]);
|
|
||||||
// stack.push(frame.x[13]);
|
|
||||||
// stack.push(frame.x[12]);
|
|
||||||
// stack.push(frame.x[11]);
|
|
||||||
// stack.push(frame.x[10]);
|
|
||||||
// stack.push(frame.x[9]);
|
|
||||||
// stack.push(frame.x[8]);
|
|
||||||
// stack.push(frame.x[7]);
|
|
||||||
// stack.push(frame.x[6]);
|
|
||||||
// stack.push(frame.x[5]);
|
|
||||||
// stack.push(frame.x[4]);
|
|
||||||
// stack.push(frame.x[3]);
|
|
||||||
// stack.push(frame.x[2]);
|
|
||||||
// stack.push(frame.x[1]);
|
|
||||||
|
|
||||||
// stack.push(frame.elr_el1 as usize);
|
|
||||||
// stack.push(frame.sp_el0 as usize);
|
|
||||||
ldp x0, x1, [sp, #16 * 0]
|
ldp x0, x1, [sp, #16 * 0]
|
||||||
msr sp_el0, x0
|
msr sp_el0, x0
|
||||||
msr elr_el1, x1
|
msr elr_el1, x1
|
||||||
@ -82,7 +61,8 @@ __aa64_ctx_switch:
|
|||||||
stp x27, x28, [sp, #16 * 4]
|
stp x27, x28, [sp, #16 * 4]
|
||||||
stp x29, x30, [sp, #16 * 5]
|
stp x29, x30, [sp, #16 * 5]
|
||||||
mrs x19, TTBR0_EL1
|
mrs x19, TTBR0_EL1
|
||||||
stp x19, xzr, [sp, #16 * 6]
|
mrs x20, TPIDR_EL0
|
||||||
|
stp x19, x20, [sp, #16 * 6]
|
||||||
|
|
||||||
mov x19, sp
|
mov x19, sp
|
||||||
str x19, [x1]
|
str x19, [x1]
|
||||||
@ -90,8 +70,9 @@ __aa64_ctx_switch_to:
|
|||||||
ldr x0, [x0]
|
ldr x0, [x0]
|
||||||
mov sp, x0
|
mov sp, x0
|
||||||
|
|
||||||
ldp x19, xzr, [sp, #16 * 6]
|
ldp x19, x20, [sp, #16 * 6]
|
||||||
msr TTBR0_EL1, x19
|
msr TTBR0_EL1, x19
|
||||||
|
msr TPIDR_EL0, x20
|
||||||
ldp x19, x20, [sp, #16 * 0]
|
ldp x19, x20, [sp, #16 * 0]
|
||||||
ldp x21, x22, [sp, #16 * 1]
|
ldp x21, x22, [sp, #16 * 1]
|
||||||
ldp x23, x24, [sp, #16 * 2]
|
ldp x23, x24, [sp, #16 * 2]
|
||||||
|
@ -67,7 +67,7 @@ impl Context {
|
|||||||
stack.push(frame.sp_el0 as usize);
|
stack.push(frame.sp_el0 as usize);
|
||||||
|
|
||||||
// Setup common
|
// Setup common
|
||||||
stack.push(0);
|
stack.push(0); // tpidr_el0
|
||||||
stack.push(ttbr0);
|
stack.push(ttbr0);
|
||||||
stack.push(__aa64_ctx_enter_from_fork as usize); // x30/lr
|
stack.push(__aa64_ctx_enter_from_fork as usize); // x30/lr
|
||||||
stack.push(frame.x[29]); // x29
|
stack.push(frame.x[29]); // x29
|
||||||
@ -96,7 +96,7 @@ impl Context {
|
|||||||
|
|
||||||
stack.push(entry);
|
stack.push(entry);
|
||||||
stack.push(arg);
|
stack.push(arg);
|
||||||
stack.push(/* ttbr0 */ 0);
|
stack.push(0);
|
||||||
stack.push(ustack);
|
stack.push(ustack);
|
||||||
|
|
||||||
stack.setup_common(__aa64_ctx_enter_user as usize, ttbr0);
|
stack.setup_common(__aa64_ctx_enter_user as usize, ttbr0);
|
||||||
@ -176,20 +176,20 @@ impl Stack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn setup_common(&mut self, entry: usize, ttbr: usize) {
|
pub fn setup_common(&mut self, entry: usize, ttbr: usize) {
|
||||||
self.push(0);
|
self.push(0); // tpidr_el0
|
||||||
self.push(ttbr);
|
self.push(ttbr);
|
||||||
self.push(entry); // x30/lr
|
self.push(entry); // x30/lr
|
||||||
self.push(0); // x29
|
self.push(0); // x29
|
||||||
self.push(0); // x28
|
self.push(0); // x28
|
||||||
self.push(0); // x27
|
self.push(0); // x27
|
||||||
self.push(0); // x26
|
self.push(0); // x26
|
||||||
self.push(0); // x25
|
self.push(0); // x25
|
||||||
self.push(0); // x24
|
self.push(0); // x24
|
||||||
self.push(0); // x23
|
self.push(0); // x23
|
||||||
self.push(0); // x22
|
self.push(0); // x22
|
||||||
self.push(0); // x21
|
self.push(0); // x21
|
||||||
self.push(0); // x20
|
self.push(0); // x20
|
||||||
self.push(0); // x19
|
self.push(0); // x19
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push(&mut self, value: usize) {
|
pub fn push(&mut self, value: usize) {
|
||||||
|
@ -197,11 +197,10 @@ impl Process {
|
|||||||
|
|
||||||
// TODO a way to terminate a single thread?
|
// TODO a way to terminate a single thread?
|
||||||
/// Terminates a process.
|
/// Terminates a process.
|
||||||
pub fn exit<I: Into<ExitCode>>(status: I) {
|
pub fn exit(status: ExitCode) {
|
||||||
unsafe {
|
unsafe {
|
||||||
asm!("msr daifclr, #0xF");
|
asm!("msr daifclr, #0xF");
|
||||||
}
|
}
|
||||||
let status = status.into();
|
|
||||||
let thread = Thread::current();
|
let thread = Thread::current();
|
||||||
let process = thread.owner().unwrap();
|
let process = thread.owner().unwrap();
|
||||||
let mut lock = process.inner.lock();
|
let mut lock = process.inner.lock();
|
||||||
@ -213,7 +212,7 @@ impl Process {
|
|||||||
|
|
||||||
for &tid in lock.threads.iter() {
|
for &tid in lock.threads.iter() {
|
||||||
debugln!("Dequeue {:?}", tid);
|
debugln!("Dequeue {:?}", tid);
|
||||||
Thread::get(tid).unwrap().terminate();
|
Thread::get(tid).unwrap().terminate(status);
|
||||||
SCHED.dequeue(tid);
|
SCHED.dequeue(tid);
|
||||||
}
|
}
|
||||||
SCHED.debug();
|
SCHED.debug();
|
||||||
@ -234,7 +233,7 @@ impl Process {
|
|||||||
panic!("This code should never run");
|
panic!("This code should never run");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exit_thread(thread: ThreadRef) {
|
pub fn exit_thread(thread: ThreadRef, status: ExitCode) {
|
||||||
let switch = {
|
let switch = {
|
||||||
let switch = thread.state() == ThreadState::Running;
|
let switch = thread.state() == ThreadState::Running;
|
||||||
let process = thread.owner().unwrap();
|
let process = thread.owner().unwrap();
|
||||||
@ -244,13 +243,13 @@ impl Process {
|
|||||||
if lock.threads.len() == 1 {
|
if lock.threads.len() == 1 {
|
||||||
// TODO call Process::exit instead?
|
// TODO call Process::exit instead?
|
||||||
drop(lock);
|
drop(lock);
|
||||||
Process::exit(ExitCode::from(0));
|
Process::exit(status);
|
||||||
panic!();
|
panic!();
|
||||||
}
|
}
|
||||||
|
|
||||||
lock.threads.retain(|&e| e != tid);
|
lock.threads.retain(|&e| e != tid);
|
||||||
|
|
||||||
thread.terminate();
|
thread.terminate(status);
|
||||||
SCHED.dequeue(tid);
|
SCHED.dequeue(tid);
|
||||||
debugln!("Thread {} terminated", tid);
|
debugln!("Thread {} terminated", tid);
|
||||||
|
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
use crate::arch::aarch64::exception::ExceptionFrame;
|
use crate::arch::aarch64::exception::ExceptionFrame;
|
||||||
use crate::proc::{wait::Wait, Process, ProcessRef, SCHED, THREADS};
|
use crate::proc::{wait::Wait, Process, ProcessRef, SCHED, THREADS};
|
||||||
use crate::sync::IrqSafeSpinLock;
|
use crate::sync::IrqSafeSpinLock;
|
||||||
|
use crate::util::InitOnce;
|
||||||
use alloc::{rc::Rc, vec::Vec};
|
use alloc::{rc::Rc, vec::Vec};
|
||||||
use core::cell::UnsafeCell;
|
use core::cell::UnsafeCell;
|
||||||
use core::sync::atomic::{AtomicU32, Ordering};
|
use core::sync::atomic::{AtomicU32, Ordering};
|
||||||
use libsys::{error::Errno, proc::Pid, signal::Signal};
|
use libsys::{error::Errno, proc::{Pid, ExitCode}, signal::Signal};
|
||||||
|
|
||||||
pub use crate::arch::platform::context::{self, Context};
|
pub use crate::arch::platform::context::{self, Context};
|
||||||
|
|
||||||
@ -36,6 +37,7 @@ struct ThreadInner {
|
|||||||
pub struct Thread {
|
pub struct Thread {
|
||||||
inner: IrqSafeSpinLock<ThreadInner>,
|
inner: IrqSafeSpinLock<ThreadInner>,
|
||||||
exit_wait: Wait,
|
exit_wait: Wait,
|
||||||
|
exit_status: InitOnce<ExitCode>,
|
||||||
pub(super) ctx: UnsafeCell<Context>,
|
pub(super) ctx: UnsafeCell<Context>,
|
||||||
signal_ctx: UnsafeCell<Context>,
|
signal_ctx: UnsafeCell<Context>,
|
||||||
signal_pending: AtomicU32,
|
signal_pending: AtomicU32,
|
||||||
@ -70,6 +72,7 @@ impl Thread {
|
|||||||
signal_ctx: UnsafeCell::new(Context::empty()),
|
signal_ctx: UnsafeCell::new(Context::empty()),
|
||||||
signal_pending: AtomicU32::new(0),
|
signal_pending: AtomicU32::new(0),
|
||||||
exit_wait: Wait::new(),
|
exit_wait: Wait::new(),
|
||||||
|
exit_status: InitOnce::new(),
|
||||||
inner: IrqSafeSpinLock::new(ThreadInner {
|
inner: IrqSafeSpinLock::new(ThreadInner {
|
||||||
signal_entry: 0,
|
signal_entry: 0,
|
||||||
signal_stack: 0,
|
signal_stack: 0,
|
||||||
@ -100,6 +103,7 @@ impl Thread {
|
|||||||
signal_ctx: UnsafeCell::new(Context::empty()),
|
signal_ctx: UnsafeCell::new(Context::empty()),
|
||||||
signal_pending: AtomicU32::new(0),
|
signal_pending: AtomicU32::new(0),
|
||||||
exit_wait: Wait::new(),
|
exit_wait: Wait::new(),
|
||||||
|
exit_status: InitOnce::new(),
|
||||||
inner: IrqSafeSpinLock::new(ThreadInner {
|
inner: IrqSafeSpinLock::new(ThreadInner {
|
||||||
signal_entry: 0,
|
signal_entry: 0,
|
||||||
signal_stack: 0,
|
signal_stack: 0,
|
||||||
@ -127,6 +131,7 @@ impl Thread {
|
|||||||
signal_ctx: UnsafeCell::new(Context::empty()),
|
signal_ctx: UnsafeCell::new(Context::empty()),
|
||||||
signal_pending: AtomicU32::new(0),
|
signal_pending: AtomicU32::new(0),
|
||||||
exit_wait: Wait::new(),
|
exit_wait: Wait::new(),
|
||||||
|
exit_status: InitOnce::new(),
|
||||||
inner: IrqSafeSpinLock::new(ThreadInner {
|
inner: IrqSafeSpinLock::new(ThreadInner {
|
||||||
signal_entry: 0,
|
signal_entry: 0,
|
||||||
signal_stack: 0,
|
signal_stack: 0,
|
||||||
@ -295,7 +300,7 @@ impl Thread {
|
|||||||
let mut lock = self.inner.lock();
|
let mut lock = self.inner.lock();
|
||||||
if lock.signal_entry == 0 || lock.signal_stack == 0 {
|
if lock.signal_entry == 0 || lock.signal_stack == 0 {
|
||||||
drop(lock);
|
drop(lock);
|
||||||
Process::exit_thread(self);
|
Process::exit_thread(self, ExitCode::from(-1));
|
||||||
panic!();
|
panic!();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,7 +327,7 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn terminate(&self) {
|
pub fn terminate(&self, status: ExitCode) {
|
||||||
let mut lock = self.inner.lock();
|
let mut lock = self.inner.lock();
|
||||||
lock.state = State::Finished;
|
lock.state = State::Finished;
|
||||||
let tid = lock.id;
|
let tid = lock.id;
|
||||||
@ -331,6 +336,7 @@ impl Thread {
|
|||||||
if let Some(wait) = wait {
|
if let Some(wait) = wait {
|
||||||
wait.abort(tid);
|
wait.abort(tid);
|
||||||
}
|
}
|
||||||
|
self.exit_status.init(status);
|
||||||
self.exit_wait.wakeup_all();
|
self.exit_wait.wakeup_all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ use libsys::{
|
|||||||
abi,
|
abi,
|
||||||
error::Errno,
|
error::Errno,
|
||||||
ioctl::IoctlCmd,
|
ioctl::IoctlCmd,
|
||||||
proc::Pid,
|
proc::{ExitCode, Pid},
|
||||||
signal::{Signal, SignalDestination},
|
signal::{Signal, SignalDestination},
|
||||||
stat::{FdSet, AccessMode, FileDescriptor, FileMode, OpenFlags, Stat, AT_EMPTY_PATH},
|
stat::{FdSet, AccessMode, FileDescriptor, FileMode, OpenFlags, Stat, AT_EMPTY_PATH},
|
||||||
traits::{Read, Write},
|
traits::{Read, Write},
|
||||||
@ -55,13 +55,16 @@ pub fn syscall(num: usize, args: &[usize]) -> Result<usize, Errno> {
|
|||||||
match num {
|
match num {
|
||||||
// Process management system calls
|
// Process management system calls
|
||||||
abi::SYS_EXIT => {
|
abi::SYS_EXIT => {
|
||||||
Process::exit(args[0] as i32);
|
Process::exit(ExitCode::from(args[0] as i32));
|
||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
abi::SYS_EX_THREAD_EXIT => {
|
abi::SYS_EX_THREAD_EXIT => {
|
||||||
Process::exit_thread(Thread::current());
|
Process::exit_thread(Thread::current(), ExitCode::from(args[0] as i32));
|
||||||
unreachable!();
|
unreachable!();
|
||||||
},
|
},
|
||||||
|
abi::SYS_EX_GETTID => {
|
||||||
|
Ok(Thread::current().id() as usize)
|
||||||
|
},
|
||||||
|
|
||||||
// I/O system calls
|
// I/O system calls
|
||||||
abi::SYS_OPENAT => {
|
abi::SYS_OPENAT => {
|
||||||
|
@ -8,6 +8,7 @@ pub const SYS_EX_CLONE: usize = 133;
|
|||||||
pub const SYS_EX_YIELD: usize = 134;
|
pub const SYS_EX_YIELD: usize = 134;
|
||||||
pub const SYS_EX_THREAD_EXIT: usize = 135;
|
pub const SYS_EX_THREAD_EXIT: usize = 135;
|
||||||
pub const SYS_EX_THREAD_WAIT: usize = 136;
|
pub const SYS_EX_THREAD_WAIT: usize = 136;
|
||||||
|
pub const SYS_EX_GETTID: usize = 137;
|
||||||
|
|
||||||
pub const SYS_EXIT: usize = 1;
|
pub const SYS_EXIT: usize = 1;
|
||||||
pub const SYS_READ: usize = 2;
|
pub const SYS_READ: usize = 2;
|
||||||
@ -21,3 +22,4 @@ pub const SYS_WAITPID: usize = 9;
|
|||||||
pub const SYS_IOCTL: usize = 10;
|
pub const SYS_IOCTL: usize = 10;
|
||||||
pub const SYS_SELECT: usize = 11;
|
pub const SYS_SELECT: usize = 11;
|
||||||
pub const SYS_FACCESSAT: usize = 12;
|
pub const SYS_FACCESSAT: usize = 12;
|
||||||
|
// pub const SYS_GETPID: usize = 13;
|
||||||
|
@ -188,7 +188,7 @@ pub fn sys_fstatat(
|
|||||||
///
|
///
|
||||||
/// System call
|
/// System call
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn sys_fork() -> Result<Option<Pid>, Errno> {
|
pub unsafe fn sys_fork() -> Result<Option<Pid>, Errno> {
|
||||||
Errno::from_syscall(unsafe { syscall!(abi::SYS_FORK) }).map(|res| {
|
Errno::from_syscall(unsafe { syscall!(abi::SYS_FORK) }).map(|res| {
|
||||||
if res != 0 {
|
if res != 0 {
|
||||||
Some(unsafe { Pid::from_raw(res as u32) })
|
Some(unsafe { Pid::from_raw(res as u32) })
|
||||||
@ -344,3 +344,10 @@ pub fn sys_faccessat(
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn sys_ex_gettid() -> u32 {
|
||||||
|
unsafe {
|
||||||
|
syscall!(abi::SYS_EX_GETTID) as u32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -16,21 +16,8 @@ pub mod os;
|
|||||||
pub mod sys;
|
pub mod sys;
|
||||||
pub mod sync;
|
pub mod sync;
|
||||||
pub mod thread;
|
pub mod thread;
|
||||||
|
pub mod signal;
|
||||||
|
|
||||||
use sys::Signal;
|
|
||||||
|
|
||||||
#[inline(never)]
|
|
||||||
pub(crate) extern "C" fn _signal_handler(arg: Signal) -> ! {
|
|
||||||
trace!("Entered signal handler: arg={:?}", arg);
|
|
||||||
match arg {
|
|
||||||
Signal::Interrupt | Signal::SegmentationFault =>
|
|
||||||
loop {},
|
|
||||||
_ => todo!()
|
|
||||||
}
|
|
||||||
sys::sys_ex_sigreturn();
|
|
||||||
}
|
|
||||||
|
|
||||||
static mut SIGNAL_STACK: [u8; 4096] = [0; 4096];
|
|
||||||
|
|
||||||
#[link_section = ".text._start"]
|
#[link_section = ".text._start"]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@ -40,11 +27,7 @@ extern "C" fn _start(_arg: usize) -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
sys::sys_ex_signal(
|
thread::init_main();
|
||||||
_signal_handler as usize,
|
|
||||||
SIGNAL_STACK.as_ptr() as usize + 4096,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let res = unsafe { main() };
|
let res = unsafe { main() };
|
||||||
@ -53,8 +36,9 @@ extern "C" fn _start(_arg: usize) -> ! {
|
|||||||
|
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
fn panic_handler(pi: &PanicInfo) -> ! {
|
fn panic_handler(pi: &PanicInfo) -> ! {
|
||||||
// TODO handle non-main thread panics
|
// TODO unwind to send panic argument back to parent thread
|
||||||
// TODO print to stdout/stderr (if available)
|
// TODO print to stdout/stderr (if available)
|
||||||
trace!("Panic ocurred: {}", pi);
|
let thread = thread::current();
|
||||||
|
trace!("{:?} panicked: {:?}", thread, pi);
|
||||||
sys::sys_exit(ExitCode::from(-1));
|
sys::sys_exit(ExitCode::from(-1));
|
||||||
}
|
}
|
||||||
|
13
libusr/src/signal.rs
Normal file
13
libusr/src/signal.rs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
use libsys::{calls::sys_ex_sigreturn, signal::Signal};
|
||||||
|
use crate::trace;
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
pub(crate) extern "C" fn signal_handler(arg: Signal) -> ! {
|
||||||
|
trace!("Entered signal handler: arg={:?}", arg);
|
||||||
|
match arg {
|
||||||
|
Signal::Interrupt | Signal::SegmentationFault =>
|
||||||
|
loop {},
|
||||||
|
_ => todo!()
|
||||||
|
}
|
||||||
|
sys_ex_sigreturn();
|
||||||
|
}
|
@ -2,12 +2,14 @@ use alloc::{boxed::Box, sync::Arc, vec};
|
|||||||
use core::cell::UnsafeCell;
|
use core::cell::UnsafeCell;
|
||||||
use core::mem::MaybeUninit;
|
use core::mem::MaybeUninit;
|
||||||
use libsys::{
|
use libsys::{
|
||||||
calls::{sys_ex_clone, sys_ex_signal, sys_ex_thread_exit, sys_ex_thread_wait},
|
calls::{sys_ex_clone, sys_ex_signal, sys_ex_thread_exit, sys_ex_thread_wait, sys_ex_gettid},
|
||||||
error::Errno,
|
error::Errno,
|
||||||
proc::ExitCode,
|
proc::ExitCode,
|
||||||
};
|
};
|
||||||
|
use core::sync::atomic::{AtomicU32, Ordering};
|
||||||
use crate::trace;
|
use core::any::Any;
|
||||||
|
use crate::{trace, signal};
|
||||||
|
use core::fmt;
|
||||||
|
|
||||||
struct NativeData<F, T>
|
struct NativeData<F, T>
|
||||||
where
|
where
|
||||||
@ -16,26 +18,69 @@ where
|
|||||||
T: Send + 'static,
|
T: Send + 'static,
|
||||||
{
|
{
|
||||||
closure: F,
|
closure: F,
|
||||||
result: Arc<UnsafeCell<MaybeUninit<T>>>,
|
result: ThreadPacket<T>,
|
||||||
stack: usize,
|
stack: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Thread {
|
||||||
|
id: u32
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type ThreadResult<T> = Result<T, Box<dyn Any + Send + Sync>>;
|
||||||
|
pub type ThreadPacket<T> = Arc<UnsafeCell<MaybeUninit<ThreadResult<T>>>>;
|
||||||
|
|
||||||
pub struct JoinHandle<T> {
|
pub struct JoinHandle<T> {
|
||||||
native: u32,
|
native: u32,
|
||||||
result: Arc<UnsafeCell<MaybeUninit<T>>>,
|
result: ThreadPacket<T>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Thread {
|
||||||
|
pub const fn id(&self) -> u32 {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for Thread {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
f.debug_struct("Thread").field("id", &self.id).finish_non_exhaustive()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> JoinHandle<T> {
|
impl<T> JoinHandle<T> {
|
||||||
pub fn join(self) -> Result<T, ()> {
|
pub fn join(self) -> ThreadResult<T> {
|
||||||
sys_ex_thread_wait(self.native).unwrap();
|
sys_ex_thread_wait(self.native).unwrap();
|
||||||
if let Ok(result) = Arc::try_unwrap(self.result) {
|
unsafe { Arc::try_unwrap(self.result).unwrap().into_inner().assume_init() }
|
||||||
Ok(unsafe { result.into_inner().assume_init() })
|
|
||||||
} else {
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe fn init_common(signal_stack_pointer: *mut u8) {
|
||||||
|
let tid = sys_ex_gettid();
|
||||||
|
asm!("msr tpidr_el0, {}", in(reg) tid);
|
||||||
|
|
||||||
|
// thread::current() should be valid at this point
|
||||||
|
|
||||||
|
sys_ex_signal(
|
||||||
|
signal::signal_handler as usize,
|
||||||
|
signal_stack_pointer as usize
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) unsafe fn init_main() {
|
||||||
|
static mut SIGNAL_STACK: [u8; 4096] = [0; 4096];
|
||||||
|
init_common(SIGNAL_STACK.as_mut_ptr().add(SIGNAL_STACK.len()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn current() -> Thread {
|
||||||
|
let mut id: u32;
|
||||||
|
unsafe {
|
||||||
|
asm!("mrs {}, tpidr_el0", out(reg) id);
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread { id }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn spawn<F, T>(f: F) -> JoinHandle<T>
|
pub fn spawn<F, T>(f: F) -> JoinHandle<T>
|
||||||
where
|
where
|
||||||
F: FnOnce() -> T,
|
F: FnOnce() -> T,
|
||||||
@ -57,18 +102,14 @@ where
|
|||||||
let mut signal_stack = vec![0u8; 8192];
|
let mut signal_stack = vec![0u8; 8192];
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
sys_ex_signal(
|
init_common(signal_stack.as_mut_ptr().add(signal_stack.len()));
|
||||||
crate::_signal_handler as usize,
|
|
||||||
signal_stack.as_mut_ptr() as usize + signal_stack.len(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let data: Box<NativeData<F, T>> = unsafe { Box::from_raw(data) };
|
let data: Box<NativeData<F, T>> = unsafe { Box::from_raw(data) };
|
||||||
let res = (data.closure)();
|
let res = (data.closure)();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
(&mut *data.result.get()).write(res);
|
(&mut *data.result.get()).write(Ok(res));
|
||||||
}
|
}
|
||||||
|
|
||||||
(data.stack, 8192)
|
(data.stack, 8192)
|
||||||
|
@ -7,7 +7,7 @@ extern crate libusr;
|
|||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
fn main() -> i32 {
|
fn main() -> i32 {
|
||||||
let pid = libusr::sys::sys_fork().unwrap();
|
let pid = unsafe { libusr::sys::sys_fork().unwrap() };
|
||||||
|
|
||||||
if let Some(pid) = pid {
|
if let Some(pid) = pid {
|
||||||
let mut status = 0;
|
let mut status = 0;
|
||||||
|
@ -27,7 +27,7 @@ fn execute(line: &str) -> Result<ExitCode, Errno> {
|
|||||||
let mut words = line.split(' ');
|
let mut words = line.split(' ');
|
||||||
let cmd = words.next().unwrap();
|
let cmd = words.next().unwrap();
|
||||||
|
|
||||||
if let Some(pid) = sys_fork()? {
|
if let Some(pid) = unsafe { sys_fork()? } {
|
||||||
let mut status = 0;
|
let mut status = 0;
|
||||||
sys_waitpid(pid, &mut status)?;
|
sys_waitpid(pid, &mut status)?;
|
||||||
Ok(ExitCode::from(status))
|
Ok(ExitCode::from(status))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user