using namespace std;
SimpleCPU::TickEvent::TickEvent(SimpleCPU *c)
- : Event(&mainEventQueue, 100), cpu(c)
+ : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c)
{
}
// constructor: schedule at specified time
//
DebugBreakEvent::DebugBreakEvent(EventQueue *q, Tick _when)
- : Event(q)
+ : Event(q, Debug_Break_Pri)
{
setFlags(AutoDelete);
- schedule(_when, -20000);
+ schedule(_when);
}
//
public:
+ /// Event priorities, to provide tie-breakers for events scheduled
+ /// at the same cycle. Most events are scheduled at the default
+ /// priority; these values are used to control events that need to
+ /// be ordered within a cycle.
+ enum Priority {
+ /// Breakpoints should happen before anything else, so we
+ /// don't miss any action when debugging.
+ Debug_Break_Pri = -100,
+
+ /// For some reason "delayed" inter-cluster writebacks are
+ /// scheduled before regular writebacks (which have default
+ /// priority). Steve?
+ Delayed_Writeback_Pri = -1,
+
+ /// Default is zero for historical reasons.
+ Default_Pri = 0,
+
+ /// CPU switches schedule the new CPU's tick event for the
+ /// same cycle (after unscheduling the old CPU's tick event).
+ /// The switch needs to come before any tick events to make
+ /// sure we don't tick both CPUs in the same cycle.
+ CPU_Switch_Pri = 31,
+
+ /// Serailization needs to occur before tick events also, so
+ /// that a serialize/unserialize is identical to an on-line
+ /// CPU switch.
+ Serialize_Pri = 32,
+
+ /// CPU ticks must come after other associated CPU events
+ /// (such as writebacks).
+ CPU_Tick_Pri = 50,
+
+ /// Statistics events (dump, reset, etc.) come after
+ /// everything else, but before exit.
+ Stat_Event_Pri = 90,
+
+ /// If we want to exit on this cycle, it's the very last thing
+ /// we do.
+ Sim_Exit_Pri = 100
+ };
+
/*
* Event constructor
* @param queue that the event gets scheduled on
*/
- Event(EventQueue *q, int p = 0)
+ Event(EventQueue *q, Priority p = Default_Pri)
: queue(q), next(NULL), _priority(p), _flags(None),
#if TRACING_ON
when_created(curTick), when_scheduled(0),
/// Schedule the event with the current priority or default priority
void schedule(Tick t);
- /// Schedule the event with a specific priority
- void schedule(Tick t, int priority);
-
/// Reschedule the event with the current priority
void reschedule(Tick t);
- /// Reschedule the event with a specific priority
- void reschedule(Tick t, int priority);
-
/// Remove the event from the current schedule
void deschedule();
queue->schedule(this);
}
-inline void
-Event::schedule(Tick t, int p)
-{
- _priority = p;
- schedule(t);
-}
-
inline void
Event::deschedule()
{
queue->reschedule(this);
}
-inline void
-Event::reschedule(Tick t, int p)
-{
- _priority = p;
- reschedule(t);
-}
-
inline void
EventQueue::schedule(Event *event)
{
};
SerializeEvent::SerializeEvent(Tick _when, Tick _repeat)
- : Event(&mainEventQueue, 990), repeat(_repeat)
+ : Event(&mainEventQueue, Serialize_Pri), repeat(_repeat)
{
setFlags(AutoDelete);
schedule(_when);
//
CountedExitEvent::CountedExitEvent(EventQueue *q, const std::string &_cause,
Tick _when, int &_downCounter)
- : Event(q),
+ : Event(q, Sim_Exit_Pri),
cause(_cause),
downCounter(_downCounter)
{
// catch stupid mistakes
assert(downCounter > 0);
- schedule(_when, 1000);
+ schedule(_when);
}
public:
SimExitEvent(const std::string &_cause, int c = 0)
- : Event(&mainEventQueue), cause(_cause),
+ : Event(&mainEventQueue, Sim_Exit_Pri), cause(_cause),
code(c)
- { schedule(curTick, 1000); }
+ { schedule(curTick); }
SimExitEvent(Tick _when, const std::string &_cause, int c = 0)
- : Event(&mainEventQueue), cause(_cause),
+ : Event(&mainEventQueue, Sim_Exit_Pri), cause(_cause),
code(c)
- { schedule(_when, 1000); }
+ { schedule(_when); }
SimExitEvent(EventQueue *q, const std::string &_cause, int c = 0)
- : Event(q), cause(_cause), code(c)
- { schedule(curTick, 1000); }
+ : Event(q, Sim_Exit_Pri), cause(_cause), code(c)
+ { schedule(curTick); }
SimExitEvent(EventQueue *q, Tick _when, const std::string &_cause,
int c = 0)
- : Event(q), cause(_cause), code(c)
- { schedule(_when, 1000); }
+ : Event(q, Sim_Exit_Pri), cause(_cause), code(c)
+ { schedule(_when); }
void process(); // process event