mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-02 07:28:21 +00:00
sched: handle thread death in a less hacky way
This commit is contained in:
@@ -18,6 +18,7 @@
|
|||||||
#define THREAD_STATE_BLOCKED 2
|
#define THREAD_STATE_BLOCKED 2
|
||||||
#define THREAD_STATE_BLOCKED_INTR 3
|
#define THREAD_STATE_BLOCKED_INTR 3
|
||||||
#define THREAD_STATE_DEAD 4
|
#define THREAD_STATE_DEAD 4
|
||||||
|
#define THREAD_STATE_DESTROYED 5
|
||||||
|
|
||||||
#define PROC_STATE_NORMAL 0
|
#define PROC_STATE_NORMAL 0
|
||||||
#define PROC_STATE_ZOMBIE 1
|
#define PROC_STATE_ZOMBIE 1
|
||||||
|
|||||||
@@ -49,11 +49,6 @@ void syscall_exit(int status){
|
|||||||
|
|
||||||
event_signal(&proc->parent->childevent, true);
|
event_signal(&proc->parent->childevent, true);
|
||||||
|
|
||||||
// context and thread destruction will happen in the waitpid()
|
|
||||||
// the pointer to this thread will reside in proc->threads
|
|
||||||
|
|
||||||
proc->threads = arch_getcls()->thread;
|
|
||||||
|
|
||||||
arch_interrupt_disable();
|
arch_interrupt_disable();
|
||||||
|
|
||||||
spinlock_release(&proc->lock);
|
spinlock_release(&proc->lock);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <arch/cls.h>
|
#include <arch/cls.h>
|
||||||
#include <arch/spinlock.h>
|
#include <arch/spinlock.h>
|
||||||
#include <kernel/alloc.h>
|
#include <kernel/alloc.h>
|
||||||
|
#include <arch/interrupt.h>
|
||||||
|
|
||||||
#define UNSUPPORTED "astral: waitpid: Unsupported waitpid options!\n"
|
#define UNSUPPORTED "astral: waitpid: Unsupported waitpid options!\n"
|
||||||
#define UNSUPPORTED_PG "astral: waitpid: Process group waits are not supported yet.\n"
|
#define UNSUPPORTED_PG "astral: waitpid: Process group waits are not supported yet.\n"
|
||||||
@@ -96,15 +97,48 @@ syscallret syscall_waitpid(pid_t pid, int *status, int options){
|
|||||||
if(status)
|
if(status)
|
||||||
*status = child->status; // XXX safer way of doing this
|
*status = child->status; // XXX safer way of doing this
|
||||||
|
|
||||||
// the pointer to the last remaining thread is is proc->threads
|
int threadc = proc->threadcount;
|
||||||
|
|
||||||
thread_t* thread = child->threads;
|
// free all the threads
|
||||||
|
|
||||||
|
while(proc->threadcount){
|
||||||
|
|
||||||
|
for(int t = 0; t < threadc; ++t){
|
||||||
|
|
||||||
|
thread_t* thread = proc->threads[t];
|
||||||
|
|
||||||
|
// XXX possible race condition here?
|
||||||
|
|
||||||
|
if(thread->state != THREAD_STATE_DEAD)
|
||||||
|
continue;
|
||||||
|
|
||||||
free(thread->regs);
|
free(thread->regs);
|
||||||
free(thread->kernelstackbase);
|
free(thread->kernelstackbase);
|
||||||
vmm_destroy(thread->ctx);
|
vmm_destroy(thread->ctx);
|
||||||
|
|
||||||
|
thread->state = THREAD_STATE_DESTROYED;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
arch_interrupt_disable();
|
||||||
|
|
||||||
|
sched_yield();
|
||||||
|
|
||||||
|
arch_interrupt_enable();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int t = 0; t < threadc; ++t){
|
||||||
|
|
||||||
|
thread_t* thread = proc->threads[t];
|
||||||
|
|
||||||
|
if(thread->state != THREAD_STATE_DESTROYED)
|
||||||
|
_panic("Freeing non-destroyed thread", NULL);
|
||||||
|
|
||||||
free(thread);
|
free(thread);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
free(child);
|
free(child);
|
||||||
|
|
||||||
retv.ret = child->pid;
|
retv.ret = child->pid;
|
||||||
|
|||||||
Reference in New Issue
Block a user