diff --git a/conts/test/main.c b/conts/test/main.c index 48d13d2..fdcc3bf 100644 --- a/conts/test/main.c +++ b/conts/test/main.c @@ -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: diff --git a/include/l4/api/thread.h b/include/l4/api/thread.h index 095c713..1bc89a4 100644 --- a/include/l4/api/thread.h +++ b/include/l4/api/thread.h @@ -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__ */ diff --git a/include/l4/generic/tcb.h b/include/l4/generic/tcb.h index aa13f87..4dceb95 100644 --- a/include/l4/generic/tcb.h +++ b/include/l4/generic/tcb.h @@ -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; diff --git a/src/api/thread.c b/src/api/thread.c index c5511bb..c0b8dd4 100644 --- a/src/api/thread.c +++ b/src/api/thread.c @@ -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);