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:
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 *
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -39,8 +39,14 @@ struct PyObject;
|
||||
#include <string>
|
||||
|
||||
struct EventQueue;
|
||||
|
||||
struct SimObjectParams
|
||||
{
|
||||
SimObjectParams()
|
||||
{
|
||||
extern EventQueue mainEventQueue;
|
||||
eventq = &mainEventQueue;
|
||||
}
|
||||
virtual ~SimObjectParams() {}
|
||||
|
||||
std::string name;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */ }
|
||||
|
||||
Reference in New Issue
Block a user