#include "scheduler.h" #include "kernel.h" #include "gdt.h" #include "log.h" #include "smp.h" #include "mem.h" #include "fs/elf.h" #include "asm_x86.h" #include "asm_task.h" #include "asm_usermode.h" #include "kmalloc.h" #include "vmem.h" #include "spinlock.h" #include "syscalls.h" #include "fs/fs.h" #include "fs/ext2.h" #define NO_TASK 0xffffffff static volatile uint32_t pid=1000; static uint32_t nextPID() { spinlock_spin(SPINLOCK_PID); pid++; uint32_t ret=pid; spinlock_release(SPINLOCK_PID); return ret; } // we hold this stuff per cpu static volatile uint32_t current_task[SMP_MAX_PROC]; // we hold this stuff per cpu static volatile struct task_list_struct { volatile bool active; // is this slot used (Y/N) volatile uint32_t pid; // process id volatile uint32_t parent; // parent process id volatile uint32_t esp; // stack pointer of the task volatile uint32_t esp0; // tss.esp0 volatile struct pdirectory *vmem; // number of virtual memory table volatile uint32_t brk; // memory brk pos volatile bool try; // waiting coz syscall not processed yet volatile bool syscall; // syscall in progress volatile uint32_t eax; volatile uint32_t ebx; volatile uint32_t ecx; volatile uint32_t edx; volatile bool thread; // is this a light thread? }task_list[SMP_MAX_PROC][MAX_TASKS]; // init tasks // volatile void scheduler_init(uint32_t cpu, void *dir) { for(int i=0;i%d on cpu %d",current_task[cpu],idx,cpu ); current_task[cpu]=idx; install_tss(cpu,task_list[cpu][idx].esp0); x86_set_page_directory(task_list[cpu][idx].vmem); return task_list[cpu][idx].esp; } } kpanic("nothing to schedule!"); } void scheduler_func() { // we need enable here again (since the pushed eflags have it disabled)? TODO: why they disabled it!??? x86_sti(); uint32_t cpu=smp_get(SMP_APIC_ID); if(current_task[cpu]==0) while(1) { task_syscall_worker(); } if(current_task[cpu]==1) while(1) { if(cpu==0) { uint32_t alloc; uint32_t entry_global=load_elf(BIN_INIT,&alloc); task_set_brk(task_get_current_pid(),alloc); asm_usermode(entry_global); while(1); } } } volatile int add_task(uint32_t parent_pid,uint32_t vmem, bool thread) { uint32_t parent=task_runs(parent_pid); uint32_t cpu=smp_get(SMP_APIC_ID); for(int i=0;i [%d]", pid, ret); return ret; } volatile uint32_t task_clone(uint32_t pid) { uint32_t idx=task_runs(pid); uint32_t cpu=smp_get(SMP_APIC_ID); int ret=add_task(pid,vmem_new_space_dir(task_list[cpu][idx].vmem,true),true); klog("[%d] cloned -> [%d]", pid, ret); return ret; } volatile uint32_t task_get_brk(uint32_t pid) { uint32_t cpu=smp_get(SMP_APIC_ID); uint32_t idx=task_idx(pid); return task_list[cpu][idx].brk; } volatile void task_set_brk(uint32_t pid, uint32_t brk) { uint32_t cpu=smp_get(SMP_APIC_ID); uint32_t idx=task_idx(pid); task_list[cpu][idx].brk=brk; } volatile uint32_t task_get_current_pid() { uint32_t cpu=smp_get(SMP_APIC_ID); return task_list[cpu][current_task[cpu]].pid; } volatile uint32_t task_get_parent(uint32_t pid) { uint32_t idx=task_idx(pid); uint32_t cpu=smp_get(SMP_APIC_ID); return task_list[cpu][idx].parent; } volatile int task_reset(uint32_t pid, uint32_t entry, uint32_t stack,uint32_t brk) { uint32_t cpu=smp_get(SMP_APIC_ID); uint32_t idx=task_idx(pid); uint32_t *stk=task_list[cpu][idx].esp; task_list[cpu][idx].brk=brk; stk[14]=entry; stk[17]=stack; return 1; } uint32_t task_idx(uint32_t pid) { uint32_t cpu=smp_get(SMP_APIC_ID); for(int i=0;i