Wait on working.

Multi-threaded apps can now wait on children to destroy.
WAIT_ON is useful when a child exists with an exit code and the pager
of the child does not want to take the hassle of destorying it via an
ipc. It provides an alternative method of synchronous thread destruction,
where the child destroys itself directly rather than the parent issuing
a destroy on it explicitly.
This commit is contained in:
Bahadir Balban
2009-10-31 23:28:54 +02:00
parent 850c645d77
commit 0f537ea1f5
4 changed files with 38 additions and 26 deletions

View File

@@ -15,8 +15,8 @@
int exit_test_thread(void *arg)
{
l4_thread_switch(0);
l4_exit(0);
//l4_thread_switch(0);
l4_exit(5);
return 0;
}
@@ -46,7 +46,6 @@ int exit_test(void)
#endif
#if 0
/* Wait on it */
printf("Waiting on Thread (%d) to exit.\n", ids.tid);
if ((ret = l4_thread_control(THREAD_WAIT, &ids)) >= 0)
@@ -54,7 +53,6 @@ int exit_test(void)
else
printf("Error. Wait on (%d) failed. err = %d\n",
ids.tid, ret);
#endif
return 0;
out_err:

View File

@@ -1,22 +1,23 @@
#ifndef __API_THREAD_H__
#define __API_THREAD_H__
#define THREAD_ACTION_MASK 0x000F
#define THREAD_CREATE 0x0000
#define THREAD_RUN 0x0001
#define THREAD_SUSPEND 0x0002
#define THREAD_DESTROY 0x0003
#define THREAD_RECYCLE 0x0004
#define THREAD_WAIT 0x0005
#define THREAD_ACTION_MASK 0xF0000000
#define THREAD_CREATE 0x00000000
#define THREAD_RUN 0x10000000
#define THREAD_SUSPEND 0x20000000
#define THREAD_DESTROY 0x30000000
#define THREAD_RECYCLE 0x40000000
#define THREAD_WAIT 0x50000000
#define THREAD_CREATE_MASK 0x0FF0
#define TC_SHARE_CAPS 0x0010 /* Share all thread capabilities */
#define TC_SHARE_UTCB 0x0020 /* Share utcb location (same space */
#define TC_SHARE_GROUP 0x0040 /* Share thread group id */
#define TC_SHARE_SPACE 0x0080 /* New thread, use given space */
#define TC_COPY_SPACE 0x0100 /* New thread, copy given space */
#define TC_NEW_SPACE 0x0200 /* New thread, new space */
#define TC_SHARE_PAGER 0x0400 /* New thread, shared pager */
#define TC_AS_PAGER 0x0800 /* Set new thread as child */
#define THREAD_CREATE_MASK 0x0FF00000
#define TC_SHARE_CAPS 0x00100000 /* Share all thread capabilities */
#define TC_SHARE_UTCB 0x00200000 /* Share utcb location (same space */
#define TC_SHARE_GROUP 0x00400000 /* Share thread group id */
#define TC_SHARE_SPACE 0x00800000 /* New thread, use given space */
#define TC_COPY_SPACE 0x01000000 /* New thread, copy given space */
#define TC_NEW_SPACE 0x02000000 /* New thread, new space */
#define TC_SHARE_PAGER 0x04000000 /* New thread, shared pager */
#define TC_AS_PAGER 0x08000000 /* Set new thread as child */
#define THREAD_EXIT_MASK 0x0000FFFF /* Thread exit code */
#endif /* __API_THREAD_H__ */

View File

@@ -98,6 +98,9 @@ struct ktcb {
/* Number of locks the task currently has acquired */
int nlocks;
/* Task exit code */
unsigned int exit_code;
/* Page table information */
struct address_space *space;

View File

@@ -102,24 +102,34 @@ int thread_destroy_children(void)
}
void thread_destroy_self()
void thread_destroy_self(unsigned int exit_code)
{
thread_destroy_children();
current->exit_code = exit_code;
sched_exit_sync();
}
int thread_wait(struct ktcb *task)
{
return 0;
int ret;
/* Wait until task switches to desired state */
WAIT_EVENT(&task->wqh_pager,
task->state == TASK_DEAD, ret);
if (ret < 0)
return ret;
else
return (int)task->exit_code;
}
int thread_destroy(struct ktcb *task)
int thread_destroy(struct ktcb *task, unsigned int exit_code)
{
exit_code &= THREAD_EXIT_MASK;
if (TASK_IS_CHILD(task))
return thread_destroy_child(task);
else if (task == current)
thread_destroy_self();
thread_destroy_self(exit_code);
return 0;
}
@@ -412,7 +422,7 @@ int sys_thread_control(unsigned int flags, struct task_ids *ids)
ret = thread_suspend(task);
break;
case THREAD_DESTROY:
ret = thread_destroy(task);
ret = thread_destroy(task, flags);
break;
case THREAD_RECYCLE:
ret = thread_recycle(task);