コード例 #1
0
ファイル: scheduler.C プロジェクト: vandanab/OS
/* Called by the currently running thread in order to give up the CPU.
	The scheduler selects the next thread from the ready queue to load onto 
	the CPU, and calls the dispatcher function defined in 'threads.h' to
	do the context switch. */
void Scheduler::yield() {
	//check if disk's last read/write is ready, the blocked thread needs to be resumed then from the disk's queue
	if(this->disk != NULL && this->disk->is_ready()) {
		this->disk->resume_from_queue();
	}

	if(this->head == NULL) {
		Console::puts("Error: Ready queue is NULL.\n");
	} else {
		//disable interrupts
		if(machine_interrupts_enabled())
			machine_disable_interrupts();
		
		Thread *the_one;
		the_one = this->head->thread_ptr;
		this->head = this->head->next;
		Thread::dispatch_to(the_one);
		
		//disable interrupts
		if(!machine_interrupts_enabled())
			machine_enable_interrupts();
	}
}
コード例 #2
0
ファイル: kernel.C プロジェクト: Mason1993/CSCE-410
int main() {

    GDT::init();
    Console::init();
    IDT::init();
    ExceptionHandler::init_dispatcher();
    IRQ::init();
    InterruptHandler::init_dispatcher();

    /* -- EXAMPLE OF AN EXCEPTION HANDLER -- */

    class DBZ_Handler : public ExceptionHandler {
      public:
      virtual void handle_exception(REGS * _regs) {
        Console::puts("DIVISION BY ZERO!\n");
        for(;;);
      }
    } dbz_handler;

    ExceptionHandler::register_handler(0, &dbz_handler);

    /* -- INITIALIZE MEMORY -- */
    /*    NOTE: We don't have paging enabled in this MP. */
    /*    NOTE2: This is not an exercise in memory management. The implementation
                of the memory management is accordingly *very* primitive! */

    /* ---- Initialize a frame pool; details are in its implementation */
    FramePool system_frame_pool;
    SYSTEM_FRAME_POOL = &system_frame_pool;

    /* ---- Create a memory pool of 256 frames. */
    MemPool memory_pool(SYSTEM_FRAME_POOL, 256);
    MEMORY_POOL = &memory_pool;

    /* -- INITIALIZE THE TIMER (we use a very simple timer).-- */

    /* Question: Why do we want a timer? We have it to make sure that
                 we enable interrupts correctly. If we forget to do it,
                 the timer "dies". */

    SimpleTimer timer(100); /* timer ticks every 10ms. */
    InterruptHandler::register_handler(0, &timer);
    /* The Timer is implemented as an interrupt handler. */

#ifdef _USES_SCHEDULER_

    /* -- SCHEDULER -- IF YOU HAVE ONE -- */

    Scheduler system_scheduler;
    SYSTEM_SCHEDULER = &system_scheduler;

#endif

#ifdef _USES_DISK_

    /* -- DISK DEVICE -- IF YOU HAVE ONE -- */

    BlockingDisk system_disk = BlockingDisk(MASTER, SYSTEM_DISK_SIZE);
    SYSTEM_DISK = &system_disk;

#endif

//#ifdef _USES_FILESYSTEM_

     /* -- FILE SYSTEM  -- IF YOU HAVE ONE -- */

     FileSystem file_system= FileSystem();
     FILE_SYSTEM = &file_system;

//#endif


    /* NOTE: The timer chip starts periodically firing as
             soon as we enable interrupts.
             It is important to install a timer handler, as we
             would get a lot of uncaptured interrupts otherwise. */

    /* -- ENABLE INTERRUPTS -- */

    machine_enable_interrupts();

    /* -- MOST OF WHAT WE NEED IS SETUP. THE KERNEL CAN START. */

    Console::puts("Hello World!\n");

    /* -- LET'S CREATE SOME THREADS... */

    Console::puts("CREATING THREAD 1...\n");
    char * stack1 = new char[1024];
    thread1 = new Thread(fun1, stack1, 1024);
    Console::puts("DONE\n");

    Console::puts("CREATING THREAD 2...");
    char * stack2 = new char[1024*2];//allow for testing file system with larger buffers
    thread2 = new Thread(fun2, stack2, 1024);
    Console::puts("DONE\n");

    Console::puts("CREATING THREAD 3...");
    char * stack3 = new char[1024*10];
    thread3 = new Thread(fun3, stack3, 1024);
    Console::puts("DONE\n");

    Console::puts("CREATING THREAD 4...");
    char * stack4 = new char[1024];
    thread4 = new Thread(fun4, stack4, 1024);
    Console::puts("DONE\n");

#ifdef _USES_SCHEDULER_

    /* WE ADD thread2 - thread4 TO THE READY QUEUE OF THE SCHEDULER. */
    SYSTEM_SCHEDULER->add(thread2);
    SYSTEM_SCHEDULER->add(thread3);
    SYSTEM_SCHEDULER->add(thread4);

#endif

    /* -- KICK-OFF THREAD1 ... */

    Console::puts("STARTING THREAD 1 ...\n");
    Thread::dispatch_to(thread1);

    /* -- AND ALL THE REST SHOULD FOLLOW ... */

    assert(FALSE); /* WE SHOULD NEVER REACH THIS POINT. */

    /* -- WE DO THE FOLLOWING TO KEEP THE COMPILER HAPPY. */
    return 1;
}