mirror of
https://github.com/drasko/codezero.git
synced 2026-03-15 00:31:50 +01:00
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
This commit is contained in:
@@ -11,6 +11,7 @@
|
|||||||
#include <l4lib/arch/syslib.h>
|
#include <l4lib/arch/syslib.h>
|
||||||
#include <l4lib/arch/syscalls.h>
|
#include <l4lib/arch/syscalls.h>
|
||||||
#include <l4/api/space.h>
|
#include <l4/api/space.h>
|
||||||
|
#
|
||||||
|
|
||||||
int exit_test_thread(void *arg)
|
int exit_test_thread(void *arg)
|
||||||
{
|
{
|
||||||
@@ -32,6 +33,7 @@ int exit_test(void)
|
|||||||
} else
|
} else
|
||||||
printf("Thread (%d) created successfully.\n", ids.tid);
|
printf("Thread (%d) created successfully.\n", ids.tid);
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* Kill it */
|
/* Kill it */
|
||||||
printf("Killing Thread (%d).\n", ids.tid);
|
printf("Killing Thread (%d).\n", ids.tid);
|
||||||
if ((ret = l4_thread_control(THREAD_DESTROY, &ids)) < 0)
|
if ((ret = l4_thread_control(THREAD_DESTROY, &ids)) < 0)
|
||||||
@@ -39,7 +41,10 @@ int exit_test(void)
|
|||||||
else
|
else
|
||||||
printf("Success: Killed Thread (%d)\n", ids.tid);
|
printf("Success: Killed Thread (%d)\n", ids.tid);
|
||||||
|
|
||||||
#if 0
|
#endif
|
||||||
|
|
||||||
|
l4_thread_switch(0);
|
||||||
|
|
||||||
/* Wait on it */
|
/* Wait on it */
|
||||||
printf("Waiting on Thread (%d) to exit.\n", ids.tid);
|
printf("Waiting on Thread (%d) to exit.\n", ids.tid);
|
||||||
if ((ret = l4_thread_control(THREAD_WAIT, &ids)) >= 0)
|
if ((ret = l4_thread_control(THREAD_WAIT, &ids)) >= 0)
|
||||||
@@ -47,7 +52,6 @@ int exit_test(void)
|
|||||||
else
|
else
|
||||||
printf("Error. Wait on (%d) failed. err = %d\n",
|
printf("Error. Wait on (%d) failed. err = %d\n",
|
||||||
ids.tid, ret);
|
ids.tid, ret);
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_err:
|
out_err:
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ cap_all_others = \
|
|||||||
\t\t\t\t.type = CAP_TYPE_TCTRL | CAP_RTYPE_CONTAINER,
|
\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.access = CAP_TCTRL_CREATE | CAP_TCTRL_DESTROY
|
||||||
\t\t\t\t | CAP_TCTRL_SUSPEND | CAP_TCTRL_RUN
|
\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.start = 0, .end = 0, .size = 0,
|
||||||
\t\t\t},
|
\t\t\t},
|
||||||
\t\t\t[%d] = {
|
\t\t\t[%d] = {
|
||||||
|
|||||||
@@ -49,6 +49,48 @@ int thread_signal_sync(struct ktcb *task, unsigned int flags,
|
|||||||
return ret;
|
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)
|
int thread_suspend(struct ktcb *task)
|
||||||
{
|
{
|
||||||
return thread_signal_sync(task, TASK_SUSPENDING, TASK_INACTIVE);
|
return thread_signal_sync(task, TASK_SUSPENDING, TASK_INACTIVE);
|
||||||
@@ -130,8 +172,10 @@ int thread_destroy(struct ktcb *task)
|
|||||||
if (child->pagerid == current->tid &&
|
if (child->pagerid == current->tid &&
|
||||||
child != current) {
|
child != current) {
|
||||||
spin_unlock(&curcont->ktcb_list.list_lock);
|
spin_unlock(&curcont->ktcb_list.list_lock);
|
||||||
|
|
||||||
|
/* Its a bug since nobody can interrupt us */
|
||||||
BUG_ON(thread_signal_sync(child, TASK_EXITING,
|
BUG_ON(thread_signal_sync(child, TASK_EXITING,
|
||||||
TASK_INACTIVE) < 0);
|
TASK_INACTIVE) < 0);
|
||||||
spin_lock(&curcont->ktcb_list.list_lock);
|
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)
|
MAP_USR_RW_FLAGS, 1)) < 0)
|
||||||
return err;
|
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)))
|
if (!(task = tcb_find(ids->tid)))
|
||||||
return -ESRCH;
|
return -ESRCH;
|
||||||
|
|
||||||
@@ -393,6 +438,9 @@ int sys_thread_control(unsigned int flags, struct task_ids *ids)
|
|||||||
case THREAD_RECYCLE:
|
case THREAD_RECYCLE:
|
||||||
ret = thread_recycle(task);
|
ret = thread_recycle(task);
|
||||||
break;
|
break;
|
||||||
|
case THREAD_WAIT:
|
||||||
|
ret = thread_wait(ids);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
|||||||
@@ -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 */
|
/* 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.
|
* FIXME: Add cid to task_ids arg.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user