00001 // timer.cc 00002 // Routines to emulate a hardware timer device. 00003 // 00004 // A hardware timer generates a CPU interrupt every X milliseconds. 00005 // This means it can be used for implementing time-slicing. 00006 // 00007 // We emulate a hardware timer by scheduling an interrupt to occur 00008 // every time stats->totalTicks has increased by TimerTicks. 00009 // 00010 // In order to introduce some randomness into time-slicing, if "doRandom" 00011 // is set, then the interrupt is comes after a random number of ticks. 00012 // 00013 // Remember -- nothing in here is part of Nachos. It is just 00014 // an emulation for the hardware that Nachos is running on top of. 00015 // 00016 // DO NOT CHANGE -- part of the machine emulation 00017 // 00018 // Copyright (c) 1992-1996 The Regents of the University of California. 00019 // All rights reserved. See copyright.h for copyright notice and limitation 00020 // of liability and disclaimer of warranty provisions. 00021 00022 #include "copyright.h" 00023 #include "timer.h" 00024 #include "main.h" 00025 #include "sysdep.h" 00026 00027 //---------------------------------------------------------------------- 00028 // Timer::Timer 00029 // Initialize a hardware timer device. Save the place to call 00030 // on each interrupt, and then arrange for the timer to start 00031 // generating interrupts. 00032 // 00033 // "doRandom" -- if true, arrange for the interrupts to occur 00034 // at random, instead of fixed, intervals. 00035 // "toCall" is the interrupt handler to call when the timer expires. 00036 //---------------------------------------------------------------------- 00037 00038 Timer::Timer(bool doRandom, CallBackObj *toCall) 00039 { 00040 randomize = doRandom; 00041 callPeriodically = toCall; 00042 disable = FALSE; 00043 SetInterrupt(); 00044 } 00045 00046 //---------------------------------------------------------------------- 00047 // Timer::CallBack 00048 // Routine called when interrupt is generated by the hardware 00049 // timer device. Schedule the next interrupt, and invoke the 00050 // interrupt handler. 00051 //---------------------------------------------------------------------- 00052 void 00053 Timer::CallBack() 00054 { 00055 // invoke the Nachos interrupt handler for this device 00056 callPeriodically->CallBack(); 00057 00058 SetInterrupt(); // do last, to let software interrupt handler 00059 // decide if it wants to disable future interrupts 00060 } 00061 00062 //---------------------------------------------------------------------- 00063 // Timer::SetInterrupt 00064 // Cause a timer interrupt to occur in the future, unless 00065 // future interrupts have been disabled. The delay is either 00066 // fixed or random. 00067 //---------------------------------------------------------------------- 00068 00069 void 00070 Timer::SetInterrupt() 00071 { 00072 if (!disable) { 00073 int delay = TimerTicks; 00074 00075 if (randomize) { 00076 delay = 1 + (RandomNumber() % (TimerTicks * 2)); 00077 } 00078 // schedule the next timer device interrupt 00079 kernel->interrupt->Schedule(this, delay, TimerInt); 00080 } 00081 }