From 5c93d9b8ba57d49b0f10cff25ee876b441def4e8 Mon Sep 17 00:00:00 2001 From: Bahadir Balban Date: Sat, 31 Oct 2009 01:44:32 +0200 Subject: [PATCH] Added thread_wait modified: conts/test/main.c modified: scripts/kernel/generate_kernel_cinfo.py modified: src/api/thread.c modified: src/generic/capability.c --- conts/test/main.c | 8 +++- scripts/kernel/generate_kernel_cinfo.py | 2 +- src/api/thread.c | 52 ++++++++++++++++++++++++- src/generic/capability.c | 9 +++-- 4 files changed, 63 insertions(+), 8 deletions(-) diff --git a/conts/test/main.c b/conts/test/main.c index aa863ae..4e48ed9 100644 --- a/conts/test/main.c +++ b/conts/test/main.c @@ -11,6 +11,7 @@ #include #include #include +# int exit_test_thread(void *arg) { @@ -32,6 +33,7 @@ int exit_test(void) } else printf("Thread (%d) created successfully.\n", ids.tid); +#if 0 /* Kill it */ printf("Killing Thread (%d).\n", ids.tid); if ((ret = l4_thread_control(THREAD_DESTROY, &ids)) < 0) @@ -39,7 +41,10 @@ int exit_test(void) else printf("Success: Killed Thread (%d)\n", ids.tid); -#if 0 +#endif + + l4_thread_switch(0); + /* Wait on it */ printf("Waiting on Thread (%d) to exit.\n", ids.tid); if ((ret = l4_thread_control(THREAD_WAIT, &ids)) >= 0) @@ -47,7 +52,6 @@ int exit_test(void) else printf("Error. Wait on (%d) failed. err = %d\n", ids.tid, ret); -#endif return 0; out_err: diff --git a/scripts/kernel/generate_kernel_cinfo.py b/scripts/kernel/generate_kernel_cinfo.py index 12c7918..dcc9a54 100755 --- a/scripts/kernel/generate_kernel_cinfo.py +++ b/scripts/kernel/generate_kernel_cinfo.py @@ -110,7 +110,7 @@ cap_all_others = \ \t\t\t\t.type = CAP_TYPE_TCTRL | CAP_RTYPE_CONTAINER, \t\t\t\t.access = CAP_TCTRL_CREATE | CAP_TCTRL_DESTROY \t\t\t\t | CAP_TCTRL_SUSPEND | CAP_TCTRL_RUN -\t\t\t\t | CAP_TCTRL_RECYCLE, +\t\t\t\t | CAP_TCTRL_RECYCLE | CAP_TCTRL_WAIT, \t\t\t\t.start = 0, .end = 0, .size = 0, \t\t\t}, \t\t\t[%d] = { diff --git a/src/api/thread.c b/src/api/thread.c index ef2894b..5115b7c 100644 --- a/src/api/thread.c +++ b/src/api/thread.c @@ -49,6 +49,48 @@ int thread_signal_sync(struct ktcb *task, unsigned int flags, return ret; } +int thread_wait(struct task_ids *ids) +{ + struct ktcb *task, *n; + int ret; + + if (!(task = tcb_find(ids->tid))) { + /* Retry in own queue till we find it */ +retry: + spin_lock(¤t->child_exit_list.list_lock); + list_foreach_removable_struct(task, n, + ¤t->child_exit_list.list, + task_list) { + if (task->tid == ids->tid) { + printk("%s: Found (%d) in exit queue.\n", + __FUNCTION__, task->tid); + list_remove(&task->task_list); + tcb_delete(task); + spin_unlock(¤t->child_exit_list.list_lock); + return 0; + } + } + spin_unlock(¤t->child_exit_list.list_lock); + schedule(); + goto retry; + } + + printk("%s: Found (%d) in global queue.\n", + __FUNCTION__, task->tid); + + /* Got a handle on the task, wait on it conditionally */ + WAIT_EVENT(&task->wqh_pager, + task->state == TASK_INACTIVE, ret); + + /* + * We found it in global queue but + * now it must be in exit queue + */ + ktcb_list_remove(task, ¤t->child_exit_list); + tcb_delete(task); + return 0; +} + int thread_suspend(struct ktcb *task) { return thread_signal_sync(task, TASK_SUSPENDING, TASK_INACTIVE); @@ -130,8 +172,10 @@ int thread_destroy(struct ktcb *task) if (child->pagerid == current->tid && child != current) { spin_unlock(&curcont->ktcb_list.list_lock); + + /* Its a bug since nobody can interrupt us */ BUG_ON(thread_signal_sync(child, TASK_EXITING, - TASK_INACTIVE) < 0); + TASK_INACTIVE) < 0); spin_lock(&curcont->ktcb_list.list_lock); } } @@ -370,7 +414,8 @@ int sys_thread_control(unsigned int flags, struct task_ids *ids) MAP_USR_RW_FLAGS, 1)) < 0) return err; - if ((flags & THREAD_ACTION_MASK) != THREAD_CREATE) + if ((flags & THREAD_ACTION_MASK) != THREAD_CREATE && + (flags & THREAD_ACTION_MASK) != THREAD_WAIT) if (!(task = tcb_find(ids->tid))) return -ESRCH; @@ -393,6 +438,9 @@ int sys_thread_control(unsigned int flags, struct task_ids *ids) case THREAD_RECYCLE: ret = thread_recycle(task); break; + case THREAD_WAIT: + ret = thread_wait(ids); + break; default: ret = -EINVAL; diff --git a/src/generic/capability.c b/src/generic/capability.c index 493ce09..889a2a1 100644 --- a/src/generic/capability.c +++ b/src/generic/capability.c @@ -447,10 +447,13 @@ struct capability *cap_match_thread(struct capability *cap, } /* If no target and create, or vice versa, it really is a bug */ - BUG_ON(!target && action_flags != THREAD_CREATE); - BUG_ON(target && action_flags == THREAD_CREATE); + BUG_ON(!target && (action_flags != THREAD_CREATE && + action_flags != THREAD_WAIT)); + BUG_ON(target && (action_flags == THREAD_CREATE || + action_flags == THREAD_WAIT)); - if (action_flags == THREAD_CREATE) { + if (action_flags == THREAD_CREATE || + action_flags == THREAD_WAIT) { /* * FIXME: Add cid to task_ids arg. *