waitpid: use event instead of busy loop when waiting for threads to die

This commit is contained in:
Matheus
2026-04-16 22:41:43 -03:00
parent 4e3c41df39
commit 3dfb6b5a8c
4 changed files with 27 additions and 6 deletions
+1
View File
@@ -36,6 +36,7 @@ typedef struct proc_t {
cred_t cred;
spinlock_t threadlistlock;
thread_t *threadlist;
eventheader_t thread_exit_event;
bool nomorethreads;
size_t runningthreadcount;
size_t fdcount;
+12 -3
View File
@@ -107,6 +107,7 @@ proc_t *proc_create() {
itimer_init(&proc->timer.profiling, profdpc, proc);
SPINLOCK_INIT(proc->threadlistlock);
EVENT_INITHEADER(&proc->child_exit_event);
EVENT_INITHEADER(&proc->thread_exit_event);
proc->fd = alloc(sizeof(fd_t) * 3);
if (proc->fd == NULL) {
@@ -173,10 +174,18 @@ void proc_stop_other_threads() {
threadlist = threadlist->procnext;
}
while (__atomic_load_n(&proc->runningthreadcount, __ATOMIC_SEQ_CST) > 1) {
arch_e9_puts("proc_stop_other_threads\n");
sched_yield();
eventlistener_t listener;
EVENT_INITLISTENER(&listener);
for (;;) {
EVENT_ATTACH(&listener, &proc->thread_exit_event);
if (__atomic_load_n(&proc->runningthreadcount, __ATOMIC_SEQ_CST) == 1)
break;
EVENT_WAIT(&listener, 0);
EVENT_DETACHALL(&listener);
}
EVENT_DETACHALL(&listener);
proc->nomorethreads = false;
}
+12 -3
View File
@@ -132,10 +132,19 @@ syscallret_t syscall_waitpid(context_t *context, pid_t pid, int *status, int opt
while (threadlist) {
thread_t *freethread = threadlist;
threadlist = threadlist->procnext;
volatile int *flags = (volatile int *)(&freethread->flags);
// wait until the thread can actually be unallocated
while ((*flags & THREAD_FLAGS_DEAD) == 0)
sched_yield();
eventlistener_t listener;
EVENT_INITLISTENER(&listener);
for (;;) {
EVENT_ATTACH(&listener, &iterator->thread_exit_event);
if (freethread->flags & THREAD_FLAGS_DEAD) {
EVENT_DETACHALL(&listener);
break;
}
EVENT_WAIT(&listener, 0);
EVENT_DETACHALL(&listener);
}
sched_destroythread(freethread);
}
+2
View File
@@ -70,6 +70,8 @@ static void threadexit_internal(context_t *, void *) {
current_cpu()->thread = NULL;
thread->flags |= THREAD_FLAGS_DEAD;
if (thread->proc)
EVENT_SIGNAL(&thread->proc->thread_exit_event);
// because a thread deallocating its own data is a nightmare, thread deallocation and such will be left to whoever frees the proc it's tied to
// (likely an exit(2) call)