00001 // alarm.cc 00002 // Routines to use a hardware timer device to provide a 00003 // software alarm clock. For now, we just provide time-slicing. 00004 // 00005 // Not completely implemented. 00006 // 00007 // Copyright (c) 1992-1996 The Regents of the University of California. 00008 // All rights reserved. See copyright.h for copyright notice and limitation 00009 // of liability and disclaimer of warranty provisions. 00010 00011 #include "copyright.h" 00012 #include "alarm.h" 00013 #include "main.h" 00014 00015 //---------------------------------------------------------------------- 00016 // Alarm::Alarm 00017 // Initialize a software alarm clock. Start up a timer device 00018 // 00019 // "doRandom" -- if true, arrange for the hardware interrupts to 00020 // occur at random, instead of fixed, intervals. 00021 //---------------------------------------------------------------------- 00022 00023 Alarm::Alarm(bool doRandom) 00024 { 00025 timer = new Timer(doRandom, this); 00026 } 00027 00028 //---------------------------------------------------------------------- 00029 // Alarm::CallBack 00030 // Software interrupt handler for the timer device. The timer device is 00031 // set up to interrupt the CPU periodically (once every TimerTicks). 00032 // This routine is called each time there is a timer interrupt, 00033 // with interrupts disabled. 00034 // 00035 // Note that instead of calling Yield() directly (which would 00036 // suspend the interrupt handler, not the interrupted thread 00037 // which is what we wanted to context switch), we set a flag 00038 // so that once the interrupt handler is done, it will appear as 00039 // if the interrupted thread called Yield at the point it is 00040 // was interrupted. 00041 // 00042 // For now, just provide time-slicing. Only need to time slice 00043 // if we're currently running something (in other words, not idle). 00044 //---------------------------------------------------------------------- 00045 00046 void 00047 Alarm::CallBack() 00048 { 00049 Interrupt *interrupt = kernel->interrupt; 00050 MachineStatus status = interrupt->getStatus(); 00051 00052 if (status != IdleMode) { 00053 interrupt->YieldOnReturn(); 00054 } 00055 }