summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Reinhardt <stever@eecs.umich.edu>2003-12-11 00:16:46 -0800
committerSteve Reinhardt <stever@eecs.umich.edu>2003-12-11 00:16:46 -0800
commit777c1ebfab0318d4b98834b0f2ef48a2de16b8dd (patch)
tree448b7f195d862ca9398e296d1b18e1cae33f49d5
parent7e6dcd812c18060a76d5a73a97e4aa05bcb0d516 (diff)
downloadgem5-777c1ebfab0318d4b98834b0f2ef48a2de16b8dd.tar.xz
Stats & serialization tweaks & cleanup. Unserializing from
a checkpoint now gives identical results to running from scratch and doing at switchover at the same cycle! - CPUs start at cycle 0 again, not cycle 1. - curTick is now serialized & unserialized. - Stats get reset in main (before event loop). Since this is done after curTick is unserialized, simTicks gets set correctly for running from a checkpoint. - Simplify serialization to happen in a single pass. - s/Serializeable/Serializable/ arch/alpha/isa_traits.hh: dev/etherlink.hh: sim/eventq.cc: sim/eventq.hh: s/Serializeable/Serializable/ kern/tru64/tru64_system.cc: sim/process.cc: Make initial CPU activation on cycle 0 again (not 1). sim/main.cc: Reset stats before getting started. Make error message on falling out of event loop more meaningful. sim/serialize.cc: sim/serialize.hh: Get rid of now-useless initial pass; serialization is done in a single pass now. Serialize & unserialize curTick. Wrap curTick and mainEventQueue in a "globals" Serializable object. s/Serializeable/Serializable/ sim/sim_object.cc: Add static function to serialize all SimObjects. sim/sim_object.hh: Add static function to serialize all SimObjects. s/Serializeable/Serializable/ --HG-- extra : convert_revision : 9dcc411d0009b54b8eb61c3a509680b81b9f6f68
-rw-r--r--arch/alpha/isa_traits.hh2
-rw-r--r--dev/etherlink.hh2
-rw-r--r--kern/tru64/tru64_system.cc4
-rw-r--r--sim/eventq.cc2
-rw-r--r--sim/eventq.hh4
-rw-r--r--sim/main.cc5
-rw-r--r--sim/process.cc6
-rw-r--r--sim/serialize.cc153
-rw-r--r--sim/serialize.hh95
-rw-r--r--sim/sim_object.cc16
-rw-r--r--sim/sim_object.hh5
11 files changed, 127 insertions, 167 deletions
diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh
index 406ffb6f3..ecca91d43 100644
--- a/arch/alpha/isa_traits.hh
+++ b/arch/alpha/isa_traits.hh
@@ -225,7 +225,7 @@ class AlphaISA
int regnum);
#if 0
- static void serializeSpecialRegs(const Serializeable::Proxy &proxy,
+ static void serializeSpecialRegs(const Serializable::Proxy &proxy,
const RegFile &regs);
static void unserializeSpecialRegs(const IniFile *db,
diff --git a/dev/etherlink.hh b/dev/etherlink.hh
index ea7bdcbcc..ef587faf7 100644
--- a/dev/etherlink.hh
+++ b/dev/etherlink.hh
@@ -52,7 +52,7 @@ class EtherLink : public SimObject
/*
* Model for a single uni-directional link
*/
- class Link : public Serializeable {
+ class Link : public Serializable {
protected:
std::string objName;
diff --git a/kern/tru64/tru64_system.cc b/kern/tru64/tru64_system.cc
index 6fe5fb81b..99d99afd4 100644
--- a/kern/tru64/tru64_system.cc
+++ b/kern/tru64/tru64_system.cc
@@ -566,7 +566,9 @@ Tru64System::registerExecContext(ExecContext *xc)
int xcIndex = System::registerExecContext(xc);
if (xcIndex == 0) {
- xc->activate();
+ // activate with zero delay so that we start ticking right
+ // away on cycle 0
+ xc->activate(0);
}
RemoteGDB *rgdb = new RemoteGDB(this, xc);
diff --git a/sim/eventq.cc b/sim/eventq.cc
index 52f7dfaff..a0aac4fee 100644
--- a/sim/eventq.cc
+++ b/sim/eventq.cc
@@ -184,7 +184,7 @@ EventQueue::unserialize(Checkpoint *cp, const std::string &section)
paramIn(cp, section, csprintf("event%d", i), eventName);
// create the event based on its pointer value
- Serializeable::create(cp, eventName);
+ Serializable::create(cp, eventName);
}
}
diff --git a/sim/eventq.hh b/sim/eventq.hh
index 475c4face..dc1b2d9af 100644
--- a/sim/eventq.hh
+++ b/sim/eventq.hh
@@ -53,7 +53,7 @@ class EventQueue; // forward declaration
* event is specified by deriving a subclass and overriding the
* process() member function.
*/
-class Event : public Serializeable, public FastAlloc
+class Event : public Serializable, public FastAlloc
{
friend class EventQueue;
@@ -204,7 +204,7 @@ DelayFunction(Tick when, T *object)
/*
* Queue of events sorted in time order
*/
-class EventQueue : public Serializeable
+class EventQueue : public Serializable
{
protected:
std::string objName;
diff --git a/sim/main.cc b/sim/main.cc
index f697aebce..287b3d6e6 100644
--- a/sim/main.cc
+++ b/sim/main.cc
@@ -389,6 +389,9 @@ main(int argc, char **argv)
// Check to make sure that the stats package is properly initialized
Statistics::check();
+ // Reset to put the stats in a consistent state.
+ Statistics::reset();
+
// Nothing to simulate if we don't have at least one CPU somewhere.
if (BaseCPU::numSimulatedCPUs() == 0) {
cerr << "Fatal: no CPUs to simulate." << endl;
@@ -437,7 +440,7 @@ main(int argc, char **argv)
// simulation to terminate (hit max cycles/insts, signal,
// simulated system halts/exits) generates an exit event, so we
// should never run out of events on the queue.
- exitNow("improperly exited event loop!", 1);
+ exitNow("no events on event loop! All CPUs must be idle.", 1);
return 0;
}
diff --git a/sim/process.cc b/sim/process.cc
index 0d7c3403d..c5eee4527 100644
--- a/sim/process.cc
+++ b/sim/process.cc
@@ -148,8 +148,10 @@ Process::registerExecContext(ExecContext *xc)
// copy process's initial regs struct
xc->regs = *init_regs;
- // mark this context as active
- xc->activate();
+ // mark this context as active.
+ // activate with zero delay so that we start ticking right
+ // away on cycle 0
+ xc->activate(0);
}
// return CPU number to caller and increment available CPU count
diff --git a/sim/serialize.cc b/sim/serialize.cc
index 9738029c2..82d295384 100644
--- a/sim/serialize.cc
+++ b/sim/serialize.cc
@@ -48,25 +48,14 @@
using namespace std;
-Serializer *Serializeable::serializer = NULL;
-
-void
-Serializeable::mark()
-{
- if (!serialized)
- serializer->add_object(this);
-
- serialized = true;
-}
-
void
-Serializeable::nameOut(ostream &os)
+Serializable::nameOut(ostream &os)
{
os << "\n[" << name() << "]\n";
}
void
-Serializeable::nameOut(ostream &os, const string &_name)
+Serializable::nameOut(ostream &os, const string &_name)
{
os << "\n[" << _name << "]\n";
}
@@ -156,7 +145,7 @@ arrayParamIn(Checkpoint *cp, const std::string &section,
void
objParamIn(Checkpoint *cp, const std::string &section,
- const std::string &name, Serializeable * &param)
+ const std::string &name, Serializable * &param)
{
if (!cp->findObj(section, name, param)) {
fatal("Can't unserialize '%s:%s'\n", section, name);
@@ -190,94 +179,70 @@ INSTANTIATE_PARAM_TEMPLATES(bool)
INSTANTIATE_PARAM_TEMPLATES(string)
-#if 0
-// unneeded?
-void
-Serializeable::childOut(const string &name, Serializeable *child)
-{
- child->mark();
- if (child->name() == "")
- panic("child is unnamed");
+/////////////////////////////
- out() << name << "=" << child->name() << "\n";
-}
-#endif
-
-Serializer::Serializer()
-{ }
+/// Container for serializing global variables (not associated with
+/// any serialized object).
+class Globals : public Serializable
+{
+ public:
+ string name() const;
+ void serialize(ostream& os);
+ void unserialize(Checkpoint *cp);
+};
-Serializer::~Serializer()
-{ }
+/// The one and only instance of the Globals class.
+Globals globals;
-ostream &
-Serializer::out() const
+string
+Globals::name() const
{
- if (!output)
- panic("must set output before serializing");
-
- return *output;
+ return "Globals";
}
void
-Serializer::add_object(Serializeable *obj)
+Globals::serialize(ostream& os)
{
- objects.push_back(obj);
+ nameOut(os);
+ SERIALIZE_SCALAR(curTick);
+
+ nameOut(os, "MainEventQueue");
+ mainEventQueue.serialize(os);
}
void
-Serializer::add_objects()
+Globals::unserialize(Checkpoint *cp)
{
- mainEventQueue.mark();
-
- SimObject::SimObjectList::iterator i = SimObject::simObjectList.begin();
- SimObject::SimObjectList::iterator end = SimObject::simObjectList.end();
+ const string &section = name();
+ UNSERIALIZE_SCALAR(curTick);
- while (i != end) {
- (*i)->mark();
- ++i;
- }
+ mainEventQueue.unserialize(cp, "MainEventQueue");
}
void
-Serializer::serialize()
+Serializable::serializeAll()
{
- if (Serializeable::serializer != NULL)
- panic("in process of serializing!");
-
- Serializeable::serializer = this;
-
string dir = CheckpointDir();
if (mkdir(dir.c_str(), 0775) == -1 && errno != EEXIST)
warn("could mkdir %s\n", dir);
string cpt_file = dir + "m5.cpt";
- output = new ofstream(cpt_file.c_str());
+ ofstream outstream(cpt_file.c_str());
time_t t = time(NULL);
- *output << "// checkpoint generated: " << ctime(&t);
-
- serlist_t list;
-
- add_objects();
- while (!objects.empty()) {
- Serializeable *obj = objects.front();
- DPRINTF(Serialize, "Serializing %s\n", obj->name());
- obj->nameOut(out());
- obj->serialize(out());
- objects.pop_front();
- list.push_back(obj);
- }
+ outstream << "// checkpoint generated: " << ctime(&t);
- while (!list.empty()) {
- list.front()->serialized = false;
- list.pop_front();
- }
+ globals.serialize(outstream);
+ SimObject::serializeAll(outstream);
+}
- Serializeable::serializer = NULL;
- delete output;
- output = NULL;
+void
+Serializable::unserializeGlobals(Checkpoint *cp)
+{
+ globals.unserialize(cp);
}
+
class SerializeEvent : public Event
{
protected:
@@ -303,8 +268,7 @@ SerializeEvent::SerializeEvent(Tick _when, Tick _repeat)
void
SerializeEvent::process()
{
- Serializer serial;
- serial.serialize();
+ Serializable::serializeAll();
if (repeat)
schedule(curTick + repeat);
}
@@ -374,8 +338,7 @@ SerializeParamContext::checkParams()
void
debug_serialize()
{
- Serializer serial;
- serial.serialize();
+ Serializable::serializeAll();
}
void
@@ -386,22 +349,22 @@ debug_serialize(Tick when)
////////////////////////////////////////////////////////////////////////
//
-// SerializeableClass member definitions
+// SerializableClass member definitions
//
////////////////////////////////////////////////////////////////////////
-// Map of class names to SerializeableBuilder creation functions.
+// Map of class names to SerializableBuilder creation functions.
// Need to make this a pointer so we can force initialization on the
-// first reference; otherwise, some SerializeableClass constructors
+// first reference; otherwise, some SerializableClass constructors
// may be invoked before the classMap constructor.
-map<string,SerializeableClass::CreateFunc> *SerializeableClass::classMap = 0;
+map<string,SerializableClass::CreateFunc> *SerializableClass::classMap = 0;
-// SerializeableClass constructor: add mapping to classMap
-SerializeableClass::SerializeableClass(const string &className,
+// SerializableClass constructor: add mapping to classMap
+SerializableClass::SerializableClass(const string &className,
CreateFunc createFunc)
{
if (classMap == NULL)
- classMap = new map<string,SerializeableClass::CreateFunc>();
+ classMap = new map<string,SerializableClass::CreateFunc>();
if ((*classMap)[className])
{
@@ -417,25 +380,25 @@ SerializeableClass::SerializeableClass(const string &className,
//
//
-Serializeable *
-SerializeableClass::createObject(Checkpoint *cp,
+Serializable *
+SerializableClass::createObject(Checkpoint *cp,
const std::string &section)
{
string className;
if (!cp->find(section, "type", className)) {
- fatal("Serializeable::create: no 'type' entry in section '%s'.\n",
+ fatal("Serializable::create: no 'type' entry in section '%s'.\n",
section);
}
CreateFunc createFunc = (*classMap)[className];
if (createFunc == NULL) {
- fatal("Serializeable::create: no create function for class '%s'.\n",
+ fatal("Serializable::create: no create function for class '%s'.\n",
className);
}
- Serializeable *object = createFunc(cp, section);
+ Serializable *object = createFunc(cp, section);
assert(object != NULL);
@@ -443,10 +406,10 @@ SerializeableClass::createObject(Checkpoint *cp,
}
-Serializeable *
-Serializeable::create(Checkpoint *cp, const std::string &section)
+Serializable *
+Serializable::create(Checkpoint *cp, const std::string &section)
{
- Serializeable *object = SerializeableClass::createObject(cp, section);
+ Serializable *object = SerializableClass::createObject(cp, section);
object->unserialize(cp, section);
return object;
}
@@ -459,8 +422,6 @@ Checkpoint::Checkpoint(const std::string &filename, const std::string &path,
if (!db->load(filename)) {
fatal("Can't load checkpoint file '%s'\n", filename);
}
-
- mainEventQueue.unserialize(this, "MainEventQueue");
}
@@ -474,7 +435,7 @@ Checkpoint::find(const std::string &section, const std::string &entry,
bool
Checkpoint::findObj(const std::string &section, const std::string &entry,
- Serializeable *&value)
+ Serializable *&value)
{
string path;
diff --git a/sim/serialize.hh b/sim/serialize.hh
index 077931d8c..60e06f94b 100644
--- a/sim/serialize.hh
+++ b/sim/serialize.hh
@@ -41,7 +41,7 @@
#include "sim/host.hh"
#include "sim/configfile.hh"
-class Serializeable;
+class Serializable;
class Checkpoint;
template <class T>
@@ -61,7 +61,7 @@ void arrayParamIn(Checkpoint *cp, const std::string &section,
void
objParamIn(Checkpoint *cp, const std::string &section,
- const std::string &name, Serializeable * &param);
+ const std::string &name, Serializable * &param);
//
@@ -92,7 +92,7 @@ objParamIn(Checkpoint *cp, const std::string &section,
#define UNSERIALIZE_OBJPTR(objptr) \
do { \
- Serializeable *sptr; \
+ Serializable *sptr; \
objParamIn(cp, section, #objptr, sptr); \
objptr = dynamic_cast<typeof(objptr)>(sptr); \
} while (0)
@@ -100,23 +100,15 @@ objParamIn(Checkpoint *cp, const std::string &section,
/*
* Basic support for object serialization.
*/
-class Serializeable
+class Serializable
{
- public:
-
- friend class Serializer;
-
protected:
- bool serialized;
- static Serializer *serializer;
-
- void mark();
void nameOut(std::ostream& os);
void nameOut(std::ostream& os, const std::string &_name);
public:
- Serializeable() : serialized(false) {}
- virtual ~Serializeable() {}
+ Serializable() {}
+ virtual ~Serializable() {}
// manditory virtual function, so objects must provide names
virtual std::string name() const = 0;
@@ -124,70 +116,51 @@ class Serializeable
virtual void serialize(std::ostream& os) {}
virtual void unserialize(Checkpoint *cp, const std::string &section) {}
- static Serializeable *create(Checkpoint *cp,
+ static Serializable *create(Checkpoint *cp,
const std::string &section);
-};
-
-class Serializer
-{
- friend class Serializeable;
- protected:
- typedef std::list<Serializeable *> serlist_t;
- serlist_t objects;
- std::ostream *output;
- std::ostream &out() const;
-
- public:
- Serializer();
- virtual ~Serializer();
-
- private:
- void add_object(Serializeable *obj);
- void add_objects();
-
- public:
- void serialize();
+ static void serializeAll();
+ static void unserializeGlobals(Checkpoint *cp);
};
//
-// A SerializeableBuilder serves as an evaluation context for a set of
-// parameters that describe a specific instance of a Serializeable. This
+// A SerializableBuilder serves as an evaluation context for a set of
+// parameters that describe a specific instance of a Serializable. This
// evaluation context corresponds to a section in the .ini file (as
// with the base ParamContext) plus an optional node in the
// configuration hierarchy (the configNode member) for resolving
-// Serializeable references. SerializeableBuilder is an abstract superclass;
+// Serializable references. SerializableBuilder is an abstract superclass;
// derived classes specialize the class for particular subclasses of
-// Serializeable (e.g., BaseCache).
+// Serializable (e.g., BaseCache).
//
// For typical usage, see the definition of
-// SerializeableClass::createObject().
+// SerializableClass::createObject().
//
-class SerializeableBuilder
+class SerializableBuilder
{
public:
- SerializeableBuilder() {}
+ SerializableBuilder() {}
- virtual ~SerializeableBuilder() {}
+ virtual ~SerializableBuilder() {}
- // Create the actual Serializeable corresponding to the parameter
+ // Create the actual Serializable corresponding to the parameter
// values in this context. This function is overridden in derived
// classes to call a specific constructor for a particular
- // subclass of Serializeable.
- virtual Serializeable *create() = 0;
+ // subclass of Serializable.
+ virtual Serializable *create() = 0;
};
//
-// An instance of SerializeableClass corresponds to a class derived from
-// Serializeable. The SerializeableClass instance serves to bind the string
+// An instance of SerializableClass corresponds to a class derived from
+// Serializable. The SerializableClass instance serves to bind the string
// name (found in the config file) to a function that creates an
// instance of the appropriate derived class.
//
// This would be much cleaner in Smalltalk or Objective-C, where types
// are first-class objects themselves.
//
-class SerializeableClass
+class SerializableClass
{
public:
@@ -196,32 +169,32 @@ class SerializeableClass
// section (specified by the first string argument), a unique name
// for the object (specified by the second string argument), and
// an optional config hierarchy node (specified by the third
- // argument). A pointer to the new SerializeableBuilder is returned.
- typedef Serializeable *(*CreateFunc)(Checkpoint *cp,
+ // argument). A pointer to the new SerializableBuilder is returned.
+ typedef Serializable *(*CreateFunc)(Checkpoint *cp,
const std::string &section);
static std::map<std::string,CreateFunc> *classMap;
// Constructor. For example:
//
- // SerializeableClass baseCacheSerializeableClass("BaseCacheSerializeable",
- // newBaseCacheSerializeableBuilder);
+ // SerializableClass baseCacheSerializableClass("BaseCacheSerializable",
+ // newBaseCacheSerializableBuilder);
//
- SerializeableClass(const std::string &className, CreateFunc createFunc);
+ SerializableClass(const std::string &className, CreateFunc createFunc);
- // create Serializeable given name of class and pointer to
+ // create Serializable given name of class and pointer to
// configuration hierarchy node
- static Serializeable *createObject(Checkpoint *cp,
+ static Serializable *createObject(Checkpoint *cp,
const std::string &section);
};
//
// Macros to encapsulate the magic of declaring & defining
-// SerializeableBuilder and SerializeableClass objects
+// SerializableBuilder and SerializableClass objects
//
#define REGISTER_SERIALIZEABLE(CLASS_NAME, OBJ_CLASS) \
-SerializeableClass the##OBJ_CLASS##Class(CLASS_NAME, \
+SerializableClass the##OBJ_CLASS##Class(CLASS_NAME, \
OBJ_CLASS::createForUnserialize);
class Checkpoint
@@ -231,7 +204,7 @@ class Checkpoint
IniFile *db;
const std::string basePath;
const ConfigNode *configNode;
- std::map<std::string, Serializeable*> objMap;
+ std::map<std::string, Serializable*> objMap;
public:
Checkpoint(const std::string &filename, const std::string &path,
@@ -241,7 +214,7 @@ class Checkpoint
std::string &value);
bool findObj(const std::string &section, const std::string &entry,
- Serializeable *&value);
+ Serializable *&value);
bool sectionExists(const std::string &section);
};
diff --git a/sim/sim_object.cc b/sim/sim_object.cc
index 90ad78648..364dbe035 100644
--- a/sim/sim_object.cc
+++ b/sim/sim_object.cc
@@ -155,3 +155,19 @@ SimObject::printAllExtraOutput(ostream &os)
obj->printExtraOutput(os);
}
}
+
+//
+// static function: serialize all SimObjects.
+//
+void
+SimObject::serializeAll(ostream &os)
+{
+ SimObjectList::iterator i = simObjectList.begin();
+ SimObjectList::iterator end = simObjectList.end();
+
+ for (; i != end; ++i) {
+ SimObject *obj = *i;
+ obj->nameOut(os);
+ obj->serialize(os);
+ }
+}
diff --git a/sim/sim_object.hh b/sim/sim_object.hh
index 6b26a1cb0..937ff9427 100644
--- a/sim/sim_object.hh
+++ b/sim/sim_object.hh
@@ -45,7 +45,7 @@
* correspond to physical components and can be specified via the
* config file (CPUs, caches, etc.).
*/
-class SimObject : public Serializeable
+class SimObject : public Serializable
{
protected:
std::string objName;
@@ -82,6 +82,9 @@ class SimObject : public Serializeable
// static: call printExtraOutput on all SimObjects
static void printAllExtraOutput(std::ostream&);
+
+ // static: call nameOut() & serialize() on all SimObjects
+ static void serializeAll(std::ostream &);
};
#endif // __SIM_OBJECT_HH__