diff options
Diffstat (limited to 'kernel/task.c')
| -rw-r--r-- | kernel/task.c | 77 |
1 files changed, 57 insertions, 20 deletions
diff --git a/kernel/task.c b/kernel/task.c index 6ea9b79..ac54dbe 100644 --- a/kernel/task.c +++ b/kernel/task.c @@ -17,7 +17,7 @@ #define MAX_TASKS 10 -static volatile int current_task=-2; +static volatile int current_task=-1; static volatile struct task_list_struct { @@ -25,6 +25,8 @@ static volatile struct task_list_struct bool active; uint32_t esp; // stack pointer of the task; uint32_t vmem; // number of virtual memory table to switch to + bool waiting; + bool skipwait; }volatile task_list[MAX_TASKS]; @@ -40,6 +42,8 @@ int add_task(uint32_t esp, uint32_t vmem) task_list[i].vmem=vmem; task_list[i].esp=esp; task_list[i].active=true; + task_list[i].waiting=false; + task_list[i].skipwait=false; return i; } @@ -48,22 +52,19 @@ int add_task(uint32_t esp, uint32_t vmem) panic(FOOLOS_MODULE_NAME,"out of task slots!"); } -// this gets called by our clock interrupt regularly! -uint32_t task_switch_next(uint32_t oldesp) +uint32_t my_scheduler(uint32_t oldesp) { - timer_tick(); - - if(current_task==-2)return oldesp; - task_list[current_task].esp=oldesp; - + for(int i=0;i<MAX_TASKS;i++) { int pid=(current_task+1+i)%MAX_TASKS; // schedule round robin style - if(task_list[pid].active) + if(task_list[pid].active && !task_list[pid].waiting) { - // log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"switch from %d to pid: %d (0x%08X) vmem: %d ", current_task,pid,task_list[pid].esp,task_list[pid].vmem); + // if(current_task!=pid) + // log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"switch from %d to %d", current_task, pid); + current_task=pid; vmem_set_dir(task_list[pid].vmem); @@ -72,34 +73,68 @@ uint32_t task_switch_next(uint32_t oldesp) } - return oldesp; + panic(FOOLOS_MODULE_NAME,"nothing to schedule!"); +} + +// this gets called by our clock interrupt regularly! +uint32_t task_switch_next(uint32_t oldesp) +{ + timer_tick(); + + // check if multitasking has been started + if(current_task<0)return oldesp; + + return my_scheduler(oldesp); } + //TODO: free vmem too! +//TODO: notify waiting parent when child finished; uint32_t task_exit(uint32_t oldesp) { task_list[current_task].active=false; + int parent_pid=task_list[current_task].parent; - for(int i=0;i<MAX_TASKS;i++) + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"[%d] exit ", current_task); + if(task_list[parent_pid].active) { - int pid=(current_task+1+i)%MAX_TASKS; // schedule round robin style - - if(task_list[pid].active) + if(task_list[parent_pid].waiting) { - // log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"switch from %d to pid: %d (0x%08X) vmem: %d ", current_task,pid,task_list[pid].esp,task_list[pid].vmem); - current_task=pid; - - vmem_set_dir(task_list[pid].vmem); - return task_list[pid].esp; + + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"wakeing up %d ", parent_pid); + task_list[parent_pid].waiting=false; + } + else + { + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"set skipwait on %d ", parent_pid); + task_list[parent_pid].skipwait=true; } + + } + + return my_scheduler(oldesp); + +} +uint32_t task_wait(uint32_t oldesp) +{ + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"[%d] wait", current_task); + if(task_list[current_task].skipwait) + { + task_list[current_task].skipwait=false; + } + else + { + task_list[current_task].waiting=true; } + return my_scheduler(oldesp); } uint32_t task_fork(uint32_t oldesp) { int pid=add_task(oldesp,vmem_new_space_dir(task_list[current_task].vmem)); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"[%d] forked -> [%d]", current_task, pid); return pid; } @@ -107,7 +142,9 @@ uint32_t task_fork(uint32_t oldesp) void task_init() { // this is our main task on slot 0 + task_list[0].parent=0; task_list[0].active=true; + task_list[0].waiting=false; task_list[0].vmem=0; task_list[0].esp = 0; // will be set by next task_switch_next() call. current_task=0; |
