Main Page   Compound List   File List   Compound Members   File Members  

Interrupt Class Reference

#include <interrupt.h>

List of all members.

Public Methods

 Interrupt ()
 ~Interrupt ()
IntStatus SetLevel (IntStatus level)
void Enable ()
IntStatus getLevel ()
void Idle ()
void Halt ()
void YieldOnReturn ()
MachineStatus getStatus ()
void setStatus (MachineStatus st)
void DumpState ()
void Schedule (VoidFunctionPtr handler, int arg, int when, IntType type)
void OneTick ()

Private Methods

bool CheckIfDue (bool advanceClock)
void ChangeLevel (IntStatus old, IntStatus now)

Private Attributes

IntStatus level
Listpending
bool inHandler
bool yieldOnReturn
MachineStatus status


Constructor & Destructor Documentation

Interrupt::Interrupt  
 

Definition at line 60 of file interrupt.cc.

References FALSE, inHandler, IntOff, level, pending, status, SystemMode, and yieldOnReturn.

00061 {
00062     level = IntOff;
00063     pending = new List();
00064     inHandler = FALSE;
00065     yieldOnReturn = FALSE;
00066     status = SystemMode;
00067 }

Interrupt::~Interrupt  
 

Definition at line 74 of file interrupt.cc.

References List::IsEmpty, pending, and List::Remove.

00075 {
00076     while (!pending->IsEmpty())
00077         delete pending->Remove();
00078     delete pending;
00079 }


Member Function Documentation

void Interrupt::ChangeLevel IntStatus    old,
IntStatus    now
[private]
 

Definition at line 97 of file interrupt.cc.

References DEBUG, intLevelNames, IntStatus, and level.

Referenced by OneTick, and SetLevel.

00098 {
00099     level = now;
00100     DEBUG('i',"\tinterrupts: %s -> %s\n",intLevelNames[old],intLevelNames[now]);
00101 }

bool Interrupt::CheckIfDue bool    advanceClock [private]
 

Definition at line 291 of file interrupt.cc.

References PendingInterrupt::arg, ASSERT, DEBUG, DebugIsEnabled, DumpState, FALSE, PendingInterrupt::handler, IdleMode, inHandler, IntOff, intTypeNames, List::IsEmpty, level, MachineStatus, NULL, pending, List::SortedInsert, List::SortedRemove, status, SystemMode, TimerInt, TRUE, PendingInterrupt::type, and PendingInterrupt::when.

Referenced by Idle, and OneTick.

00292 {
00293     MachineStatus old = status;
00294     int when;
00295 
00296     ASSERT(level == IntOff);            // interrupts need to be disabled,
00297                                         // to invoke an interrupt handler
00298     if (DebugIsEnabled('i'))
00299         DumpState();
00300     PendingInterrupt *toOccur = 
00301                 (PendingInterrupt *)pending->SortedRemove(&when);
00302 
00303     if (toOccur == NULL)                // no pending interrupts
00304         return FALSE;                   
00305 
00306     if (advanceClock && when > stats->totalTicks) {     // advance the clock
00307         stats->idleTicks += (when - stats->totalTicks);
00308         stats->totalTicks = when;
00309     } else if (when > stats->totalTicks) {      // not time yet, put it back
00310         pending->SortedInsert(toOccur, when);
00311         return FALSE;
00312     }
00313 
00314 // Check if there is nothing more to do, and if so, quit
00315     if ((status == IdleMode) && (toOccur->type == TimerInt) 
00316                                 && pending->IsEmpty()) {
00317          pending->SortedInsert(toOccur, when);
00318          return FALSE;
00319     }
00320 
00321     DEBUG('i', "Invoking interrupt handler for the %s at time %d\n", 
00322                         intTypeNames[toOccur->type], toOccur->when);
00323 #ifdef USER_PROGRAM
00324     if (machine != NULL)
00325         machine->DelayedLoad(0, 0);
00326 #endif
00327     inHandler = TRUE;
00328     status = SystemMode;                        // whatever we were doing,
00329                                                 // we are now going to be
00330                                                 // running in the kernel
00331     (*(toOccur->handler))(toOccur->arg);        // call the interrupt handler
00332     status = old;                               // restore the machine status
00333     inHandler = FALSE;
00334     delete toOccur;
00335     return TRUE;
00336 }

void Interrupt::DumpState  
 

Definition at line 360 of file interrupt.cc.

References intLevelNames, level, List::Mapcar, pending, and PrintPending.

Referenced by CheckIfDue.

00361 {
00362     printf("Time: %d, interrupts %s\n", stats->totalTicks, 
00363                                         intLevelNames[level]);
00364     printf("Pending interrupts:\n");
00365     fflush(stdout);
00366     pending->Mapcar(PrintPending);
00367     printf("End of pending interrupts\n");
00368     fflush(stdout);
00369 }

void Interrupt::Enable  
 

Definition at line 136 of file interrupt.cc.

References IntOn, and SetLevel.

Referenced by Initialize.

00137 { 
00138     (void) SetLevel(IntOn); 
00139 }

IntStatus Interrupt::getLevel   [inline]
 

Definition at line 86 of file interrupt.h.

References IntStatus, and level.

00086 {return level;}// Return whether interrupts

MachineStatus Interrupt::getStatus   [inline]
 

Definition at line 98 of file interrupt.h.

References MachineStatus, and status.

Referenced by TimerInterruptHandler.

00098 { return status; } // idle, kernel, user

void Interrupt::Halt  
 

Definition at line 241 of file interrupt.cc.

References Cleanup.

Referenced by Idle.

00242 {
00243     printf("Machine halting!\n\n");
00244     stats->Print();
00245     Cleanup();     // Never returns.
00246 }

void Interrupt::Idle  
 

Definition at line 211 of file interrupt.cc.

References CheckIfDue, DEBUG, FALSE, Halt, IdleMode, status, SystemMode, TRUE, and yieldOnReturn.

00212 {
00213     DEBUG('i', "Machine idling; checking for interrupts.\n");
00214     status = IdleMode;
00215     if (CheckIfDue(TRUE)) {             // check for any pending interrupts
00216         while (CheckIfDue(FALSE))       // check for any other pending 
00217             ;                           // interrupts
00218         yieldOnReturn = FALSE;          // since there's nothing in the
00219                                         // ready queue, the yield is automatic
00220         status = SystemMode;
00221         return;                         // return in case there's now
00222                                         // a runnable thread
00223     }
00224 
00225     // if there are no pending interrupts, and nothing is on the ready
00226     // queue, it is time to stop.   If the console or the network is 
00227     // operating, there are *always* pending interrupts, so this code
00228     // is not reached.  Instead, the halt must be invoked by the user program.
00229 
00230     DEBUG('i', "Machine idle.  No interrupts to do.\n");
00231     printf("No threads ready or runnable, and no pending interrupts.\n");
00232     printf("Assuming the program completed.\n");
00233     Halt();
00234 }

void Interrupt::OneTick  
 

Definition at line 151 of file interrupt.cc.

References ChangeLevel, CheckIfDue, DEBUG, FALSE, IntOff, IntOn, MachineStatus, status, SystemMode, SystemTick, UserTick, and yieldOnReturn.

Referenced by SetLevel.

00152 {
00153     MachineStatus old = status;
00154 
00155 // advance simulated time
00156     if (status == SystemMode) {
00157         stats->totalTicks += SystemTick;
00158         stats->systemTicks += SystemTick;
00159     } else {                                    // USER_PROGRAM
00160         stats->totalTicks += UserTick;
00161         stats->userTicks += UserTick;
00162     }
00163     DEBUG('i', "\n== Tick %d ==\n", stats->totalTicks);
00164 
00165 // check any pending interrupts are now ready to fire
00166     ChangeLevel(IntOn, IntOff);         // first, turn off interrupts
00167                                         // (interrupt handlers run with
00168                                         // interrupts disabled)
00169     while (CheckIfDue(FALSE))           // check for pending interrupts
00170         ;
00171     ChangeLevel(IntOff, IntOn);         // re-enable interrupts
00172     if (yieldOnReturn) {                // if the timer device handler asked 
00173                                         // for a context switch, ok to do it now
00174         yieldOnReturn = FALSE;
00175         status = SystemMode;            // yield is a kernel routine
00176         currentThread->Yield();
00177         status = old;
00178     }
00179 }

void Interrupt::Schedule VoidFunctionPtr    handler,
int    arg,
int    when,
IntType    type
 

Definition at line 265 of file interrupt.cc.

References ASSERT, DEBUG, IntType, intTypeNames, pending, List::SortedInsert, and VoidFunctionPtr.

00266 {
00267     int when = stats->totalTicks + fromNow;
00268     PendingInterrupt *toOccur = new PendingInterrupt(handler, arg, when, type);
00269 
00270     DEBUG('i', "Scheduling interrupt handler the %s at time = %d\n", 
00271                                         intTypeNames[type], when);
00272     ASSERT(fromNow > 0);
00273 
00274     pending->SortedInsert(toOccur, when);
00275 }

IntStatus Interrupt::SetLevel IntStatus    level
 

Definition at line 115 of file interrupt.cc.

References ASSERT, ChangeLevel, FALSE, inHandler, IntOff, IntOn, IntStatus, level, and OneTick.

Referenced by Enable.

00116 {
00117     IntStatus old = level;
00118     
00119     ASSERT((now == IntOff) || (inHandler == FALSE));// interrupt handlers are 
00120                                                 // prohibited from enabling 
00121                                                 // interrupts
00122 
00123     ChangeLevel(old, now);                      // change to new state
00124     if ((now == IntOn) && (old == IntOff))
00125         OneTick();                              // advance simulated time
00126     return old;
00127 }

void Interrupt::setStatus MachineStatus    st [inline]
 

Definition at line 99 of file interrupt.h.

References MachineStatus, and status.

00099 { status = st; }

void Interrupt::YieldOnReturn  
 

Definition at line 193 of file interrupt.cc.

References ASSERT, inHandler, TRUE, and yieldOnReturn.

Referenced by TimerInterruptHandler.

00194 { 
00195     ASSERT(inHandler == TRUE);  
00196     yieldOnReturn = TRUE; 
00197 }


Member Data Documentation

bool Interrupt::inHandler [private]
 

Definition at line 119 of file interrupt.h.

Referenced by CheckIfDue, Interrupt, SetLevel, and YieldOnReturn.

IntStatus Interrupt::level [private]
 

Definition at line 116 of file interrupt.h.

Referenced by ChangeLevel, CheckIfDue, DumpState, getLevel, Interrupt, and SetLevel.

List* Interrupt::pending [private]
 

Definition at line 117 of file interrupt.h.

Referenced by CheckIfDue, DumpState, Interrupt, Schedule, and ~Interrupt.

MachineStatus Interrupt::status [private]
 

Definition at line 122 of file interrupt.h.

Referenced by CheckIfDue, getStatus, Idle, Interrupt, OneTick, and setStatus.

bool Interrupt::yieldOnReturn [private]
 

Definition at line 120 of file interrupt.h.

Referenced by Idle, Interrupt, OneTick, and YieldOnReturn.


The documentation for this class was generated from the following files:
Generated on Mon Feb 10 09:54:56 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