From 88ca2033f7e50d0bef0066a738faae79fcaf3279 Mon Sep 17 00:00:00 2001 From: Bahadir Balban Date: Sun, 9 Nov 2008 11:37:24 +0200 Subject: [PATCH] Now shared tcb parts freed correctly. --- tasks/fs0/src/task.c | 20 +++++++++++++++----- tasks/mm0/src/task.c | 36 +++++++++++++++++++++++++++++++----- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/tasks/fs0/src/task.c b/tasks/fs0/src/task.c index eb062aa..e172c43 100644 --- a/tasks/fs0/src/task.c +++ b/tasks/fs0/src/task.c @@ -143,15 +143,25 @@ struct tcb *tcb_create(struct tcb *orig, l4id_t tid, unsigned long utcb, return task; } -/* FIXME: Modify it to work with shared structures!!! */ +/* Free shared structures if no references left */ +void tcb_free_resources(struct tcb *task) +{ + + if (--task->fs_data->tcb_refs == 0) + kfree(task->fs_data); + + if (--task->files->tcb_refs == 0) { + kfree(task->files->fdpool); + kfree(task->files); + } + +} + void tcb_destroy(struct tcb *task) { global_remove_task(task); - if (--task->fs_data->tcb_refs == 0) - kfree(task->fs_data); - if (--task->files->tcb_refs == 0) - kfree(task->files); + tcb_free_resources(task); kfree(task); } diff --git a/tasks/mm0/src/task.c b/tasks/mm0/src/task.c index 1c42a93..4e3ad69 100644 --- a/tasks/mm0/src/task.c +++ b/tasks/mm0/src/task.c @@ -111,15 +111,41 @@ struct tcb *tcb_alloc_init(unsigned int flags) return task; } -/* NOTE: We may need to delete shared tcb parts here as well. */ +/* + * Free vmas, fd structure and utcb address. + * Make sure to sync all IO beforehand + */ +int task_free_resources(struct tcb *task) +{ + /* + * Threads may share file descriptor structure + * if no users left, free it. + */ + if (!(--task->files->tcb_refs)) + kfree(task->files); + + /* + * Threads may share the virtual space. + * if no users of the vma struct left, + * free it along with all its vma links. + */ + if (!(--task->vm_area_head->tcb_refs)) { + /* Free all vmas */ + task_release_vmas(task->vm_area_head); + + /* Free the head */ + kfree(task->vm_area_head); + } + + return 0; +} + int tcb_destroy(struct tcb *task) { global_remove_task(task); - if (--task->vm_area_head->tcb_refs == 0) - kfree(task->vm_area_head); - if (--task->files->tcb_refs == 0) - kfree(task->files); + /* Free all resources of the task */ + task_free_resources(task); kfree(task);