diff --git a/src/main.c b/src/main.c index e5eac44..3f70542 100644 --- a/src/main.c +++ b/src/main.c @@ -92,6 +92,7 @@ ACTIVE_INPUT_TASK = test_user; ThreadHandle* h = kmalloc(sizeof(ThreadHandle)); + h->refcount = 1; h->task = test_user; h->exited = false; memset(&h->lock, 0, sizeof(Mutex)); diff --git a/src/sched/process.c b/src/sched/process.c index 280cb1a..6b26ccd 100644 --- a/src/sched/process.c +++ b/src/sched/process.c @@ -165,8 +165,13 @@ void process_destroy(Process* process) { switch (type) { case HANDLE_TYPE_THREAD: - kfree(data, sizeof(ThreadHandle)); + { + ThreadHandle* h = (ThreadHandle*) data; + if (--h->refcount == 0) { + kfree(data, sizeof(ThreadHandle)); + } break; + } case HANDLE_TYPE_DEVICE: ((GenericDevice*) data)->refcount -= 1; break; diff --git a/src/sched/task.h b/src/sched/task.h index 63beebb..78f8163 100644 --- a/src/sched/task.h +++ b/src/sched/task.h @@ -23,8 +23,9 @@ typedef struct { Task* task; int status; }; - bool exited; Mutex lock; + usize refcount; + bool exited; } ThreadHandle; typedef struct { diff --git a/src/sys/syscalls.c b/src/sys/syscalls.c index 74f773d..4fed49d 100644 --- a/src/sys/syscalls.c +++ b/src/sys/syscalls.c @@ -249,6 +249,7 @@ Handle sys_create_thread(void (*fn)(void*), void* arg) { mutex_unlock(&process->threads_lock); return INVALID_HANDLE; } + handle->refcount = 1; Task* task = arch_create_user_task(self->process, "user thread", fn, arg); if (!task) { @@ -433,8 +434,13 @@ int sys_close(Handle handle) { if (handle_tab_close(&arch_get_cur_task()->process->handle_table, handle)) { switch (type) { case HANDLE_TYPE_THREAD: - kfree(data, sizeof(ThreadHandle)); + { + ThreadHandle* h = (ThreadHandle*) data; + if (--h->refcount == 0) { + kfree(data, sizeof(ThreadHandle)); + } break; + } case HANDLE_TYPE_DEVICE: ((GenericDevice*) data)->refcount -= 1; break; diff --git a/src/utils/handle.c b/src/utils/handle.c index 28c59d1..3edc3ec 100644 --- a/src/utils/handle.c +++ b/src/utils/handle.c @@ -4,6 +4,7 @@ #include "sys/dev.h" #include "fs/vfs.h" #include "sys/fs.h" +#include "sched/task.h" Handle handle_tab_insert(HandleTable* self, void* data, HandleType type) { mutex_lock(&self->lock); @@ -131,9 +132,13 @@ bool handle_tab_duplicate(HandleTable* self, HandleTable* ret) { switch (type) { case HANDLE_TYPE_THREAD: - //kfree(data, sizeof(ThreadHandle)); - // todo refcount + { + ThreadHandle* h = (ThreadHandle*) data; + if (--h->refcount == 0) { + kfree(data, sizeof(ThreadHandle)); + } break; + } case HANDLE_TYPE_DEVICE: ((GenericDevice*) data)->refcount += 1; break;