NachOS/code/machine/interrupt.h

134 lines
5 KiB
C++

// interrupt.h
// Data structures to emulate low-level interrupt hardware.
//
// The hardware provides a routine (SetLevel) to enable or disable
// interrupts.
//
// In order to emulate the hardware, we need to keep track of all
// interrupts the hardware devices would cause, and when they
// are supposed to occur.
//
// This module also keeps track of simulated time. Time advances
// only when the following occur:
// interrupts are re-enabled
// a user instruction is executed
// there is nothing in the ready queue
//
// As a result, unlike real hardware, interrupts (and thus time-slice
// context switches) cannot occur anywhere in the code where interrupts
// are enabled, but rather only at those places in the code where
// simulated time advances (so that it becomes time to invoke an
// interrupt in the hardware simulation).
//
// NOTE: this means that incorrectly synchronized code may work
// fine on this hardware simulation (even with randomized time slices),
// but it wouldn't work on real hardware. (Just because we can't
// always detect when your program would fail in real life, does not
// mean it's ok to write incorrectly synchronized code!)
//
// DO NOT CHANGE -- part of the machine emulation
//
// Copyright (c) 1992-1993 The Regents of the University of California.
// All rights reserved. See copyright.h for copyright notice and limitation
// of liability and disclaimer of warranty provisions.
#ifndef INTERRUPT_H
#define INTERRUPT_H
#include "copyright.h"
#include "list.h"
// Interrupts can be disabled (IntOff) or enabled (IntOn)
enum IntStatus { IntOff, IntOn };
// Nachos can be running kernel code (SystemMode), user code (UserMode),
// or there can be no runnable thread, because the ready list
// is empty (IdleMode).
enum MachineStatus {IdleMode, SystemMode, UserMode};
// IntType records which hardware device generated an interrupt.
// In Nachos, we support a hardware timer device, a disk, a console
// display and keyboard, and a network.
enum IntType { TimerInt, DiskInt, ConsoleWriteInt, ConsoleReadInt,
NetworkSendInt, NetworkRecvInt};
// The following class defines an interrupt that is scheduled
// to occur in the future. The internal data structures are
// left public to make it simpler to manipulate.
class PendingInterrupt {
public:
PendingInterrupt(VoidFunctionPtr func, void *param,
long long time, IntType kind);
// initialize an interrupt that will
// occur in the future
VoidFunctionPtr handler; // The function (in the hardware device
// emulator) to call when the interrupt occurs
void *arg; // The argument to the function.
long long when; // When the interrupt is supposed to fire
IntType type; // for debugging
};
// The following class defines the data structures for the simulation
// of hardware interrupts. We record whether interrupts are enabled
// or disabled, and any hardware interrupts that are scheduled to occur
// in the future.
class Interrupt:public dontcopythis {
public:
Interrupt(); // initialize the interrupt simulation
~Interrupt(); // de-allocate data structures
IntStatus SetLevel(IntStatus level);// Disable or enable interrupts
// and return previous setting.
void Enable(); // Enable interrupts.
IntStatus getLevel() {return level;}// Return whether interrupts
// are enabled or disabled
void Idle(); // The ready queue is empty, roll
// simulated time forward until the
// next interrupt
void Powerdown(); // quit and print out stats
void YieldOnReturn(); // cause a context switch on return
// from an interrupt handler
MachineStatus getStatus() { return status; } // idle, kernel, user
void setStatus(MachineStatus st) { status = st; }
void DumpState(); // Print interrupt state
// NOTE: the following are internal to the hardware simulation code.
// DO NOT call these directly. I should make them "private",
// but they need to be public since they are called by the
// hardware device simulators.
void Schedule(VoidFunctionPtr handler,// Schedule an interrupt to occur
void *arg, long long when, IntType type);// at time ``when''. This is called
// by the hardware device simulators.
void OneTick(); // Advance simulated time
private:
IntStatus level; // are interrupts enabled or disabled?
List *pending; // the list of interrupts scheduled
// to occur in the future
bool inHandler; // TRUE if we are running an interrupt handler
bool yieldOnReturn; // TRUE if we are to context switch
// on return from the interrupt handler
MachineStatus status; // idle, kernel mode, user mode
// these functions are internal to the interrupt simulation code
bool CheckIfDue(bool advanceClock); // Check if an interrupt is supposed
// to occur now
void ChangeLevel(IntStatus old, // SetLevel, without advancing the
IntStatus now); // simulated time
};
#endif // INTERRRUPT_H