Properly deallocate thread stack on pthread_exit.
This commit is contained in:
+16
-4
@@ -1,6 +1,8 @@
|
||||
use core::mem::size_of;
|
||||
|
||||
use syscall::{Result, O_CLOEXEC};
|
||||
|
||||
use crate::{arch::*, proc::*, RtTcb};
|
||||
use crate::{arch::*, proc::*, signal::tmp_disable_signals, RtTcb};
|
||||
|
||||
/// 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) -> Result<FdGuard> {
|
||||
@@ -48,10 +50,20 @@ pub unsafe fn rlct_clone_impl(stack: *mut usize) -> Result<FdGuard> {
|
||||
Ok(new_thr_fd)
|
||||
}
|
||||
|
||||
pub fn exit_this_thread() -> ! {
|
||||
let thread_fd = RtTcb::current().thread_fd();
|
||||
pub unsafe fn exit_this_thread(stack_base: *mut (), stack_size: usize) -> ! {
|
||||
let _guard = tmp_disable_signals();
|
||||
|
||||
let tcb = RtTcb::current();
|
||||
let thread_fd = tcb.thread_fd();
|
||||
|
||||
let _ = syscall::funmap(tcb as *const RtTcb as usize, syscall::PAGE_SIZE);
|
||||
|
||||
// TODO: modify interface so it writes directly to the thread fd?
|
||||
let status_fd = syscall::dup(**thread_fd, b"status").unwrap();
|
||||
syscall::write(status_fd, &usize::MAX.to_ne_bytes()).unwrap();
|
||||
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]);
|
||||
syscall::write(status_fd, &buf).unwrap();
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ impl Pal for Sys {
|
||||
}
|
||||
loop {}
|
||||
}
|
||||
fn exit_thread() -> ! {
|
||||
unsafe fn exit_thread(_stack_base: *mut (), _stack_size: usize) -> ! {
|
||||
// TODO
|
||||
Self::exit(0)
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ pub trait Pal {
|
||||
|
||||
fn exit(status: c_int) -> !;
|
||||
|
||||
fn exit_thread() -> !;
|
||||
unsafe fn exit_thread(stack_base: *mut (), stack_size: usize) -> !;
|
||||
|
||||
fn fchdir(fildes: c_int) -> c_int;
|
||||
|
||||
|
||||
@@ -1137,7 +1137,7 @@ impl Pal for Sys {
|
||||
(unsafe { syscall::syscall5(syscall::number::SYS_GETPID, !0, !0, !0, !0, !0) }).is_ok()
|
||||
}
|
||||
|
||||
fn exit_thread() -> ! {
|
||||
redox_rt::thread::exit_this_thread()
|
||||
unsafe fn exit_thread(stack_base: *mut (), stack_size: usize) -> ! {
|
||||
redox_rt::thread::exit_this_thread(stack_base, stack_size)
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -2,7 +2,7 @@
|
||||
|
||||
use core::{
|
||||
cell::{Cell, UnsafeCell},
|
||||
mem::MaybeUninit,
|
||||
mem::{offset_of, MaybeUninit},
|
||||
ptr::{addr_of, NonNull},
|
||||
sync::atomic::{AtomicBool, AtomicUsize, Ordering},
|
||||
};
|
||||
@@ -22,8 +22,6 @@ use crate::{
|
||||
|
||||
use crate::sync::{waitval::Waitval, Mutex};
|
||||
|
||||
const MAIN_PTHREAD_ID: usize = 1;
|
||||
|
||||
/// Called only by the main thread, as part of relibc_start.
|
||||
pub unsafe fn init() {
|
||||
Tcb::current()
|
||||
@@ -269,7 +267,7 @@ 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);
|
||||
.fetch_or(PthreadFlags::DETACHED.bits(), Ordering::AcqRel);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -294,6 +292,8 @@ pub unsafe fn exit_current_thread(retval: Retval) -> ! {
|
||||
header::tls::run_all_destructors();
|
||||
|
||||
let this = current_thread().expect("failed to obtain current thread when exiting");
|
||||
let stack_base = this.stack_base;
|
||||
let stack_size = this.stack_size;
|
||||
|
||||
if this.flags.load(Ordering::Acquire) & PthreadFlags::DETACHED.bits() != 0 {
|
||||
// When detached, the thread state no longer makes any sense, and can immediately be
|
||||
@@ -304,12 +304,12 @@ pub unsafe fn exit_current_thread(retval: Retval) -> ! {
|
||||
this.waitval.post(retval);
|
||||
}
|
||||
|
||||
Sys::exit_thread()
|
||||
Sys::exit_thread(stack_base.cast(), stack_size)
|
||||
}
|
||||
|
||||
unsafe fn dealloc_thread(thread: &Pthread) {
|
||||
// TODO: How should this be handled on Linux?
|
||||
OS_TID_TO_PTHREAD.lock().remove(&thread.os_tid.get().read());
|
||||
//drop(Box::from_raw(thread as *const Pthread as *mut Pthread));
|
||||
}
|
||||
pub const SIGRT_RLCT_CANCEL: usize = 33;
|
||||
pub const SIGRT_RLCT_TIMER: usize = 34;
|
||||
|
||||
Reference in New Issue
Block a user