diff options
Diffstat (limited to 'src/core/scheduler.c')
| -rw-r--r-- | src/core/scheduler.c | 60 |
1 files changed, 58 insertions, 2 deletions
diff --git a/src/core/scheduler.c b/src/core/scheduler.c index 848b7b7..0a8c5c7 100644 --- a/src/core/scheduler.c +++ b/src/core/scheduler.c @@ -1,12 +1,67 @@ +#include "scheduler.h" #include "libc/stdio.h" #include "gdt.h" -#include "mem.h" #include "paging.h" char show_tics=0; +char scheduler_on=0; +PROC procs[MAX_PROC]; +u16 current_id; +u16 nproc; void schedule(){ + // Note that this function is called by clock + // clock is called by INT_CLOCK (core/int.S) + // which store all the process information on + // the stack. Thus, knowing the C calling conventions + // and that schedule() is call by two functions with no parameters, + // the first process register can be accessed by ebp+2 + u32 *stack; + asm("mov %%ebp, %0":"=r" (stack)); + + // No proc to schedule + if(nproc<2) + return; + + PROC *p=&procs[current_id]; + p->regs.gs=stack[2]; // ebp+2=gs cf note above + p->regs.fs=stack[3]; + p->regs.es=stack[4]; + p->regs.ds=stack[5]; + p->regs.edi=stack[6]; + p->regs.esi=stack[7]; + p->regs.ebp=stack[8]; + // We do not take p->regs.esp=stack[9] + // since it corresponds to the kernel stack + // (it was push during the interruption) + p->regs.edx=stack[10]; + p->regs.ecx=stack[11]; + p->regs.ebx=stack[12]; + p->regs.eax=stack[13]; + p->regs.eip=stack[14]; + p->regs.cs=stack[15]; + p->regs.eflags=stack[16]; + p->regs.esp=stack[17]; + p->regs.ss=stack[18]; + + current_id++; + if(current_id>=nproc) + current_id=0; + // Have a clean stack on next interrupt + TSS.esp0=(u32)stack+19; + asm("mov %%ss, %0": "=m" (TSS.ss0)); + + // Ensure interrupts are activated and NT flag is clear + p->regs.eflags|=0x200; + p->regs.eflags&=0xffffbfff; + + // Perform task switch + asm( + "mov %0, %%esi \n\t" + "jmp task_switch \n\t" + :: "a" (p) + ); } void clock(){ @@ -19,7 +74,8 @@ void clock(){ if(show_tics) putchar('.'); } - schedule(); + if(scheduler_on==1) + schedule(); } void run_task(int *page_dir, void *task, int task_size){ |
