Main Page   Compound List   File List   Compound Members   File Members  

scheduler.cc

Go to the documentation of this file.
00001 // scheduler.cc 
00002 //      Routines to choose the next thread to run, and to dispatch to
00003 //      that thread.
00004 //
00005 //      These routines assume that interrupts are already disabled.
00006 //      If interrupts are disabled, we can assume mutual exclusion
00007 //      (since we are on a uniprocessor).
00008 //
00009 //      NOTE: We can't use Locks to provide mutual exclusion here, since
00010 //      if we needed to wait for a lock, and the lock was busy, we would 
00011 //      end up calling FindNextToRun(), and that would put us in an 
00012 //      infinite loop.
00013 //
00014 //      Very simple implementation -- no priorities, straight FIFO.
00015 //      Might need to be improved in later assignments.
00016 //
00017 // Copyright (c) 1992-1993 The Regents of the University of California.
00018 // All rights reserved.  See copyright.h for copyright notice and limitation 
00019 // of liability and disclaimer of warranty provisions.
00020 
00021 #include "copyright.h"
00022 #include "scheduler.h"
00023 #include "system.h"
00024 
00025 //----------------------------------------------------------------------
00026 // Scheduler::Scheduler
00027 //      Initialize the list of ready but not running threads to empty.
00028 //----------------------------------------------------------------------
00029 
00030 Scheduler::Scheduler()
00031 { 
00032     readyList = new List; 
00033 } 
00034 
00035 //----------------------------------------------------------------------
00036 // Scheduler::~Scheduler
00037 //      De-allocate the list of ready threads.
00038 //----------------------------------------------------------------------
00039 
00040 Scheduler::~Scheduler()
00041 { 
00042     delete readyList; 
00043 } 
00044 
00045 //----------------------------------------------------------------------
00046 // Scheduler::ReadyToRun
00047 //      Mark a thread as ready, but not running.
00048 //      Put it on the ready list, for later scheduling onto the CPU.
00049 //
00050 //      "thread" is the thread to be put on the ready list.
00051 //----------------------------------------------------------------------
00052 
00053 void
00054 Scheduler::ReadyToRun (Thread *thread)
00055 {
00056     DEBUG('t', "Putting thread %s on ready list.\n", thread->getName());
00057 
00058     thread->setStatus(READY);
00059     readyList->Append((void *)thread);
00060 }
00061 
00062 //----------------------------------------------------------------------
00063 // Scheduler::FindNextToRun
00064 //      Return the next thread to be scheduled onto the CPU.
00065 //      If there are no ready threads, return NULL.
00066 // Side effect:
00067 //      Thread is removed from the ready list.
00068 //----------------------------------------------------------------------
00069 
00070 Thread *
00071 Scheduler::FindNextToRun ()
00072 {
00073     return (Thread *)readyList->Remove();
00074 }
00075 
00076 //----------------------------------------------------------------------
00077 // Scheduler::Run
00078 //      Dispatch the CPU to nextThread.  Save the state of the old thread,
00079 //      and load the state of the new thread, by calling the machine
00080 //      dependent context switch routine, SWITCH.
00081 //
00082 //      Note: we assume the state of the previously running thread has
00083 //      already been changed from running to blocked or ready (depending).
00084 // Side effect:
00085 //      The global variable currentThread becomes nextThread.
00086 //
00087 //      "nextThread" is the thread to be put into the CPU.
00088 //----------------------------------------------------------------------
00089 
00090 void
00091 Scheduler::Run (Thread *nextThread)
00092 {
00093     Thread *oldThread = currentThread;
00094     
00095 #ifdef USER_PROGRAM                     // ignore until running user programs 
00096     if (currentThread->space != NULL) { // if this thread is a user program,
00097         currentThread->SaveUserState(); // save the user's CPU registers
00098         currentThread->space->SaveState();
00099     }
00100 #endif
00101     
00102     oldThread->CheckOverflow();             // check if the old thread
00103                                             // had an undetected stack overflow
00104 
00105     currentThread = nextThread;             // switch to the next thread
00106     currentThread->setStatus(RUNNING);      // nextThread is now running
00107     
00108     DEBUG('t', "Switching from thread \"%s\" to thread \"%s\"\n",
00109           oldThread->getName(), nextThread->getName());
00110     
00111     // This is a machine-dependent assembly language routine defined 
00112     // in switch.s.  You may have to think
00113     // a bit to figure out what happens after this, both from the point
00114     // of view of the thread and from the perspective of the "outside world".
00115 
00116     SWITCH(oldThread, nextThread);
00117     
00118     DEBUG('t', "Now in thread \"%s\"\n", currentThread->getName());
00119 
00120     // If the old thread gave up the processor because it was finishing,
00121     // we need to delete its carcass.  Note we cannot delete the thread
00122     // before now (for example, in Thread::Finish()), because up to this
00123     // point, we were still running on the old thread's stack!
00124     if (threadToBeDestroyed != NULL) {
00125         delete threadToBeDestroyed;
00126         threadToBeDestroyed = NULL;
00127     }
00128     
00129 #ifdef USER_PROGRAM
00130     if (currentThread->space != NULL) {         // if there is an address space
00131         currentThread->RestoreUserState();     // to restore, do it.
00132         currentThread->space->RestoreState();
00133     }
00134 #endif
00135 }
00136 
00137 //----------------------------------------------------------------------
00138 // Scheduler::Print
00139 //      Print the scheduler state -- in other words, the contents of
00140 //      the ready list.  For debugging.
00141 //----------------------------------------------------------------------
00142 void
00143 Scheduler::Print()
00144 {
00145     printf("Ready list contents:\n");
00146     readyList->Mapcar((VoidFunctionPtr) ThreadPrint);
00147 }

Generated on Mon Feb 10 09:54:47 2003 for nachos by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002
The University of Southern California does not screen or control the content on this website and thus does not guarantee the accuracy, integrity, or quality of such content. All content on this website is provided by and is the sole responsibility of the person from which such content originated, and such content does not necessarily reflect the opinions of the University administration or the Board of Trustees