there are two main thrusts of this changeset.
1) return the periodicity of checkpoints back into the code (i.e. make m5 checkpoint n m meaningful again). 2) to do this, i had to much around with being able to repeatedly schedule and SimLoopExitEvent, which led to changes in how exit simloop events are handled to make this easier. src/arch/alpha/isa/decoder.isa: src/mem/cache/cache_impl.hh: modify arg. order for new calling convention of exitSimLoop. src/cpu/base.cc: src/sim/main.cc: src/sim/pseudo_inst.cc: src/sim/root.cc: now, instead of creating a new SimLoopExitEvent, call a wrapper schedExitSimLoop which handles all the default args. src/sim/sim_events.cc: src/sim/sim_events.hh: src/sim/sim_exit.hh: add the periodicity of checkpointing back into the code. to facilitate this, there are now two wrappers (instead of just overloading exitSimLoop). exitSimLoop is only for exiting NOW (i.e. at curTick), while schedExitSimLoop schedules and exit event for the future. --HG-- extra : convert_revision : c61f4bf05517172edd2c83368fd10bb0f0678029
This commit is contained in:
parent
54cf456fd1
commit
9c901225f8
9 changed files with 50 additions and 26 deletions
|
@ -701,7 +701,7 @@ decode OPCODE default Unknown::unknown() {
|
||||||
0x00: decode PALFUNC {
|
0x00: decode PALFUNC {
|
||||||
format EmulatedCallPal {
|
format EmulatedCallPal {
|
||||||
0x00: halt ({{
|
0x00: halt ({{
|
||||||
exitSimLoop(curTick, "halt instruction encountered");
|
exitSimLoop("halt instruction encountered");
|
||||||
}}, IsNonSpeculative);
|
}}, IsNonSpeculative);
|
||||||
0x83: callsys({{
|
0x83: callsys({{
|
||||||
xc->syscall(R0);
|
xc->syscall(R0);
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "cpu/cpuevent.hh"
|
#include "cpu/cpuevent.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "cpu/profile.hh"
|
#include "cpu/profile.hh"
|
||||||
|
#include "sim/sim_exit.hh"
|
||||||
#include "sim/param.hh"
|
#include "sim/param.hh"
|
||||||
#include "sim/process.hh"
|
#include "sim/process.hh"
|
||||||
#include "sim/sim_events.hh"
|
#include "sim/sim_events.hh"
|
||||||
|
@ -125,8 +126,9 @@ BaseCPU::BaseCPU(Params *p)
|
||||||
//
|
//
|
||||||
if (p->max_insts_any_thread != 0)
|
if (p->max_insts_any_thread != 0)
|
||||||
for (int i = 0; i < number_of_threads; ++i)
|
for (int i = 0; i < number_of_threads; ++i)
|
||||||
new SimLoopExitEvent(comInstEventQueue[i], p->max_insts_any_thread,
|
schedExitSimLoop("a thread reached the max instruction count",
|
||||||
"a thread reached the max instruction count");
|
p->max_insts_any_thread, 0,
|
||||||
|
comInstEventQueue[i]);
|
||||||
|
|
||||||
if (p->max_insts_all_threads != 0) {
|
if (p->max_insts_all_threads != 0) {
|
||||||
// allocate & initialize shared downcounter: each event will
|
// allocate & initialize shared downcounter: each event will
|
||||||
|
@ -150,8 +152,9 @@ BaseCPU::BaseCPU(Params *p)
|
||||||
//
|
//
|
||||||
if (p->max_loads_any_thread != 0)
|
if (p->max_loads_any_thread != 0)
|
||||||
for (int i = 0; i < number_of_threads; ++i)
|
for (int i = 0; i < number_of_threads; ++i)
|
||||||
new SimLoopExitEvent(comLoadEventQueue[i], p->max_loads_any_thread,
|
schedExitSimLoop("a thread reached the max load count",
|
||||||
"a thread reached the max load count");
|
p->max_loads_any_thread, 0,
|
||||||
|
comLoadEventQueue[i]);
|
||||||
|
|
||||||
if (p->max_loads_all_threads != 0) {
|
if (p->max_loads_all_threads != 0) {
|
||||||
// allocate & initialize shared downcounter: each event will
|
// allocate & initialize shared downcounter: each event will
|
||||||
|
|
4
src/mem/cache/cache_impl.hh
vendored
4
src/mem/cache/cache_impl.hh
vendored
|
@ -51,7 +51,7 @@
|
||||||
#include "mem/cache/miss/mshr.hh"
|
#include "mem/cache/miss/mshr.hh"
|
||||||
#include "mem/cache/prefetch/prefetcher.hh"
|
#include "mem/cache/prefetch/prefetcher.hh"
|
||||||
|
|
||||||
#include "sim/sim_events.hh" // for SimExitEvent
|
#include "sim/sim_exit.hh" // for SimExitEvent
|
||||||
|
|
||||||
template<class TagStore, class Buffering, class Coherence>
|
template<class TagStore, class Buffering, class Coherence>
|
||||||
bool
|
bool
|
||||||
|
@ -254,7 +254,7 @@ Cache<TagStore,Buffering,Coherence>::access(PacketPtr &pkt)
|
||||||
if (missCount) {
|
if (missCount) {
|
||||||
--missCount;
|
--missCount;
|
||||||
if (missCount == 0)
|
if (missCount == 0)
|
||||||
new SimLoopExitEvent(curTick, "A cache reached the maximum miss count");
|
exitSimLoop("A cache reached the maximum miss count");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
missQueue->handleMiss(pkt, size, curTick + hitLatency);
|
missQueue->handleMiss(pkt, size, curTick + hitLatency);
|
||||||
|
|
|
@ -317,8 +317,8 @@ simulate(Tick num_cycles = -1)
|
||||||
else
|
else
|
||||||
num_cycles = curTick + num_cycles;
|
num_cycles = curTick + num_cycles;
|
||||||
|
|
||||||
Event *limit_event = new SimLoopExitEvent(num_cycles,
|
Event *limit_event = schedExitSimLoop("simulate() limit reached",
|
||||||
"simulate() limit reached");
|
num_cycles);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
// there should always be at least one event (the SimLoopExitEvent
|
// there should always be at least one event (the SimLoopExitEvent
|
||||||
|
|
|
@ -138,14 +138,14 @@ namespace AlphaPseudo
|
||||||
void
|
void
|
||||||
m5exit_old(ThreadContext *tc)
|
m5exit_old(ThreadContext *tc)
|
||||||
{
|
{
|
||||||
exitSimLoop(curTick, "m5_exit_old instruction encountered");
|
exitSimLoop("m5_exit_old instruction encountered");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
m5exit(ThreadContext *tc, Tick delay)
|
m5exit(ThreadContext *tc, Tick delay)
|
||||||
{
|
{
|
||||||
Tick when = curTick + delay * Clock::Int::ns;
|
Tick when = curTick + delay * Clock::Int::ns;
|
||||||
exitSimLoop(when, "m5_exit instruction encountered");
|
schedExitSimLoop("m5_exit instruction encountered", when);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -270,7 +270,11 @@ namespace AlphaPseudo
|
||||||
{
|
{
|
||||||
if (!doCheckpointInsts)
|
if (!doCheckpointInsts)
|
||||||
return;
|
return;
|
||||||
exitSimLoop("checkpoint");
|
|
||||||
|
Tick when = curTick + delay * Clock::Int::ns;
|
||||||
|
Tick repeat = period * Clock::Int::ns;
|
||||||
|
|
||||||
|
schedExitSimLoop("checkpoint", when, repeat);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
|
|
|
@ -100,7 +100,7 @@ void
|
||||||
Root::startup()
|
Root::startup()
|
||||||
{
|
{
|
||||||
if (max_tick != 0)
|
if (max_tick != 0)
|
||||||
exitSimLoop(curTick + max_tick, "reached maximum cycle count");
|
schedExitSimLoop("reached maximum cycle count", curTick + max_tick);
|
||||||
|
|
||||||
if (progress_interval != 0)
|
if (progress_interval != 0)
|
||||||
new ProgressEvent(&mainEventQueue, progress_interval);
|
new ProgressEvent(&mainEventQueue, progress_interval);
|
||||||
|
|
|
@ -57,6 +57,11 @@ SimLoopExitEvent::process()
|
||||||
|
|
||||||
// otherwise do nothing... the IsExitEvent flag takes care of
|
// otherwise do nothing... the IsExitEvent flag takes care of
|
||||||
// exiting the simulation loop and returning this object to Python
|
// exiting the simulation loop and returning this object to Python
|
||||||
|
|
||||||
|
// but if you are doing this on intervals, don't forget to make another
|
||||||
|
if (repeat) {
|
||||||
|
schedule(curTick + repeat);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,16 +71,20 @@ SimLoopExitEvent::description()
|
||||||
return "simulation loop exit";
|
return "simulation loop exit";
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
SimLoopExitEvent *
|
||||||
exitSimLoop(Tick when, const std::string &message, int exit_code)
|
schedExitSimLoop(const std::string &message, Tick when, Tick repeat,
|
||||||
|
EventQueue *q, int exit_code)
|
||||||
{
|
{
|
||||||
new SimLoopExitEvent(when, message, exit_code);
|
if (q == NULL)
|
||||||
|
q = &mainEventQueue;
|
||||||
|
|
||||||
|
return new SimLoopExitEvent(q, when, repeat, message, exit_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
exitSimLoop(const std::string &message, int exit_code)
|
exitSimLoop(const std::string &message, int exit_code)
|
||||||
{
|
{
|
||||||
exitSimLoop(curTick, message, exit_code);
|
schedExitSimLoop(message, curTick, 0, NULL, exit_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -42,6 +42,7 @@ class SimLoopExitEvent : public Event
|
||||||
// string explaining why we're terminating
|
// string explaining why we're terminating
|
||||||
std::string cause;
|
std::string cause;
|
||||||
int code;
|
int code;
|
||||||
|
Tick repeat;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Default constructor. Only really used for derived classes.
|
// Default constructor. Only really used for derived classes.
|
||||||
|
@ -49,15 +50,18 @@ class SimLoopExitEvent : public Event
|
||||||
: Event(&mainEventQueue, Sim_Exit_Pri)
|
: Event(&mainEventQueue, Sim_Exit_Pri)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
SimLoopExitEvent(Tick _when, const std::string &_cause, int c = 0)
|
SimLoopExitEvent(EventQueue *q,
|
||||||
: Event(&mainEventQueue, Sim_Exit_Pri), cause(_cause),
|
Tick _when, Tick _repeat, const std::string &_cause,
|
||||||
code(c)
|
int c = 0)
|
||||||
|
: Event(q, Sim_Exit_Pri), cause(_cause),
|
||||||
|
code(c), repeat(_repeat)
|
||||||
{ setFlags(IsExitEvent); schedule(_when); }
|
{ setFlags(IsExitEvent); schedule(_when); }
|
||||||
|
|
||||||
SimLoopExitEvent(EventQueue *q,
|
// SimLoopExitEvent(EventQueue *q,
|
||||||
Tick _when, const std::string &_cause, int c = 0)
|
// Tick _when, const std::string &_cause,
|
||||||
: Event(q, Sim_Exit_Pri), cause(_cause), code(c)
|
// Tick _repeat = 0, int c = 0)
|
||||||
{ setFlags(IsExitEvent); schedule(_when); }
|
// : Event(q, Sim_Exit_Pri), cause(_cause), code(c), repeat(_repeat)
|
||||||
|
// { setFlags(IsExitEvent); schedule(_when); }
|
||||||
|
|
||||||
std::string getCause() { return cause; }
|
std::string getCause() { return cause; }
|
||||||
int getCode() { return code; }
|
int getCode() { return code; }
|
||||||
|
|
|
@ -38,6 +38,8 @@
|
||||||
|
|
||||||
// forward declaration
|
// forward declaration
|
||||||
class Callback;
|
class Callback;
|
||||||
|
class EventQueue;
|
||||||
|
class SimLoopExitEvent;
|
||||||
|
|
||||||
/// Register a callback to be called when Python exits. Defined in
|
/// Register a callback to be called when Python exits. Defined in
|
||||||
/// sim/main.cc.
|
/// sim/main.cc.
|
||||||
|
@ -47,12 +49,14 @@ void registerExitCallback(Callback *);
|
||||||
/// Python) at the indicated tick. The message and exit_code
|
/// Python) at the indicated tick. The message and exit_code
|
||||||
/// parameters are saved in the SimLoopExitEvent to indicate why the
|
/// parameters are saved in the SimLoopExitEvent to indicate why the
|
||||||
/// exit occurred.
|
/// exit occurred.
|
||||||
void exitSimLoop(Tick when, const std::string &message, int exit_code = 0);
|
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
|
/// Schedule an event to exit the simulation loop (returning to
|
||||||
/// Python) at the end of the current cycle (curTick). The message
|
/// Python) at the end of the current cycle (curTick). The message
|
||||||
/// and exit_code parameters are saved in the SimLoopExitEvent to
|
/// and exit_code parameters are saved in the SimLoopExitEvent to
|
||||||
/// indicate why the exit occurred.
|
/// indicate why the exit occurred.
|
||||||
void exitSimLoop(const std::string &cause, int exit_code = 0);
|
void exitSimLoop(const std::string &message, int exit_code = 0);
|
||||||
|
|
||||||
#endif // __SIM_EXIT_HH__
|
#endif // __SIM_EXIT_HH__
|
||||||
|
|
Loading…
Reference in a new issue