Mercurial > hvf > hvf-old
changeset 506:5cb01f04b0eb
cp: handle task exits
Introduced a new SVC that will terminate the current task. If a task
returns from its "main" function, it will implicitly use this new SVC.
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Sat, 23 Apr 2011 17:29:58 -0400 |
parents | b1c6346f553c |
children | 354fc5b6cbd9 |
files | cp/include/interrupt.h cp/include/sched.h cp/nucleus/sched.c cp/nucleus/svc.c |
diffstat | 4 files changed, 54 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/cp/include/interrupt.h Sat Apr 23 14:16:31 2011 -0400 +++ b/cp/include/interrupt.h Sat Apr 23 17:29:58 2011 -0400 @@ -1,5 +1,5 @@ /* - * (C) Copyright 2007-2010 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> + * (C) Copyright 2007-2011 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> * * This file is released under the GPLv2. See the COPYING file for more * details. @@ -89,7 +89,8 @@ */ #define SVC_SCHEDULE 0 #define SVC_SCHEDULE_BLOCKED 1 -#define NR_SVC 2 +#define SVC_SCHEDULE_EXIT 2 +#define NR_SVC 3 extern u64 svc_table[NR_SVC]; /* Interrupt handlers */
--- a/cp/include/sched.h Sat Apr 23 14:16:31 2011 -0400 +++ b/cp/include/sched.h Sat Apr 23 17:29:58 2011 -0400 @@ -21,6 +21,7 @@ #define TASK_RUNNING 0 #define TASK_SLEEPING 1 #define TASK_LOCKED 2 +#define TASK_ZOMBIE 3 #define STACK_FRAME_SIZE 160 @@ -115,6 +116,8 @@ int state; /* state */ + void *stack; /* the stack */ + char name[TASK_NAME_LEN+1]; /* task name */ /* lock dependency tracking */ @@ -143,6 +146,7 @@ int newstate); /* scheduler helper - use with caution */ extern void __schedule_svc(void); extern void __schedule_blocked_svc(void); +extern void __schedule_exit_svc(void); extern void make_runnable(struct task *task); @@ -212,4 +216,23 @@ ); } +/** + * exit - schedule with the intent to terminate the current task + */ +static inline void exit(void) +{ + /* + * if we are not interruptable, we shouldn't call any functions that + * may sleep - schedule() is guaranteed to sleep :) + */ + BUG_ON(!interruptable()); + + asm volatile( + " svc %0\n" + : /* output */ + : /* input */ + "i" (SVC_SCHEDULE_EXIT) + ); +} + #endif
--- a/cp/nucleus/sched.c Sat Apr 23 14:16:31 2011 -0400 +++ b/cp/nucleus/sched.c Sat Apr 23 17:29:58 2011 -0400 @@ -32,15 +32,9 @@ if (f) (*f)(data); - /* - * Done, now, it's time to cleanup - * - * FIXME: - * - delete from processes list - * - free stack page - * - free struct - * - schedule - */ + exit(); + + /* unreachable */ BUG(); } @@ -68,6 +62,8 @@ task->state = TASK_SLEEPING; + task->stack = stack; + task->nr_locks = 0; } @@ -224,8 +220,6 @@ * Add back on the queue */ prev->state = newstate; - if (newstate != TASK_LOCKED) - list_add_tail(&prev->run_queue, &runnable); /* * If the previous task didn't use it's full slice, force idle_task @@ -234,6 +228,19 @@ if (prev->slice_end_time >= (ticks + SCHED_TICKS_PER_SLICE)) force_idle = prev->slice_end_time; + switch(newstate) { + case TASK_ZOMBIE: + list_del(&prev->proc_list); + free_pages(prev->stack, 0); + free(prev); + break; + case TASK_LOCKED: + break; + default: + list_add_tail(&prev->run_queue, &runnable); + break; + } + go: /* * Run the rest of the scheduler that selects the next task and @@ -258,6 +265,14 @@ __schedule(SVC_INT_OLD_PSW, TASK_LOCKED); } +/** + * __schedule_blocked__svc - wrapper for the supervisor-service call handler + */ +void __schedule_exit_svc(void) +{ + __schedule(SVC_INT_OLD_PSW, TASK_ZOMBIE); +} + /* * Initialize the schduler, and all associated structures */
--- a/cp/nucleus/svc.c Sat Apr 23 14:16:31 2011 -0400 +++ b/cp/nucleus/svc.c Sat Apr 23 17:29:58 2011 -0400 @@ -1,5 +1,5 @@ /* - * (C) Copyright 2007-2010 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> + * (C) Copyright 2007-2011 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> * * This file is released under the GPLv2. See the COPYING file for more * details. @@ -11,5 +11,6 @@ u64 svc_table[NR_SVC] = { (u64) __schedule_svc, (u64) __schedule_blocked_svc, + (u64) __schedule_exit_svc, };