diff options
Diffstat (limited to 'kernel/scheduler.c')
| -rw-r--r-- | kernel/scheduler.c | 69 |
1 files changed, 64 insertions, 5 deletions
diff --git a/kernel/scheduler.c b/kernel/scheduler.c index 540e72b..b367825 100644 --- a/kernel/scheduler.c +++ b/kernel/scheduler.c @@ -2,7 +2,6 @@ // // - #include "kernel.h" #include "mem.h" #include "asm/x86.h" @@ -20,10 +19,17 @@ static volatile struct task_list_struct volatile bool active; volatile uint32_t esp; // stack pointer of the task; volatile pdirectory *vmem; // number of virtual memory table to switch to - volatile bool waiting; + volatile bool waiting; volatile bool skipwait; volatile uint32_t brk; volatile uint32_t esp0; + + volatile bool syscall; // waiting for syscall to be processed. + volatile uint32_t eax; + volatile uint32_t ebx; + volatile uint32_t ecx; + volatile uint32_t edx; + }volatile task_list[MAX_TASKS]; @@ -59,6 +65,36 @@ volatile int add_task(uint32_t esp, uint32_t vmem) kpanic("out of task slots!"); } +void task_wake_syscall_worker() +{ + task_list[2].waiting=false; // todo: context switch immiditly? +} + +void task_syscall_worker() +{ + klog("checking if any pending syscalls."); + + for(int i=0;i<MAX_TASKS;i++) + { + if(task_list[i].syscall) + { + klog("task %d waiting on syscall %d. processing...",i,task_list[i].eax); + + task_list[2].vmem=task_list[i].vmem; // switch syscall worker to pagedir of calling userprog + x86_set_page_directory(task_list[2].vmem); + syscall_generic(task_list[i].eax, + task_list[i].ebx, + task_list[i].ecx, + task_list[i].edx); + + task_list[i].syscall=false; + } + } + + task_list[current_task].waiting=true; + __asm__("hlt"); //TODO: force task switch here... via syscall? +} + // // REMEMBER WE ARE INSIDE AN INTERRUPT HERE - DON'T WASTE TIME! // @@ -83,10 +119,10 @@ volatile uint32_t my_scheduler(uint32_t oldesp) { int pid=(current_task+1+i)%MAX_TASKS; // schedule round robin style - if(task_list[pid].active && !task_list[pid].waiting) + if(task_list[pid].active && !task_list[pid].waiting && !task_list[pid].syscall) { -// if(current_task!=pid) -// klog("switch from %d to %d", current_task, pid); + if(current_task!=pid) + klog("switch from %d to %d", current_task, pid); current_task=pid; install_tss(task_list[pid].esp0); @@ -108,6 +144,16 @@ volatile uint32_t task_switch_next(uint32_t oldesp) return my_scheduler(oldesp); } +volatile uint32_t task_syscall(uint32_t eax,uint32_t ebx, uint32_t ecx, uint32_t edx,uint32_t oldesp) +{ + task_list[current_task].syscall=true; + task_list[current_task].eax=eax; + task_list[current_task].ebx=ebx; + task_list[current_task].ecx=ecx; + task_list[current_task].edx=edx; + return my_scheduler(oldesp); +} + //TODO: free vmem too! //TODO: notify waiting parent when child finished; volatile uint32_t task_exit(uint32_t oldesp) @@ -164,6 +210,11 @@ volatile uint32_t task_fork(uint32_t oldesp) // init task (root of all other tasks / processes) // volatile void scheduler_init(pdirectory *dir) { + for(int i=0;i<MAX_TASKS;i++) + { + task_list[i].active=false; + } + current_task=0; // this is our main user task on slot 0 @@ -181,6 +232,14 @@ volatile void scheduler_init(pdirectory *dir) task_list[1].esp = kballoc(4)+4*4096; task_list[1].esp0 = 0; // not needed by kernel space tasks + task_list[2].parent=0; + task_list[2].active=true; + task_list[2].waiting=false; + task_list[2].vmem=dir; + task_list[2].esp = kballoc(4)+4*4096; + task_list[2].esp0 = 0; // not needed by kernel space tasks + + task_pusha(task_list[2].esp); task_pusha(task_list[1].esp); task_pusha(task_list[0].esp); |
