summaryrefslogtreecommitdiff
path: root/sim
diff options
context:
space:
mode:
Diffstat (limited to 'sim')
-rw-r--r--sim/eventq.cc48
-rw-r--r--sim/eventq.hh11
-rw-r--r--sim/param.cc4
-rw-r--r--sim/serialize.cc108
-rw-r--r--sim/serialize.hh88
5 files changed, 169 insertions, 90 deletions
diff --git a/sim/eventq.cc b/sim/eventq.cc
index 77eb490c7..ef813eb13 100644
--- a/sim/eventq.cc
+++ b/sim/eventq.cc
@@ -129,7 +129,7 @@ Event::serialize(std::ostream &os)
void
-Event::unserialize(const IniFile *db, const string &section)
+Event::unserialize(Checkpoint *cp, const string &section)
{
if (scheduled())
deschedule();
@@ -154,39 +154,51 @@ Event::unserialize(const IniFile *db, const string &section)
void
EventQueue::nameChildren()
{
-#if 0
- int j = 0;
-
+ int numEvents = 0;
Event *event = head;
while (event) {
- stringstream stream;
- ccprintf(stream, "%s.event%d", name(), j++);
- event->setName(stream.str());
-
+ if (event->getFlags(Event::AutoSerialize)) {
+ event->setName(csprintf("%s.event%d", name(), numEvents++));
+ }
event = event->next;
}
-#endif
+
+ numAutoSerializeEvents = numEvents;
}
void
EventQueue::serialize(ostream &os)
{
-#if 0
- string objects = "";
+ // should have been set by a preceding call to nameChildren()
+ assert(numAutoSerializeEvents >= 0);
+ SERIALIZE_SCALAR(numAutoSerializeEvents);
+
+ int numEvents = 0;
Event *event = head;
while (event) {
- objects += event->name();
- objects += " ";
- event->serialize(os);
-
+ if (event->getFlags(Event::AutoSerialize)) {
+ event->nameOut(os);
+ event->serialize(os);
+ numEvents++;
+ }
event = event->next;
}
- nameOut(os, "Serialized");
- SERIALIZE_SCALAR(objects);
-#endif
+
+ assert(numEvents == numAutoSerializeEvents);
+}
+
+
+void
+EventQueue::unserialize(Checkpoint *cp, const std::string &section)
+{
+ UNSERIALIZE_SCALAR(numAutoSerializeEvents);
+ for (int eventNum = 0; eventNum < numAutoSerializeEvents; ++eventNum) {
+ Serializeable::create(cp, csprintf("%s.event%d", section, eventNum));
+ }
}
+
void
EventQueue::dump()
{
diff --git a/sim/eventq.hh b/sim/eventq.hh
index a8eae1248..11bfe3a4e 100644
--- a/sim/eventq.hh
+++ b/sim/eventq.hh
@@ -73,7 +73,8 @@ class Event : public Serializeable, public FastAlloc
None = 0x0,
Squashed = 0x1,
Scheduled = 0x2,
- AutoDelete = 0x4
+ AutoDelete = 0x4,
+ AutoSerialize = 0x8
};
bool getFlags(Flags f) const { return (_flags & f) == f; }
@@ -190,7 +191,7 @@ class Event : public Serializeable, public FastAlloc
};
virtual void serialize(std::ostream &os);
- virtual void unserialize(const IniFile *db, const std::string &section);
+ virtual void unserialize(Checkpoint *cp, const std::string &section);
};
template <class T, void (T::* F)()>
@@ -221,6 +222,9 @@ class EventQueue : public Serializeable
private:
Event *head;
+ // only used to hold value between nameChildren() and serialize()
+ int numAutoSerializeEvents;
+
void insert(Event *event);
void remove(Event *event);
@@ -228,7 +232,7 @@ class EventQueue : public Serializeable
// constructor
EventQueue(const std::string &n)
- : Serializeable(n), head(NULL)
+ : Serializeable(n), head(NULL), numAutoSerializeEvents(-1)
{}
// schedule the given event on this queue
@@ -264,6 +268,7 @@ class EventQueue : public Serializeable
virtual void nameChildren();
virtual void serialize(std::ostream &os);
+ virtual void unserialize(Checkpoint *cp, const std::string &section);
};
diff --git a/sim/param.cc b/sim/param.cc
index 5f3f604c1..7affe4786 100644
--- a/sim/param.cc
+++ b/sim/param.cc
@@ -97,7 +97,7 @@ parseParam(const string &s, T &value)
template <class T>
void
-showParam(ostream &os, const T &value)
+showParam(ostream &os, T const &value)
{
os << value;
}
@@ -277,7 +277,7 @@ template VectorParam<type>;
// types that can use the above templates
#define INSTANTIATE_PARAM_TEMPLATES(type, typestr) \
template bool parseParam<type>(const string &s, type &value); \
-template void showParam<type>(ostream &os, const type &value); \
+template void showParam<type>(ostream &os, type const &value); \
template void Param<type>::parse(const string &); \
template void VectorParam<type>::parse(const string &); \
template void Param<type>::showValue(ostream &) const; \
diff --git a/sim/serialize.cc b/sim/serialize.cc
index f838acc8d..dfd495a32 100644
--- a/sim/serialize.cc
+++ b/sim/serialize.cc
@@ -43,6 +43,7 @@
#include "sim/sim_events.hh"
#include "sim/sim_object.hh"
#include "base/trace.hh"
+#include "sim/config_node.hh"
using namespace std;
@@ -88,11 +89,11 @@ paramOut(ostream &os, const std::string &name, const T& param)
template <class T>
void
-paramIn(const IniFile *db, const std::string &section,
+paramIn(Checkpoint *cp, const std::string &section,
const std::string &name, T& param)
{
std::string str;
- if (!db->find(section, name, str) || !parseParam(str, param)) {
+ if (!cp->find(section, name, str) || !parseParam(str, param)) {
fatal("Can't unserialize '%s:%s'\n", section, name);
}
}
@@ -116,11 +117,11 @@ arrayParamOut(ostream &os, const std::string &name,
template <class T>
void
-arrayParamIn(const IniFile *db, const std::string &section,
+arrayParamIn(Checkpoint *cp, const std::string &section,
const std::string &name, T *param, int size)
{
std::string str;
- if (!db->find(section, name, str)) {
+ if (!cp->find(section, name, str)) {
fatal("Can't unserialize '%s:%s'\n", section, name);
}
@@ -159,17 +160,27 @@ arrayParamIn(const IniFile *db, const std::string &section,
}
+void
+objParamIn(Checkpoint *cp, const std::string &section,
+ const std::string &name, Serializeable * &param)
+{
+ if (!cp->findObj(section, name, param)) {
+ fatal("Can't unserialize '%s:%s'\n", section, name);
+ }
+}
+
+
#define INSTANTIATE_PARAM_TEMPLATES(type) \
template void \
-paramOut(ostream &os, const std::string &name, const type &param); \
+paramOut(ostream &os, const std::string &name, type const &param); \
template void \
-paramIn(const IniFile *db, const std::string &section, \
+paramIn(Checkpoint *cp, const std::string &section, \
const std::string &name, type & param); \
template void \
arrayParamOut(ostream &os, const std::string &name, \
- const type *param, int size); \
+ type const *param, int size); \
template void \
-arrayParamIn(const IniFile *db, const std::string &section, \
+arrayParamIn(Checkpoint *cp, const std::string &section, \
const std::string &name, type *param, int size);
@@ -421,41 +432,74 @@ SerializeableClass::SerializeableClass(const string &className,
//
//
Serializeable *
-SerializeableClass::createObject(IniFile &configDB,
- const string &configClassName)
+SerializeableClass::createObject(Checkpoint *cp,
+ const std::string &section)
{
- // find simulation object class name from configuration class
- // (specified by 'type=' parameter)
- string simObjClassName;
+ string className;
- if (!configDB.findDefault(configClassName, "type", simObjClassName)) {
- cerr << "Configuration class '" << configClassName << "' not found."
- << endl;
- abort();
+ if (!cp->find(section, "type", className)) {
+ fatal("Serializeable::create: no 'type' entry in section '%s'.\n",
+ section);
}
- // look up className to get appropriate createFunc
- if (classMap->find(simObjClassName) == classMap->end()) {
- cerr << "Simulator object class '" << simObjClassName << "' not found."
- << endl;
- abort();
+ CreateFunc createFunc = (*classMap)[className];
+
+ if (createFunc == NULL) {
+ fatal("Serializeable::create: no create function for class '%s'.\n",
+ className);
}
- CreateFunc createFunc = (*classMap)[simObjClassName];
+ Serializeable *object = createFunc(cp, section);
- // builder instance
- SerializeableBuilder *objectBuilder = (*createFunc)();
+ assert(object != NULL);
- assert(objectBuilder != NULL);
+ return object;
+}
- // now create the actual simulation object
- Serializeable *object = objectBuilder->create();
- assert(object != NULL);
+Serializeable *
+Serializeable::create(Checkpoint *cp, const std::string &section)
+{
+ Serializeable *object = SerializeableClass::createObject(cp, section);
+ object->unserialize(cp, section);
+ return object;
+}
- // done with the SerializeableBuilder now
- delete objectBuilder;
- return object;
+Checkpoint::Checkpoint(const std::string &filename, const std::string &path,
+ const ConfigNode *_configNode)
+ : db(new IniFile), basePath(path), configNode(_configNode)
+{
+ if (!db->load(filename)) {
+ fatal("Can't load checkpoint file '%s'\n", filename);
+ }
+
+ mainEventQueue.unserialize(this, "MainEventQueue");
+}
+
+
+bool
+Checkpoint::find(const std::string &section, const std::string &entry,
+ std::string &value)
+{
+ return db->find(section, entry, value);
}
+
+bool
+Checkpoint::findObj(const std::string &section, const std::string &entry,
+ Serializeable *&value)
+{
+ string path;
+
+ if (!db->find(section, entry, path))
+ return false;
+
+ if ((value = configNode->resolveSimObject(path)) != NULL)
+ return true;
+
+ if ((value = objMap[path]) != NULL)
+ return true;
+
+ return false;
+}
diff --git a/sim/serialize.hh b/sim/serialize.hh
index 4e0dbd1bd..b615e6527 100644
--- a/sim/serialize.hh
+++ b/sim/serialize.hh
@@ -41,13 +41,14 @@
#include "sim/host.hh"
#include "sim/configfile.hh"
-class IniFile;
+class Serializeable;
+class Checkpoint;
template <class T>
void paramOut(std::ostream &os, const std::string &name, const T& param);
template <class T>
-void paramIn(const IniFile *db, const std::string &section,
+void paramIn(Checkpoint *cp, const std::string &section,
const std::string &name, T& param);
template <class T>
@@ -55,16 +56,21 @@ void arrayParamOut(std::ostream &os, const std::string &name,
const T *param, int size);
template <class T>
-void arrayParamIn(const IniFile *db, const std::string &section,
+void arrayParamIn(Checkpoint *cp, const std::string &section,
const std::string &name, T *param, int size);
+void
+objParamIn(Checkpoint *cp, const std::string &section,
+ const std::string &name, Serializeable * &param);
+
+
//
// These macros are streamlined to use in serialize/unserialize
// functions. It's assumed that serialize() has a parameter 'os' for
-// the ostream, and unserialize() has parameters 'db' and 'section'.
+// the ostream, and unserialize() has parameters 'cp' and 'section'.
#define SERIALIZE_SCALAR(scalar) paramOut(os, #scalar, scalar)
-#define UNSERIALIZE_SCALAR(scalar) paramIn(db, section, #scalar, scalar)
+#define UNSERIALIZE_SCALAR(scalar) paramIn(cp, section, #scalar, scalar)
// ENUMs are like SCALARs, but we cast them to ints on the way out
#define SERIALIZE_ENUM(scalar) paramOut(os, #scalar, (int)scalar)
@@ -72,7 +78,7 @@ void arrayParamIn(const IniFile *db, const std::string &section,
#define UNSERIALIZE_ENUM(scalar) \
do { \
int tmp; \
- paramIn(db, section, #scalar, tmp); \
+ paramIn(cp, section, #scalar, tmp); \
scalar = (typeof(scalar))tmp; \
} while (0)
@@ -80,7 +86,16 @@ void arrayParamIn(const IniFile *db, const std::string &section,
arrayParamOut(os, #member, member, size)
#define UNSERIALIZE_ARRAY(member, size) \
- arrayParamIn(db, section, #member, member, size)
+ arrayParamIn(cp, section, #member, member, size)
+
+#define SERIALIZE_OBJPTR(objptr) paramOut(os, #objptr, (objptr)->name())
+
+#define UNSERIALIZE_OBJPTR(objptr) \
+ do { \
+ Serializeable *sptr; \
+ objParamIn(cp, section, #objptr, sptr); \
+ objptr = dynamic_cast<typeof(objptr)>(sptr); \
+ } while (0)
/*
* Basic support for object serialization.
@@ -113,7 +128,10 @@ class Serializeable
virtual void nameChildren() {}
virtual void serialize(std::ostream& os) {}
- virtual void unserialize(const IniFile *db, const std::string &section) {}
+ virtual void unserialize(Checkpoint *cp, const std::string &section) {}
+
+ static Serializeable *create(Checkpoint *cp,
+ const std::string &section);
};
class Serializer
@@ -187,7 +205,8 @@ class SerializeableClass
// 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 SerializeableBuilder *(*CreateFunc)();
+ typedef Serializeable *(*CreateFunc)(Checkpoint *cp,
+ const std::string &section);
static std::map<std::string,CreateFunc> *classMap;
@@ -200,9 +219,8 @@ class SerializeableClass
// create Serializeable given name of class and pointer to
// configuration hierarchy node
- static Serializeable *createObject(IniFile &configDB,
- const std::string &configClassName);
-
+ static Serializeable *createObject(Checkpoint *cp,
+ const std::string &section);
};
//
@@ -210,29 +228,29 @@ class SerializeableClass
// SerializeableBuilder and SerializeableClass objects
//
-#define CREATE_SERIALIZEABLE(OBJ_CLASS) \
-OBJ_CLASS *OBJ_CLASS##Builder::create()
-
-#define REGISTER_SERIALIZEABLE(CLASS_NAME, OBJ_CLASS) \
-class OBJ_CLASS##Builder : public SerializeableBuilder \
-{ \
- public: \
- \
- OBJ_CLASS##Builder() {} \
- virtual ~OBJ_CLASS##Builder() {} \
- \
- OBJ_CLASS *create(); \
-}; \
- \
- \
-SerializeableBuilder * \
-new##OBJ_CLASS##Builder() \
-{ \
- return new OBJ_CLASS##Builder(); \
-} \
- \
-SerializeableClass the##OBJ_CLASS##Class(CLASS_NAME, \
- new##OBJ_CLASS##Builder);
+#define REGISTER_SERIALIZEABLE(CLASS_NAME, OBJ_CLASS) \
+SerializeableClass the##OBJ_CLASS##Class(CLASS_NAME, \
+ OBJ_CLASS::createForUnserialize);
+
+class Checkpoint
+{
+ private:
+
+ IniFile *db;
+ const std::string basePath;
+ const ConfigNode *configNode;
+ std::map<std::string, Serializeable*> objMap;
+
+ public:
+ Checkpoint(const std::string &filename, const std::string &path,
+ const ConfigNode *_configNode);
+
+ bool find(const std::string &section, const std::string &entry,
+ std::string &value);
+
+ bool findObj(const std::string &section, const std::string &entry,
+ Serializeable *&value);
+};
//