Properly deallocate thread stack on pthread_exit.

This commit is contained in:
4lDO2
2024-08-05 13:22:18 +02:00
parent af6435e12d
commit fed49a29af
5 changed files with 26 additions and 14 deletions
+16 -4
View File
@@ -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!()
}
+1 -1
View File
@@ -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)
}
+1 -1
View File
@@ -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;
+2 -2
View File
@@ -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
View File
@@ -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;