Better cleanup of dead threads

This commit is contained in:
Mark
2020-02-03 13:59:00 +02:00
parent 32f51f53f0
commit b6d2cfb9b3
2 changed files with 107 additions and 1 deletions
+33
View File
@@ -1,4 +1,6 @@
#include "sys/amd64/context.h"
#include "sys/amd64/mm/pool.h"
#include "sys/amd64/mm/phys.h"
#include "sys/amd64/hw/irq.h"
#include "sys/amd64/hw/idt.h"
#include "sys/user/signum.h"
@@ -8,6 +10,7 @@
#include "sys/thread.h"
#include "sys/sched.h"
#include "sys/debug.h"
#include "sys/heap.h"
#include "sys/mm.h"
void yield(void);
@@ -146,6 +149,12 @@ void sched_debug_cycle(uint64_t delta_ms) {
struct thread *thr = queue_head;
extern struct thread user_init;
struct heap_stat st;
struct amd64_phys_stat phys_st;
struct amd64_pool_stat pool_st;
kdebug("--- DEBUG_CYCLE ---\n");
debugs(DEBUG_DEFAULT, "Process tree:\n");
sched_debug_tree(DEBUG_DEFAULT, &user_init, 0);
@@ -167,6 +176,30 @@ void sched_debug_cycle(uint64_t delta_ms) {
} else {
kdebug("--- IDLE\n");
}
heap_stat(heap_global, &st);
kdebug("Heap stat:\n");
kdebug("Allocated blocks: %u\n", st.alloc_count);
kdebug("Used %S, free %S, total %S\n", st.alloc_size, st.free_size, st.total_size);
amd64_phys_stat(&phys_st);
kdebug("Physical memory:\n");
kdebug("Used %S (%u), free %S (%u), ceiling %p\n",
phys_st.pages_used * 0x1000,
phys_st.pages_used,
phys_st.pages_free * 0x1000,
phys_st.pages_free,
phys_st.limit);
amd64_mm_pool_stat(&pool_st);
kdebug("Paging pool:\n");
kdebug("Used %S (%u), free %S (%u)\n",
pool_st.pages_used * 0x1000,
pool_st.pages_used,
pool_st.pages_free * 0x1000,
pool_st.pages_free);
kdebug("--- ----------- ---\n");
}
void yield(void) {
+74 -1
View File
@@ -57,6 +57,24 @@ static void thread_add(struct thread *thr) {
threads_all_head = thr;
}
static void thread_remove(struct thread *thr) {
struct thread *prev = thr->g_prev;
struct thread *next = thr->g_next;
if (prev) {
prev->g_next = next;
} else {
threads_all_head = next;
}
if (next) {
next->g_prev = prev;
}
thr->g_next = NULL;
thr->g_prev = NULL;
}
////
static void thread_ioctx_empty(struct thread *thr) {
@@ -113,6 +131,32 @@ struct thread *thread_child(struct thread *of, pid_t pid) {
return NULL;
}
void thread_unchild(struct thread *thr) {
struct thread *par = thr->parent;
_assert(par);
struct thread *p = NULL;
struct thread *c = par->first_child;
int found = 0;
while (c) {
if (c == thr) {
found = 1;
if (p) {
p->next_child = thr->next_child;
} else {
par->first_child = thr->next_child;
}
break;
}
p = c;
c = c->next_child;
}
_assert(found);
}
void thread_cleanup(struct thread *thr) {
_assert(thr);
// Leave only the system context required for hierachy tracking and error code/pid
@@ -136,6 +180,30 @@ void thread_cleanup(struct thread *thr) {
mm_space_release(thr->space);
}
void thread_free(struct thread *thr) {
_assert(thr->flags & THREAD_STOPPED);
_assert(thr->flags & THREAD_EMPTY);
// Free kstack
for (size_t i = 0; i < thr->data.rsp0_size / MM_PAGE_SIZE; ++i) {
amd64_phys_free(MM_PHYS(i * MM_PAGE_SIZE + thr->data.rsp0_base));
}
// Free page directory (if not mm_kernel)
if (thr->space != mm_kernel) {
// Make sure we don't shoot a leg off
uintptr_t cr3;
asm volatile ("movq %%cr3, %0":"=a"(cr3));
_assert(MM_VIRTUALIZE(cr3) != (uintptr_t) thr->space);
mm_space_free(thr->space);
}
// Free thread itself
memset(thr, 0, sizeof(struct thread));
kfree(thr);
}
int thread_init(struct thread *thr, uintptr_t entry, void *arg, int user) {
uintptr_t stack_pages = amd64_phys_alloc_contiguous(2);
_assert(stack_pages != MM_NADDR);
@@ -552,11 +620,16 @@ int sys_waitpid(pid_t pid, int *status) {
thread_check_signal(thr, 0);
}
// Make sure no platform context remains
_assert(chld->flags & THREAD_EMPTY);
if (status) {
*status = chld->exit_status;
}
// TODO: Cleanup the child here
thread_unchild(chld);
thread_remove(chld);
thread_free(chld);
return 0;
}