summaryrefslogtreecommitdiff
path: root/src/sim
diff options
context:
space:
mode:
Diffstat (limited to 'src/sim')
-rw-r--r--src/sim/main.cc42
-rw-r--r--src/sim/pseudo_inst.cc6
-rw-r--r--src/sim/serialize.cc117
-rw-r--r--src/sim/serialize.hh7
-rw-r--r--src/sim/sim_events.cc8
-rw-r--r--src/sim/sim_events.hh21
-rw-r--r--src/sim/sim_object.cc64
-rw-r--r--src/sim/sim_object.hh29
8 files changed, 178 insertions, 116 deletions
diff --git a/src/sim/main.cc b/src/sim/main.cc
index bf844da7f..3eb7fa95d 100644
--- a/src/sim/main.cc
+++ b/src/sim/main.cc
@@ -62,6 +62,7 @@
#include "sim/async.hh"
#include "sim/builder.hh"
#include "sim/host.hh"
+#include "sim/serialize.hh"
#include "sim/sim_events.hh"
#include "sim/sim_exit.hh"
#include "sim/sim_object.hh"
@@ -521,6 +522,37 @@ simulate(Tick num_cycles = -1)
// not reached... only exit is return on SimLoopExitEvent
}
+Event *
+createCountedQuiesce()
+{
+ return new CountedQuiesceEvent();
+}
+
+void
+cleanupCountedQuiesce(Event *counted_quiesce)
+{
+ CountedQuiesceEvent *event =
+ dynamic_cast<CountedQuiesceEvent *>(counted_quiesce);
+ if (event == NULL) {
+ fatal("Called cleanupCountedQuiesce() on an event that was not "
+ "a CountedQuiesceEvent.");
+ }
+ assert(event->getCount() == 0);
+ delete event;
+}
+
+void
+serializeAll()
+{
+ Serializable::serializeAll();
+}
+
+void
+unserializeAll()
+{
+ Serializable::unserializeAll();
+}
+
/**
* Queue of C++ callbacks to invoke on simulator exit.
*/
@@ -535,6 +567,16 @@ registerExitCallback(Callback *callback)
exitCallbacks.add(callback);
}
+BaseCPU *
+convertToBaseCPUPtr(SimObject *obj)
+{
+ BaseCPU *ptr = dynamic_cast<BaseCPU *>(obj);
+
+ if (ptr == NULL)
+ warn("Casting to BaseCPU pointer failed");
+ return ptr;
+}
+
/**
* Do C++ simulator exit processing. Exported to SWIG to be invoked
* when simulator terminates via Python's atexit mechanism.
diff --git a/src/sim/pseudo_inst.cc b/src/sim/pseudo_inst.cc
index ae52cdd41..b2854e491 100644
--- a/src/sim/pseudo_inst.cc
+++ b/src/sim/pseudo_inst.cc
@@ -209,12 +209,6 @@ namespace AlphaPseudo
{
if (!doCheckpointInsts)
return;
-
-
- Tick when = curTick + delay * Clock::Int::ns;
- Tick repeat = period * Clock::Int::ns;
-
- Checkpoint::setup(when, repeat);
}
uint64_t
diff --git a/src/sim/serialize.cc b/src/sim/serialize.cc
index 0e3139116..7450d7b7e 100644
--- a/src/sim/serialize.cc
+++ b/src/sim/serialize.cc
@@ -244,56 +244,41 @@ Serializable::serializeAll()
globals.serialize(outstream);
SimObject::serializeAll(outstream);
-
- assert(Serializable::ckptPrevCount + 1 == Serializable::ckptCount);
- Serializable::ckptPrevCount++;
- if (ckptMaxCount && ++ckptCount >= ckptMaxCount)
- exitSimLoop(curTick + 1, "Maximum number of checkpoints dropped");
-
}
-
void
-Serializable::unserializeGlobals(Checkpoint *cp)
-{
- globals.unserialize(cp);
-}
-
-
-class SerializeEvent : public Event
+Serializable::unserializeAll()
{
- protected:
- Tick repeat;
-
- public:
- SerializeEvent(Tick _when, Tick _repeat);
- virtual void process();
- virtual void serialize(std::ostream &os)
- {
- panic("Cannot serialize the SerializeEvent");
- }
+ string dir = Checkpoint::dir();
+ string cpt_file = dir + Checkpoint::baseFilename;
+ string section = "";
-};
+ DPRINTFR(Config, "Loading checkpoint dir '%s'\n",
+ dir);
+ Checkpoint *cp = new Checkpoint(dir, section);
+ unserializeGlobals(cp);
-SerializeEvent::SerializeEvent(Tick _when, Tick _repeat)
- : Event(&mainEventQueue, Serialize_Pri), repeat(_repeat)
-{
- setFlags(AutoDelete);
- schedule(_when);
+ SimObject::unserializeAll(cp);
}
void
-SerializeEvent::process()
+Serializable::unserializeGlobals(Checkpoint *cp)
{
- Serializable::serializeAll();
- if (repeat)
- schedule(curTick + repeat);
+ globals.unserialize(cp);
}
const char *Checkpoint::baseFilename = "m5.cpt";
static string checkpointDirBase;
+void
+setCheckpointDir(const std::string &name)
+{
+ checkpointDirBase = name;
+ if (checkpointDirBase[checkpointDirBase.size() - 1] != '/')
+ checkpointDirBase += "/";
+}
+
string
Checkpoint::dir()
{
@@ -304,75 +289,11 @@ Checkpoint::dir()
}
void
-Checkpoint::setup(Tick when, Tick period)
-{
- new SerializeEvent(when, period);
-}
-
-class SerializeParamContext : public ParamContext
-{
- private:
- SerializeEvent *event;
-
- public:
- SerializeParamContext(const string &section);
- ~SerializeParamContext();
- void checkParams();
-};
-
-SerializeParamContext serialParams("serialize");
-
-Param<string> serialize_dir(&serialParams, "dir",
- "dir to stick checkpoint in "
- "(sprintf format with cycle #)");
-
-Param<Counter> serialize_cycle(&serialParams,
- "cycle",
- "cycle to serialize",
- 0);
-
-Param<Counter> serialize_period(&serialParams,
- "period",
- "period to repeat serializations",
- 0);
-
-Param<int> serialize_count(&serialParams, "count",
- "maximum number of checkpoints to drop");
-
-SerializeParamContext::SerializeParamContext(const string &section)
- : ParamContext(section), event(NULL)
-{ }
-
-SerializeParamContext::~SerializeParamContext()
-{
-}
-
-void
-SerializeParamContext::checkParams()
-{
- checkpointDirBase = simout.resolve(serialize_dir);
-
- // guarantee that directory ends with a '/'
- if (checkpointDirBase[checkpointDirBase.size() - 1] != '/')
- checkpointDirBase += "/";
-
- if (serialize_cycle > 0)
- Checkpoint::setup(serialize_cycle, serialize_period);
-
- Serializable::ckptMaxCount = serialize_count;
-}
-
-void
debug_serialize()
{
Serializable::serializeAll();
}
-void
-debug_serialize(Tick when)
-{
- new SerializeEvent(when, 0);
-}
////////////////////////////////////////////////////////////////////////
//
diff --git a/src/sim/serialize.hh b/src/sim/serialize.hh
index 64ed6142f..a80dc99e4 100644
--- a/src/sim/serialize.hh
+++ b/src/sim/serialize.hh
@@ -127,6 +127,7 @@ class Serializable
static int ckptMaxCount;
static int ckptPrevCount;
static void serializeAll();
+ static void unserializeAll();
static void unserializeGlobals(Checkpoint *cp);
};
@@ -204,6 +205,9 @@ class SerializableClass
SerializableClass the##OBJ_CLASS##Class(CLASS_NAME, \
OBJ_CLASS::createForUnserialize);
+void
+setCheckpointName(const std::string &name);
+
class Checkpoint
{
private:
@@ -237,9 +241,6 @@ class Checkpoint
// Filename for base checkpoint file within directory.
static const char *baseFilename;
-
- // Set up a checkpoint creation event or series of events.
- static void setup(Tick when, Tick period = 0);
};
#endif // __SERIALIZE_HH__
diff --git a/src/sim/sim_events.cc b/src/sim/sim_events.cc
index b7901832d..97f7ae03c 100644
--- a/src/sim/sim_events.cc
+++ b/src/sim/sim_events.cc
@@ -78,6 +78,14 @@ exitSimLoop(const std::string &message, int exit_code)
exitSimLoop(curTick, message, exit_code);
}
+void
+CountedQuiesceEvent::process()
+{
+ if (--count == 0) {
+ exitSimLoop("Finished quiesce");
+ }
+}
+
//
// constructor: automatically schedules at specified time
//
diff --git a/src/sim/sim_events.hh b/src/sim/sim_events.hh
index 4f305ad38..50368f258 100644
--- a/src/sim/sim_events.hh
+++ b/src/sim/sim_events.hh
@@ -44,6 +44,11 @@ class SimLoopExitEvent : public Event
int code;
public:
+ // Default constructor. Only really used for derived classes.
+ SimLoopExitEvent()
+ : Event(&mainEventQueue, Sim_Exit_Pri)
+ { }
+
SimLoopExitEvent(Tick _when, const std::string &_cause, int c = 0)
: Event(&mainEventQueue, Sim_Exit_Pri), cause(_cause),
code(c)
@@ -62,6 +67,22 @@ class SimLoopExitEvent : public Event
virtual const char *description();
};
+class CountedQuiesceEvent : public SimLoopExitEvent
+{
+ private:
+ // Count down to quiescing
+ int count;
+ public:
+ CountedQuiesceEvent()
+ : count(0)
+ { }
+ void process();
+
+ void setCount(int _count) { count = _count; }
+
+ int getCount() { return count; }
+};
+
//
// Event class to terminate simulation after 'n' related events have
// occurred using a shared counter: used to terminate when *all*
diff --git a/src/sim/sim_object.cc b/src/sim/sim_object.cc
index a35c7a88d..551555b25 100644
--- a/src/sim/sim_object.cc
+++ b/src/sim/sim_object.cc
@@ -73,6 +73,7 @@ SimObject::SimObject(Params *p)
doRecordEvent = !Stats::event_ignore.match(name());
simObjectList.push_back(this);
+ state = Atomic;
}
//
@@ -88,6 +89,7 @@ SimObject::SimObject(const string &_name)
doRecordEvent = !Stats::event_ignore.match(name());
simObjectList.push_back(this);
+ state = Atomic;
}
void
@@ -219,6 +221,24 @@ SimObject::serializeAll(ostream &os)
}
}
+void
+SimObject::unserializeAll(Checkpoint *cp)
+{
+ SimObjectList::reverse_iterator ri = simObjectList.rbegin();
+ SimObjectList::reverse_iterator rend = simObjectList.rend();
+
+ for (; ri != rend; ++ri) {
+ SimObject *obj = *ri;
+ DPRINTFR(Config, "Unserializing '%s'\n",
+ obj->name());
+ if(cp->sectionExists(obj->name()))
+ obj->unserialize(cp, obj->name());
+ else
+ warn("Not unserializing '%s': no section found in checkpoint.\n",
+ obj->name());
+ }
+}
+
#ifdef DEBUG
//
// static function: flag which objects should have the debugger break
@@ -250,10 +270,50 @@ SimObject::recordEvent(const std::string &stat)
Stats::recordEvent(stat);
}
+bool
+SimObject::quiesce(Event *quiesce_event)
+{
+ if (state != QuiescedAtomic && state != Atomic) {
+ panic("Must implement your own quiesce function if it is to be used "
+ "in timing mode!");
+ }
+ state = QuiescedAtomic;
+ return false;
+}
+
+void
+SimObject::resume()
+{
+ if (state == QuiescedAtomic) {
+ state = Atomic;
+ } else if (state == QuiescedTiming) {
+ state = Timing;
+ }
+}
+
+void
+SimObject::setMemoryMode(State new_mode)
+{
+ assert(new_mode == Timing || new_mode == Atomic);
+ if (state == QuiescedAtomic && new_mode == Timing) {
+ state = QuiescedTiming;
+ } else if (state == QuiescedTiming && new_mode == Atomic) {
+ state = QuiescedAtomic;
+ } else {
+ state = new_mode;
+ }
+}
+
+void
+SimObject::switchOut()
+{
+ panic("Unimplemented!");
+}
+
void
-SimObject::drain(Serializer *serializer)
+SimObject::takeOverFrom(BaseCPU *cpu)
{
- serializer->signalDrained();
+ panic("Unimplemented!");
}
DEFINE_SIM_OBJECT_CLASS_NAME("SimObject", SimObject)
diff --git a/src/sim/sim_object.hh b/src/sim/sim_object.hh
index 84e9376a0..e0b21782f 100644
--- a/src/sim/sim_object.hh
+++ b/src/sim/sim_object.hh
@@ -44,7 +44,8 @@
#include "sim/serialize.hh"
#include "sim/startup.hh"
-class Serializer;
+class BaseCPU;
+class Event;
/*
* Abstract superclass for simulation objects. Represents things that
@@ -58,15 +59,26 @@ class SimObject : public Serializable, protected StartupCallback
std::string name;
};
+ enum State {
+ Atomic,
+ Timing,
+ Quiescing,
+ QuiescedAtomic,
+ QuiescedTiming
+ };
+
protected:
Params *_params;
+ State state;
+
+ void changeState(State new_state) { state = new_state; }
public:
const Params *params() const { return _params; }
- private:
- friend class Serializer;
+ State getState() { return state; }
+ private:
typedef std::vector<SimObject *> SimObjectList;
// list of all instantiated simulation objects
@@ -100,13 +112,16 @@ class SimObject : public Serializable, protected StartupCallback
// static: call nameOut() & serialize() on all SimObjects
static void serializeAll(std::ostream &);
+ static void unserializeAll(Checkpoint *cp);
// Methods to drain objects in order to take checkpoints
// Or switch from timing -> atomic memory model
- virtual void drain(Serializer *serializer);
- virtual void resume() { return;} ;
- virtual void serializationComplete()
- { assert(0 && "Unimplemented"); };
+ // Quiesce returns true if the SimObject cannot quiesce immediately.
+ virtual bool quiesce(Event *quiesce_event);
+ virtual void resume();
+ virtual void setMemoryMode(State new_mode);
+ virtual void switchOut();
+ virtual void takeOverFrom(BaseCPU *cpu);
#ifdef DEBUG
public: