Replace curTick global variable with accessor functions.
This step makes it easy to replace the accessor functions (which still access a global variable) with ones that access per-thread curTick values.
This commit is contained in:
@@ -38,10 +38,10 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
Tick curTick = 0;
|
||||
Tick _curTick = 0;
|
||||
|
||||
namespace SimClock {
|
||||
/// The simulated frequency of curTick. (In ticks per second)
|
||||
/// The simulated frequency of curTick(). (In ticks per second)
|
||||
Tick Frequency;
|
||||
|
||||
namespace Float {
|
||||
|
||||
@@ -37,11 +37,15 @@
|
||||
#include "base/types.hh"
|
||||
|
||||
/// The universal simulation clock.
|
||||
extern Tick curTick;
|
||||
extern Tick _curTick;
|
||||
|
||||
inline Tick curTick() { return _curTick; }
|
||||
inline void curTick(Tick newVal) { _curTick = newVal; }
|
||||
|
||||
const Tick retryTime = 1000;
|
||||
|
||||
namespace SimClock {
|
||||
/// The simulated frequency of curTick.
|
||||
/// The simulated frequency of curTick().
|
||||
extern Tick Frequency;
|
||||
|
||||
namespace Float {
|
||||
|
||||
@@ -309,7 +309,7 @@ void
|
||||
EventQueue::dump() const
|
||||
{
|
||||
cprintf("============================================================\n");
|
||||
cprintf("EventQueue Dump (cycle %d)\n", curTick);
|
||||
cprintf("EventQueue Dump (cycle %d)\n", curTick());
|
||||
cprintf("------------------------------------------------------------\n");
|
||||
|
||||
if (empty())
|
||||
|
||||
@@ -136,7 +136,7 @@ class Event : public Serializable, public FastAlloc
|
||||
queue = q;
|
||||
#endif
|
||||
#ifdef EVENTQ_DEBUG
|
||||
whenScheduled = curTick;
|
||||
whenScheduled = curTick();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -254,7 +254,7 @@ class Event : public Serializable, public FastAlloc
|
||||
queue = NULL;
|
||||
#endif
|
||||
#ifdef EVENTQ_DEBUG
|
||||
whenCreated = curTick;
|
||||
whenCreated = curTick();
|
||||
whenScheduled = 0;
|
||||
#endif
|
||||
}
|
||||
@@ -405,15 +405,15 @@ class EventQueue : public Serializable
|
||||
}
|
||||
}
|
||||
|
||||
// default: process all events up to 'now' (curTick)
|
||||
void serviceEvents() { serviceEvents(curTick); }
|
||||
// default: process all events up to 'now' (curTick())
|
||||
void serviceEvents() { serviceEvents(curTick()); }
|
||||
|
||||
// return true if no events are queued
|
||||
bool empty() const { return head == NULL; }
|
||||
|
||||
void dump() const;
|
||||
|
||||
Tick nextEventTime() { return empty() ? curTick : head->when(); }
|
||||
Tick nextEventTime() { return empty() ? curTick() : head->when(); }
|
||||
|
||||
bool debugVerify() const;
|
||||
|
||||
@@ -486,7 +486,7 @@ class EventManager
|
||||
inline void
|
||||
EventQueue::schedule(Event *event, Tick when)
|
||||
{
|
||||
assert((UTick)when >= (UTick)curTick);
|
||||
assert((UTick)when >= (UTick)curTick());
|
||||
assert(!event->scheduled());
|
||||
assert(event->initialized());
|
||||
|
||||
@@ -523,7 +523,7 @@ EventQueue::deschedule(Event *event)
|
||||
inline void
|
||||
EventQueue::reschedule(Event *event, Tick when, bool always)
|
||||
{
|
||||
assert(when >= curTick);
|
||||
assert(when >= curTick());
|
||||
assert(always || event->scheduled());
|
||||
assert(event->initialized());
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ exitNowHandler(int sigtype)
|
||||
void
|
||||
abortHandler(int sigtype)
|
||||
{
|
||||
ccprintf(cerr, "Program aborted at cycle %d\n", curTick);
|
||||
ccprintf(cerr, "Program aborted at cycle %d\n", curTick());
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -95,7 +95,7 @@ quiesceNs(ThreadContext *tc, uint64_t ns)
|
||||
|
||||
EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
|
||||
|
||||
Tick resume = curTick + SimClock::Int::ns * ns;
|
||||
Tick resume = curTick() + SimClock::Int::ns * ns;
|
||||
|
||||
cpu->reschedule(quiesceEvent, resume, true);
|
||||
|
||||
@@ -117,7 +117,7 @@ quiesceCycles(ThreadContext *tc, uint64_t cycles)
|
||||
|
||||
EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
|
||||
|
||||
Tick resume = curTick + cpu->ticks(cycles);
|
||||
Tick resume = curTick() + cpu->ticks(cycles);
|
||||
|
||||
cpu->reschedule(quiesceEvent, resume, true);
|
||||
|
||||
@@ -141,7 +141,7 @@ quiesceTime(ThreadContext *tc)
|
||||
uint64_t
|
||||
rpns(ThreadContext *tc)
|
||||
{
|
||||
return curTick / SimClock::Int::ns;
|
||||
return curTick() / SimClock::Int::ns;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -156,7 +156,7 @@ wakeCPU(ThreadContext *tc, uint64_t cpuid)
|
||||
void
|
||||
m5exit(ThreadContext *tc, Tick delay)
|
||||
{
|
||||
Tick when = curTick + delay * SimClock::Int::ns;
|
||||
Tick when = curTick() + delay * SimClock::Int::ns;
|
||||
exitSimLoop("m5_exit instruction encountered", 0, when);
|
||||
}
|
||||
|
||||
@@ -233,7 +233,7 @@ resetstats(ThreadContext *tc, Tick delay, Tick period)
|
||||
return;
|
||||
|
||||
|
||||
Tick when = curTick + delay * SimClock::Int::ns;
|
||||
Tick when = curTick() + delay * SimClock::Int::ns;
|
||||
Tick repeat = period * SimClock::Int::ns;
|
||||
|
||||
Stats::schedStatEvent(false, true, when, repeat);
|
||||
@@ -246,7 +246,7 @@ dumpstats(ThreadContext *tc, Tick delay, Tick period)
|
||||
return;
|
||||
|
||||
|
||||
Tick when = curTick + delay * SimClock::Int::ns;
|
||||
Tick when = curTick() + delay * SimClock::Int::ns;
|
||||
Tick repeat = period * SimClock::Int::ns;
|
||||
|
||||
Stats::schedStatEvent(true, false, when, repeat);
|
||||
@@ -259,7 +259,7 @@ dumpresetstats(ThreadContext *tc, Tick delay, Tick period)
|
||||
return;
|
||||
|
||||
|
||||
Tick when = curTick + delay * SimClock::Int::ns;
|
||||
Tick when = curTick() + delay * SimClock::Int::ns;
|
||||
Tick repeat = period * SimClock::Int::ns;
|
||||
|
||||
Stats::schedStatEvent(true, true, when, repeat);
|
||||
@@ -271,7 +271,7 @@ m5checkpoint(ThreadContext *tc, Tick delay, Tick period)
|
||||
if (!tc->getCpuPtr()->params()->do_checkpoint_insts)
|
||||
return;
|
||||
|
||||
Tick when = curTick + delay * SimClock::Int::ns;
|
||||
Tick when = curTick() + delay * SimClock::Int::ns;
|
||||
Tick repeat = period * SimClock::Int::ns;
|
||||
|
||||
exitSimLoop("checkpoint", 0, when, repeat);
|
||||
|
||||
@@ -400,7 +400,7 @@ void
|
||||
Globals::serialize(ostream &os)
|
||||
{
|
||||
nameOut(os);
|
||||
SERIALIZE_SCALAR(curTick);
|
||||
SERIALIZE_SCALAR(curTick());
|
||||
|
||||
nameOut(os, "MainEventQueue");
|
||||
mainEventQueue.serialize(os);
|
||||
@@ -410,7 +410,9 @@ void
|
||||
Globals::unserialize(Checkpoint *cp)
|
||||
{
|
||||
const string §ion = name();
|
||||
UNSERIALIZE_SCALAR(curTick);
|
||||
Tick tick;
|
||||
paramIn(cp, section, "curTick", tick);
|
||||
curTick(tick);
|
||||
|
||||
mainEventQueue.unserialize(cp, "MainEventQueue");
|
||||
}
|
||||
@@ -533,10 +535,10 @@ string Checkpoint::currentDirectory;
|
||||
string
|
||||
Checkpoint::setDir(const string &name)
|
||||
{
|
||||
// use csprintf to insert curTick into directory name if it
|
||||
// use csprintf to insert curTick() into directory name if it
|
||||
// appears to have a format placeholder in it.
|
||||
currentDirectory = (name.find("%") != string::npos) ?
|
||||
csprintf(name, curTick) : name;
|
||||
csprintf(name, curTick()) : name;
|
||||
if (currentDirectory[currentDirectory.size() - 1] != '/')
|
||||
currentDirectory += "/";
|
||||
return currentDirectory;
|
||||
|
||||
@@ -250,7 +250,7 @@ class Checkpoint
|
||||
|
||||
public:
|
||||
// Set the current directory. This function takes care of
|
||||
// inserting curTick if there's a '%d' in the argument, and
|
||||
// inserting curTick() if there's a '%d' in the argument, and
|
||||
// appends a '/' if necessary. The final name is returned.
|
||||
static std::string setDir(const std::string &base_name);
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ SimLoopExitEvent::process()
|
||||
// but if you are doing this on intervals, don't forget to make another
|
||||
if (repeat) {
|
||||
assert(getFlags(IsMainQueue));
|
||||
mainEventQueue.schedule(this, curTick + repeat);
|
||||
mainEventQueue.schedule(this, curTick() + repeat);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,10 +47,10 @@ class SimLoopExitEvent;
|
||||
void registerExitCallback(Callback *);
|
||||
|
||||
/// 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
|
||||
/// indicate why the exit occurred.
|
||||
void exitSimLoop(const std::string &message, int exit_code = 0,
|
||||
Tick when = curTick, Tick repeat = 0);
|
||||
Tick when = curTick(), Tick repeat = 0);
|
||||
|
||||
#endif // __SIM_EXIT_HH__
|
||||
|
||||
@@ -131,7 +131,7 @@ class SimObject : public EventManager, public Serializable
|
||||
/**
|
||||
* startup() is the final initialization call before simulation.
|
||||
* All state is initialized (including unserialized state, if any,
|
||||
* such as the curTick value), so this is the appropriate place to
|
||||
* such as the curTick() value), so this is the appropriate place to
|
||||
* schedule initial event(s) for objects that need them.
|
||||
*/
|
||||
virtual void startup();
|
||||
|
||||
@@ -47,14 +47,14 @@
|
||||
SimLoopExitEvent *
|
||||
simulate(Tick num_cycles)
|
||||
{
|
||||
inform("Entering event queue @ %d. Starting simulation...\n", curTick);
|
||||
inform("Entering event queue @ %d. Starting simulation...\n", curTick());
|
||||
|
||||
if (num_cycles < 0)
|
||||
fatal("simulate: num_cycles must be >= 0 (was %d)\n", num_cycles);
|
||||
else if (curTick + num_cycles < 0) //Overflow
|
||||
else if (curTick() + num_cycles < 0) //Overflow
|
||||
num_cycles = MaxTick;
|
||||
else
|
||||
num_cycles = curTick + num_cycles;
|
||||
num_cycles = curTick() + num_cycles;
|
||||
|
||||
Event *limit_event =
|
||||
new SimLoopExitEvent("simulate() limit reached", 0);
|
||||
@@ -64,12 +64,12 @@ simulate(Tick num_cycles)
|
||||
// there should always be at least one event (the SimLoopExitEvent
|
||||
// we just scheduled) in the queue
|
||||
assert(!mainEventQueue.empty());
|
||||
assert(curTick <= mainEventQueue.nextTick() &&
|
||||
assert(curTick() <= mainEventQueue.nextTick() &&
|
||||
"event scheduled in the past");
|
||||
|
||||
// forward current cycle to the time of the first event on the
|
||||
// queue
|
||||
curTick = mainEventQueue.nextTick();
|
||||
curTick(mainEventQueue.nextTick());
|
||||
Event *exit_event = mainEventQueue.serviceOne();
|
||||
if (exit_event != NULL) {
|
||||
// hit some kind of exit event; return to Python
|
||||
|
||||
@@ -66,7 +66,7 @@ struct SimTicksReset : public Callback
|
||||
void process()
|
||||
{
|
||||
statTime.set();
|
||||
startTick = curTick;
|
||||
startTick = curTick();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -81,7 +81,7 @@ statElapsedTime()
|
||||
Tick
|
||||
statElapsedTicks()
|
||||
{
|
||||
return curTick - startTick;
|
||||
return curTick() - startTick;
|
||||
}
|
||||
|
||||
SimTicksReset simTicksReset;
|
||||
@@ -189,7 +189,7 @@ class StatEvent : public Event
|
||||
Stats::reset();
|
||||
|
||||
if (repeat) {
|
||||
Stats::schedStatEvent(dump, reset, curTick + repeat, repeat);
|
||||
Stats::schedStatEvent(dump, reset, curTick() + repeat, repeat);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
namespace Stats {
|
||||
|
||||
void initSimStats();
|
||||
void schedStatEvent(bool dump, bool reset, Tick when = curTick,
|
||||
void schedStatEvent(bool dump, bool reset, Tick when = curTick(),
|
||||
Tick repeat = 0);
|
||||
|
||||
} // namespace Stats
|
||||
|
||||
@@ -59,7 +59,7 @@ SyscallDesc::doSyscall(int callnum, LiveProcess *process, ThreadContext *tc)
|
||||
#endif
|
||||
DPRINTFR(SyscallVerbose,
|
||||
"%d: %s: syscall %s called w/arguments %d,%d,%d,%d\n",
|
||||
curTick, tc->getCpuPtr()->name(), name,
|
||||
curTick(), tc->getCpuPtr()->name(), name,
|
||||
process->getSyscallArg(tc, index),
|
||||
process->getSyscallArg(tc, index),
|
||||
process->getSyscallArg(tc, index),
|
||||
@@ -68,7 +68,7 @@ SyscallDesc::doSyscall(int callnum, LiveProcess *process, ThreadContext *tc)
|
||||
SyscallReturn retval = (*funcPtr)(this, callnum, process, tc);
|
||||
|
||||
DPRINTFR(SyscallVerbose, "%d: %s: syscall %s returns %d\n",
|
||||
curTick,tc->getCpuPtr()->name(), name, retval.value());
|
||||
curTick(),tc->getCpuPtr()->name(), name, retval.value());
|
||||
|
||||
if (!(flags & SyscallDesc::SuppressReturnValue))
|
||||
process->setSyscallReturn(tc, retval);
|
||||
|
||||
@@ -363,7 +363,7 @@ template <class T1, class T2>
|
||||
void
|
||||
getElapsedTime(T1 &sec, T2 &usec)
|
||||
{
|
||||
int elapsed_usecs = curTick / SimClock::Int::us;
|
||||
int elapsed_usecs = curTick() / SimClock::Int::us;
|
||||
sec = elapsed_usecs / one_million;
|
||||
usec = elapsed_usecs % one_million;
|
||||
}
|
||||
@@ -1190,7 +1190,7 @@ timesFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
TypedBufferArg<typename OS::tms> bufp(process->getSyscallArg(tc, index));
|
||||
|
||||
// Fill in the time structure (in clocks)
|
||||
int64_t clocks = curTick * OS::M5_SC_CLK_TCK / SimClock::Int::s;
|
||||
int64_t clocks = curTick() * OS::M5_SC_CLK_TCK / SimClock::Int::s;
|
||||
bufp->tms_utime = clocks;
|
||||
bufp->tms_stime = 0;
|
||||
bufp->tms_cutime = 0;
|
||||
|
||||
Reference in New Issue
Block a user