1b3e94a20d
From release 0.1.0 pre-patched archive. This includes all Red Bear modifications previously maintained as patches in local/patches/relibc/.
71 lines
2.4 KiB
Rust
71 lines
2.4 KiB
Rust
use core::mem::size_of;
|
|
|
|
use syscall::Result;
|
|
|
|
use crate::{RtTcb, arch::*, proc::*, signal::tmp_disable_signals, static_proc_info};
|
|
|
|
/// Spawns a new context sharing the same address space as the current one (i.e. a new thread).
|
|
pub unsafe fn rlct_clone_impl(stack: *mut usize, tcb: &RtTcb) -> Result<usize> {
|
|
let proc_info = static_proc_info();
|
|
let cur_proc_fd = proc_info.proc_fd.as_ref().unwrap();
|
|
|
|
let cur_thr_fd = RtTcb::current().thread_fd();
|
|
let new_thr_fd = cur_proc_fd.dup(b"new-thread")?.to_upper().unwrap();
|
|
|
|
// Inherit existing address space
|
|
{
|
|
let cur_addr_space_fd = cur_thr_fd.dup(b"addrspace")?;
|
|
let new_addr_space_sel_fd = new_thr_fd.dup(b"current-addrspace")?;
|
|
|
|
let buf = create_set_addr_space_buf(
|
|
cur_addr_space_fd.as_raw_fd(),
|
|
__relibc_internal_rlct_clone_ret as *const () as usize,
|
|
stack as usize,
|
|
);
|
|
new_addr_space_sel_fd.write(&buf)?;
|
|
}
|
|
|
|
// Inherit reference to file table
|
|
{
|
|
let cur_filetable_fd = cur_thr_fd.dup(b"filetable")?;
|
|
let new_filetable_sel_fd = new_thr_fd.dup(b"current-filetable")?;
|
|
|
|
new_filetable_sel_fd.write(&usize::to_ne_bytes(cur_filetable_fd.as_raw_fd()))?;
|
|
}
|
|
|
|
// Since the signal handler is not yet initialized, signals specifically targeting the thread
|
|
// (relibc is only required to implement thread-specific signals that already originate from
|
|
// the same process) will be discarded. Process-specific signals will ignore this new thread,
|
|
// until it has initialized its own signal handler.
|
|
|
|
let start_fd = new_thr_fd.dup(b"start")?;
|
|
|
|
let fd = new_thr_fd.as_raw_fd();
|
|
unsafe {
|
|
tcb.thr_fd.get().write(Some(new_thr_fd));
|
|
}
|
|
|
|
// Unblock context.
|
|
start_fd.write(&[0])?;
|
|
|
|
Ok(fd)
|
|
}
|
|
|
|
pub unsafe fn exit_this_thread(stack_base: *mut (), stack_size: usize) -> ! {
|
|
let _guard = tmp_disable_signals();
|
|
|
|
let tcb = RtTcb::current();
|
|
// TODO: modify interface so it writes directly to the thread fd?
|
|
let status_fd = tcb.thread_fd().dup(b"status").unwrap();
|
|
|
|
let _ = unsafe { syscall::funmap(tcb as *const RtTcb as usize, syscall::PAGE_SIZE) };
|
|
|
|
let mut buf = [0; size_of::<usize>() * 3];
|
|
plain::slice_from_mut_bytes(&mut buf)
|
|
.unwrap()
|
|
.copy_from_slice(&[usize::MAX, stack_base as usize, stack_size]);
|
|
// TODO: SYS_CALL w/CONSUME
|
|
status_fd.write(&buf).unwrap();
|
|
unreachable!()
|
|
}
|