eventq: convert all usage of events to use the new API.

For now, there is still a single global event queue, but this is
necessary for making the steps towards a parallelized m5.
This commit is contained in:
Nathan Binkert
2008-10-09 04:58:24 -07:00
parent 8291d9db0a
commit e06321091d
68 changed files with 398 additions and 388 deletions

View File

@@ -56,12 +56,9 @@ debug_break()
// Debug event: place a breakpoint on the process function and
// schedule the event to break at a particular cycle
//
class DebugBreakEvent : public Event
struct DebugBreakEvent : public Event
{
public:
DebugBreakEvent(EventQueue *q, Tick _when);
DebugBreakEvent();
void process(); // process event
virtual const char *description() const;
};
@@ -69,11 +66,10 @@ class DebugBreakEvent : public Event
//
// constructor: schedule at specified time
//
DebugBreakEvent::DebugBreakEvent(EventQueue *q, Tick _when)
: Event(q, Debug_Break_Pri)
DebugBreakEvent::DebugBreakEvent()
: Event(Debug_Break_Pri)
{
setFlags(AutoDelete);
schedule(_when);
}
//
@@ -99,13 +95,15 @@ DebugBreakEvent::description() const
void
schedBreakCycle(Tick when)
{
new DebugBreakEvent(&mainEventQueue, when);
mainEventQueue.schedule(new DebugBreakEvent, when);
warn("need to stop all queues");
}
void
eventqDump()
{
mainEventQueue.dump();
warn("need to dump all queues");
}

View File

@@ -44,6 +44,7 @@
#include "params/BaseCPU.hh"
#include "sim/pseudo_inst.hh"
#include "sim/serialize.hh"
#include "sim/sim_events.hh"
#include "sim/sim_exit.hh"
#include "sim/stat_control.hh"
#include "sim/stats.hh"
@@ -88,7 +89,7 @@ quiesceNs(ThreadContext *tc, uint64_t ns)
Tick resume = curTick + Clock::Int::ns * ns;
quiesceEvent->reschedule(resume, true);
mainEventQueue.reschedule(quiesceEvent, resume, true);
DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n",
tc->getCpuPtr()->name(), ns, resume);
@@ -108,7 +109,7 @@ quiesceCycles(ThreadContext *tc, uint64_t cycles)
Tick resume = curTick + tc->getCpuPtr()->ticks(cycles);
quiesceEvent->reschedule(resume, true);
mainEventQueue.reschedule(quiesceEvent, resume, true);
DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n",
tc->getCpuPtr()->name(), cycles, resume);
@@ -128,7 +129,8 @@ void
m5exit(ThreadContext *tc, Tick delay)
{
Tick when = curTick + delay * Clock::Int::ns;
schedExitSimLoop("m5_exit instruction encountered", when);
Event *event = new SimLoopExitEvent("m5_exit instruction encountered", 0);
mainEventQueue.schedule(event, when);
}
void
@@ -239,7 +241,8 @@ m5checkpoint(ThreadContext *tc, Tick delay, Tick period)
Tick when = curTick + delay * Clock::Int::ns;
Tick repeat = period * Clock::Int::ns;
schedExitSimLoop("checkpoint", when, repeat);
Event *event = new SimLoopExitEvent("checkpoint", 0, repeat);
mainEventQueue.schedule(event, when);
}
uint64_t

View File

@@ -40,6 +40,13 @@
using namespace std;
SimLoopExitEvent::SimLoopExitEvent(const std::string &_cause, int c, Tick r)
: Event(Sim_Exit_Pri), cause(_cause), code(c), repeat(r)
{
setFlags(IsExitEvent);
}
//
// handle termination event
//
@@ -49,7 +56,7 @@ SimLoopExitEvent::process()
// if this got scheduled on a different queue (e.g. the committed
// instruction queue) then make a corresponding event on the main
// queue.
if (queue() != &mainEventQueue) {
if (!getFlags(IsMainQueue)) {
exitSimLoop(cause, code);
delete this;
}
@@ -59,7 +66,8 @@ SimLoopExitEvent::process()
// but if you are doing this on intervals, don't forget to make another
if (repeat) {
schedule(curTick + repeat);
assert(getFlags(IsMainQueue));
mainEventQueue.schedule(this, curTick + repeat);
}
}
@@ -70,43 +78,32 @@ SimLoopExitEvent::description() const
return "simulation loop exit";
}
SimLoopExitEvent *
schedExitSimLoop(const std::string &message, Tick when, Tick repeat,
EventQueue *q, int exit_code)
{
if (q == NULL)
q = &mainEventQueue;
return new SimLoopExitEvent(q, when, repeat, message, exit_code);
}
void
exitSimLoop(const std::string &message, int exit_code)
{
schedExitSimLoop(message, curTick, 0, NULL, exit_code);
Event *event = new SimLoopExitEvent(message, exit_code);
mainEventQueue.schedule(event, curTick);
}
CountedDrainEvent::CountedDrainEvent()
: SimLoopExitEvent("Finished drain", 0), count(0)
{ }
void
CountedDrainEvent::process()
{
if (--count == 0) {
exitSimLoop("Finished drain");
}
if (--count == 0)
exitSimLoop(cause, code);
}
//
// constructor: automatically schedules at specified time
//
CountedExitEvent::CountedExitEvent(EventQueue *q, const std::string &_cause,
Tick _when, int &_downCounter)
: Event(q, Sim_Exit_Pri),
cause(_cause),
downCounter(_downCounter)
CountedExitEvent::CountedExitEvent(const std::string &_cause, int &counter)
: Event(Sim_Exit_Pri), cause(_cause), downCounter(counter)
{
// catch stupid mistakes
assert(downCounter > 0);
schedule(_when);
}
@@ -128,9 +125,11 @@ CountedExitEvent::description() const
return "counted exit";
}
#ifdef CHECK_SWAP_CYCLES
new CheckSwapEvent(&mainEventQueue, CHECK_SWAP_CYCLES);
#endif
CheckSwapEvent::CheckSwapEvent(int ival)
: interval(ival)
{
mainEventQueue.schedule(this, curTick + interval);
}
void
CheckSwapEvent::process()
@@ -149,7 +148,8 @@ CheckSwapEvent::process()
exitSimLoop("Lack of swap space");
}
schedule(curTick + interval);
assert(getFlags(IsMainQueue));
mainEventQueue.schedule(this, curTick + interval);
}
const char *

View File

@@ -38,30 +38,14 @@
//
class SimLoopExitEvent : public Event
{
private:
protected:
// string explaining why we're terminating
std::string cause;
int code;
Tick repeat;
public:
// Default constructor. Only really used for derived classes.
SimLoopExitEvent()
: Event(&mainEventQueue, Sim_Exit_Pri)
{ }
SimLoopExitEvent(EventQueue *q,
Tick _when, Tick _repeat, const std::string &_cause,
int c = 0)
: Event(q, Sim_Exit_Pri), cause(_cause),
code(c), repeat(_repeat)
{ setFlags(IsExitEvent); schedule(_when); }
// SimLoopExitEvent(EventQueue *q,
// Tick _when, const std::string &_cause,
// Tick _repeat = 0, int c = 0)
// : Event(q, Sim_Exit_Pri), cause(_cause), code(c), repeat(_repeat)
// { setFlags(IsExitEvent); schedule(_when); }
SimLoopExitEvent(const std::string &_cause, int c, Tick repeat = 0);
std::string getCause() { return cause; }
int getCode() { return code; }
@@ -76,10 +60,10 @@ class CountedDrainEvent : public SimLoopExitEvent
private:
// Count of how many objects have not yet drained
int count;
public:
CountedDrainEvent()
: count(0)
{ }
CountedDrainEvent();
void process();
void setCount(int _count) { count = _count; }
@@ -99,8 +83,7 @@ class CountedExitEvent : public Event
int &downCounter; // decrement & terminate if zero
public:
CountedExitEvent(EventQueue *q, const std::string &_cause,
Tick _when, int &_downCounter);
CountedExitEvent(const std::string &_cause, int &_downCounter);
void process(); // process event
@@ -116,10 +99,7 @@ class CheckSwapEvent : public Event
int interval;
public:
CheckSwapEvent(EventQueue *q, int ival)
: Event(q), interval(ival)
{ schedule(curTick + interval); }
CheckSwapEvent(int ival);
void process(); // process event
virtual const char *description() const;

View File

@@ -45,14 +45,6 @@ class SimLoopExitEvent;
/// sim/main.cc.
void registerExitCallback(Callback *);
/// Schedule an event to exit the simulation loop (returning to
/// Python) at the indicated tick. The message and exit_code
/// parameters are saved in the SimLoopExitEvent to indicate why the
/// exit occurred.
SimLoopExitEvent *schedExitSimLoop(const std::string &message, Tick when,
Tick repeat = 0, EventQueue *q = NULL,
int exit_code = 0);
/// Schedule an event to exit the simulation loop (returning to
/// Python) at the end of the current cycle (curTick). The message
/// and exit_code parameters are saved in the SimLoopExitEvent to

View File

@@ -39,8 +39,14 @@ struct PyObject;
#include <string>
struct EventQueue;
struct SimObjectParams
{
SimObjectParams()
{
extern EventQueue mainEventQueue;
eventq = &mainEventQueue;
}
virtual ~SimObjectParams() {}
std::string name;

View File

@@ -56,8 +56,9 @@ simulate(Tick num_cycles)
else
num_cycles = curTick + num_cycles;
Event *limit_event;
limit_event = schedExitSimLoop("simulate() limit reached", num_cycles);
Event *limit_event =
new SimLoopExitEvent("simulate() limit reached", 0);
mainEventQueue.schedule(limit_event, num_cycles);
while (1) {
// there should always be at least one event (the SimLoopExitEvent
@@ -82,8 +83,8 @@ simulate(Tick num_cycles)
// if we didn't hit limit_event, delete it
if (se_event != limit_event) {
assert(limit_event->scheduled());
limit_event->deschedule();
delete limit_event;
limit_event->squash();
warn_once("be nice to actually delete the event here");
}
return se_event;

View File

@@ -154,12 +154,10 @@ class _StatEvent : public Event
Tick repeat;
public:
_StatEvent(bool _dump, bool _reset, Tick _when, Tick _repeat)
: Event(&mainEventQueue, Stat_Event_Pri), dump(_dump), reset(_reset),
repeat(_repeat)
_StatEvent(bool _dump, bool _reset, Tick _repeat)
: Event(Stat_Event_Pri), dump(_dump), reset(_reset), repeat(_repeat)
{
setFlags(AutoDelete);
schedule(_when);
}
virtual void
@@ -171,15 +169,18 @@ class _StatEvent : public Event
if (reset)
Stats::reset();
if (repeat)
new _StatEvent(dump, reset, curTick + repeat, repeat);
if (repeat) {
Event *event = new _StatEvent(dump, reset, repeat);
mainEventQueue.schedule(event, curTick + repeat);
}
}
};
void
StatEvent(bool dump, bool reset, Tick when, Tick repeat)
{
new _StatEvent(dump, reset, when, repeat);
Event *event = new _StatEvent(dump, reset, repeat);
mainEventQueue.schedule(event, when);
}
/* namespace Stats */ }