From 02a44f67b9538c0f7a99c5e60a29cd7cf8974e67 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Thu, 30 Apr 2026 19:06:46 +0100 Subject: [PATCH] sched: task: implement task creation flags --- include/kernel/syscall.h | 1 + include/kernel/task.h | 5 +++-- init/main.c | 3 ++- sched/task.c | 20 +++++++++++++++----- syscall/task.c | 19 +++++-------------- 5 files changed, 26 insertions(+), 22 deletions(-) diff --git a/include/kernel/syscall.h b/include/kernel/syscall.h index 8fef94d..edbe5bf 100644 --- a/include/kernel/syscall.h +++ b/include/kernel/syscall.h @@ -42,6 +42,7 @@ extern kern_status_t sys_task_exit(int status); extern kern_status_t sys_task_self(kern_handle_t *out); extern kern_status_t sys_task_create( kern_handle_t parent_handle, + task_flags_t flags, const char *name, size_t name_len, kern_handle_t *out_task, diff --git a/include/kernel/task.h b/include/kernel/task.h index d3f6751..7d6283f 100644 --- a/include/kernel/task.h +++ b/include/kernel/task.h @@ -40,9 +40,10 @@ struct task { extern struct task *task_alloc(void); extern struct task *task_cast(struct object *obj); extern struct task *task_create( + struct task *parent, + task_flags_t flags, const char *name, - size_t name_len, - struct handle_table *handles); + size_t name_len); static inline struct task *task_ref(struct task *task) { return OBJECT_CAST(struct task, t_base, object_ref(&task->t_base)); diff --git a/init/main.c b/init/main.c index abf6c72..2059af5 100644 --- a/init/main.c +++ b/init/main.c @@ -108,7 +108,8 @@ void kernel_init(uintptr_t arg) bsp.bsp_trailer.bsp_exec_entry, bsp.bsp_vmo); - struct task *bootstrap_task = task_create("bootstrap", 9, NULL); + struct task *bootstrap_task + = task_create(NULL, TASK_F_DEFAULT, "bootstrap", 9); tracek("created bootstrap task (pid=%u)", bootstrap_task->t_id); status = bsp_launch_async(&bsp, bootstrap_task); diff --git a/sched/task.c b/sched/task.c index 9b64973..54064f2 100644 --- a/sched/task.c +++ b/sched/task.c @@ -172,10 +172,12 @@ struct task *task_alloc(void) } struct task *task_create( + struct task *parent, + task_flags_t task_flags, const char *name, - size_t name_len, - struct handle_table *handles) + size_t name_len) { + kern_status_t status = KERN_OK; struct task *task = task_alloc(); if (!task) { return NULL; @@ -194,13 +196,21 @@ struct task *task_create( VM_USER_LIMIT, &task->t_address_space); - if (!handles) { - handles = handle_table_create(); + if (task_flags & TASK_F_CLONE_ALL_HANDLES) { + status = handle_table_duplicate( + parent->t_handles, + &task->t_handles); + } else { + task->t_handles = handle_table_create(); + } + + if (status != KERN_OK) { + object_unref(&task->t_base); + return NULL; } task->t_address_space->s_pmap = pmap; task->t_state = TASK_RUNNING; - task->t_handles = handles; if (name) { name_len = MIN(name_len, sizeof task->t_name - 1); diff --git a/syscall/task.c b/syscall/task.c index ee3395d..90fbc9d 100644 --- a/syscall/task.c +++ b/syscall/task.c @@ -53,6 +53,7 @@ kern_status_t sys_task_self(kern_handle_t *out) kern_status_t sys_task_create( kern_handle_t parent_handle, + task_flags_t task_flags, const char *name, size_t name_len, kern_handle_t *out_task, @@ -124,7 +125,7 @@ kern_status_t sys_task_create( task_unlock_irqrestore(self, flags); - struct task *child = task_create(name, name_len, NULL); + struct task *child = task_create(parent, task_flags, name, name_len); if (!child) { object_unref(parent_obj); @@ -468,14 +469,6 @@ kern_status_t sys_task_duplicate( unsigned long flags; task_lock_irqsave(self, &flags); - struct handle_table *child_handle_table = NULL; - status = handle_table_duplicate(self->t_handles, &child_handle_table); - if (status != KERN_OK) { - task_unlock_irqrestore(self, flags); - put_current_task(self); - return status; - } - struct handle *child_handle_slot = NULL, *space_handle_slot = NULL; kern_handle_t child_handle, space_handle; status = handle_table_alloc_handle( @@ -484,7 +477,6 @@ kern_status_t sys_task_duplicate( &child_handle_slot, &child_handle); if (status != KERN_OK) { - handle_table_destroy(child_handle_table); task_unlock_irqrestore(self, flags); put_current_task(self); return status; @@ -496,7 +488,6 @@ kern_status_t sys_task_duplicate( &space_handle_slot, &space_handle); if (status != KERN_OK) { - handle_table_destroy(child_handle_table); handle_table_free_handle(self->t_handles, child_handle); task_unlock_irqrestore(self, flags); put_current_task(self); @@ -504,11 +495,11 @@ kern_status_t sys_task_duplicate( } struct task *new_task = task_create( + self, + TASK_F_CLONE_ALL_HANDLES, self->t_name, - strlen(self->t_name), - child_handle_table); + strlen(self->t_name)); if (!new_task) { - handle_table_destroy(child_handle_table); put_current_task(self); return KERN_NO_MEMORY; }