#include "sched.h" #include "terminal.h" #include "task.h" #include "interrupts.h" Scheduler scheduler; void Scheduler::do_it(registers *regs) { schedule(regs); } int Scheduler::addTask(Task* t) { if(t==0) { PANIC("Added bad task"); } if(!t->page_dir.is_set()) { con->putval("invalid page directory for task",ntasks+1); con->putval("Set as: ",t->page_dir.physical_address); PANIC("INVALID PAGE DIRECTORY"); } t->pid=ntasks++; t->setNext(head); head=t; return t->pid; } Task* Scheduler::removeTask(int pid) { PANIC("NOT CALLED"); Task* r = head; if(!head) return 0; if(head->pid==pid) { head=head->getNext(); } else { Task* prev = head; r=head->getNext(); while(r!=0) { if(r->pid==pid) { prev->setNext(r->getNext()); r->setNext(0); break; } prev=r; r=r->getNext(); } } return r; // do bugger all for now. } void Scheduler::schedule(registers *regs) { // return; //con->print("In Scheduler\n"); //static int count=0; //if(currTask) {con->print("WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW"); hang(); } //con->putval("In scheduler - head=",head); //con->putval("Number of tasks=",ntasks); //con->putval("current task:",currTask); // con->print("\n"); // for(Task* t=head;t!=0;t=t->getNext()) { // // if(t->pid==2) { // con->print("PID: "); // con->puthex(t->pid); // con->print("-state: "); // con->puthex(t->_state); // con->putval("-Task: ",t); // // if(t->_state==Task::EXITED) // // PANIC("FOO"); // } // //con->putval("Task: ",t); // } //IRQHandler::dump_registers(*regs); // con->putval("Head = ",head); // u32 ss = regs->ss; //if(!head || firstTask.page_dir ==0) { // this will become the idle thread once it's prepared. // firstTask.setup(regs->eip,PageDirectory::current,regs->useresp,0); // addTask(&firstTask); // } if(currTask==0) { con->print("\n***First scheduler invocation!\n "); currTask=head; } else { // con->putval("Switching from task ",currTask->pid); currTask->store_regs(regs); } // PANIC("HERE"); if(currTask->_state==Task::RUNNING) currTask->setState(Task::RUNNABLE); Task* nextTask=currTask; // con->print("Starting search....."); if(nextTask==nextTask->getNext()) PANIC("Circular list in scheduler..."); // go around the list looking for the next runnable task. do { Task*prev=nextTask; nextTask=nextTask->getNext(); if(nextTask==0) { nextTask=head; continue; } // remove a dead one if we pass it. if(nextTask->_state==Task::EXITED) { if(prev==0) { head=nextTask->getNext(); } else { prev->setNext(nextTask->getNext()); } nextTask->page_dir.switch_to_this(); nextTask->page_dir.destroy(); delete nextTask; } // con->putval("\n\nXXXXXX--------------task ",nextTask); // con->putval("\nXXXXXX--------------pid ",nextTask->pid); // con->putval("XXXXXX--------------state ",nextTask->_state); // con->putval("XXXXXX--------------next ",nextTask->getNext()); } while(nextTask->_state!=Task::RUNNABLE); // do { // if(nextTask==nextTask->next) // PANIC("Circular list in scheduler..."); // // con->putval("\n\nXXXXXX--------------task ",nextTask); // con->putval("\nXXXXXX--------------pid ",nextTask->pid); // con->putval("XXXXXX--------------state ",nextTask->_state); // con->putval("XXXXXX--------------next ",nextTask->next); // if(nextTask!=0) // nextTask=nextTask->next; // if(nextTask==0) // nextTask=head; // } while(nextTask->_state!=Task::RUNNABLE); nextTask->restore_regs(regs); currTask=nextTask; /*con->print("Task has state: "); switch(currTask->state) { case Task::RUNNABLE: con->print("Runnable\n");break; case Task::BLOCKED: con->print("BLOCKED\n"); break; default: con->print("OTHER\n"); }*/ if(currTask->_state!=Task::RUNNABLE) { PANIC("Task to run is not runnable!"); } currTask->setState(Task::RUNNING); // if(currTask->pid==1) { // con->print("IDLE THREAD\n"); // } else { // con->putval("next task is:",(nextTask->pid)); // con->putval("next EIP is:",regs->eip); // con->putval("PGDIR: ",currTask->page_dir.physical_address); // } currTask->page_dir.switch_to_this(); // if(currTask->pid!=4) // con->putval("Switching to task ",currTask->pid); return; }