diff options
-rw-r--r-- | arch/alpha/alpha_memory.cc | 4 | ||||
-rw-r--r-- | arch/alpha/alpha_memory.hh | 2 | ||||
-rw-r--r-- | arch/alpha/isa_traits.hh | 4 | ||||
-rw-r--r-- | cpu/exec_context.cc | 4 | ||||
-rw-r--r-- | cpu/exec_context.hh | 2 | ||||
-rw-r--r-- | cpu/simple_cpu/simple_cpu.cc | 9 | ||||
-rw-r--r-- | cpu/simple_cpu/simple_cpu.hh | 4 | ||||
-rw-r--r-- | dev/alpha_access.h | 4 | ||||
-rw-r--r-- | dev/alpha_console.cc | 6 | ||||
-rw-r--r-- | dev/alpha_console.hh | 2 | ||||
-rw-r--r-- | dev/console.cc | 2 | ||||
-rw-r--r-- | dev/console.hh | 2 | ||||
-rw-r--r-- | sim/eventq.cc | 48 | ||||
-rw-r--r-- | sim/eventq.hh | 11 | ||||
-rw-r--r-- | sim/param.cc | 4 | ||||
-rw-r--r-- | sim/serialize.cc | 108 | ||||
-rw-r--r-- | sim/serialize.hh | 88 |
17 files changed, 192 insertions, 112 deletions
diff --git a/arch/alpha/alpha_memory.cc b/arch/alpha/alpha_memory.cc index 7c0b1120f..c79b821d0 100644 --- a/arch/alpha/alpha_memory.cc +++ b/arch/alpha/alpha_memory.cc @@ -204,13 +204,13 @@ AlphaTlb::serialize(ostream &os) } void -AlphaTlb::unserialize(const IniFile *db, const string §ion) +AlphaTlb::unserialize(Checkpoint *cp, const string §ion) { UNSERIALIZE_SCALAR(size); UNSERIALIZE_SCALAR(nlu); for (int i = 0; i < size; i++) { - table[i].unserialize(db, csprintf("%s.PTE%d", section, i)); + table[i].unserialize(cp, csprintf("%s.PTE%d", section, i)); if (table[i].valid) { lookupTable.insert(make_pair(table[i].tag, i)); } diff --git a/arch/alpha/alpha_memory.hh b/arch/alpha/alpha_memory.hh index fc4d46191..bfcd313e2 100644 --- a/arch/alpha/alpha_memory.hh +++ b/arch/alpha/alpha_memory.hh @@ -74,7 +74,7 @@ class AlphaTlb : public SimObject // Checkpointing virtual void serialize(std::ostream &os); - virtual void unserialize(const IniFile *db, const std::string §ion); + virtual void unserialize(Checkpoint *cp, const std::string §ion); }; class AlphaItb : public AlphaTlb diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index fbdcffbcf..406ffb6f3 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -34,7 +34,7 @@ #include "base/misc.hh" class FullCPU; -class IniFile; +class Checkpoint; #define TARGET_ALPHA @@ -160,7 +160,7 @@ class AlphaISA uint8_t opcode, ra; // current instruction details (for intr's) void serialize(std::ostream &os); - void unserialize(const IniFile *db, const std::string §ion); + void unserialize(Checkpoint *cp, const std::string §ion); }; static StaticInstPtr<AlphaISA> decodeInst(MachInst); diff --git a/cpu/exec_context.cc b/cpu/exec_context.cc index b869a8c4d..195c9daad 100644 --- a/cpu/exec_context.cc +++ b/cpu/exec_context.cc @@ -108,10 +108,10 @@ ExecContext::serialize(ostream &os) void -ExecContext::unserialize(const IniFile *db, const std::string §ion) +ExecContext::unserialize(Checkpoint *cp, const std::string §ion) { UNSERIALIZE_ENUM(_status); - regs.unserialize(db, section); + regs.unserialize(cp, section); // thread_num and cpu_id are deterministic from the config UNSERIALIZE_SCALAR(func_exe_insn); } diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 6938b369f..cb826a15e 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -142,7 +142,7 @@ class ExecContext void regStats(const std::string &name); void serialize(std::ostream &os); - void unserialize(const IniFile *db, const std::string §ion); + void unserialize(Checkpoint *cp, const std::string §ion); #ifdef FULL_SYSTEM bool validInstAddr(Addr addr) { return true; } diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc index 3179b7b1f..519a8cd4d 100644 --- a/cpu/simple_cpu/simple_cpu.cc +++ b/cpu/simple_cpu/simple_cpu.cc @@ -262,6 +262,7 @@ SimpleCPU::serialize(ostream &os) { SERIALIZE_ENUM(_status); SERIALIZE_SCALAR(inst); + nameOut(os, csprintf("%s.xc", name())); xc->serialize(os); nameOut(os, csprintf("%s.tickEvent", name())); tickEvent.serialize(os); @@ -270,14 +271,14 @@ SimpleCPU::serialize(ostream &os) } void -SimpleCPU::unserialize(const IniFile *db, const string §ion) +SimpleCPU::unserialize(Checkpoint *cp, const string §ion) { UNSERIALIZE_ENUM(_status); UNSERIALIZE_SCALAR(inst); - xc->unserialize(db, section); - tickEvent.unserialize(db, csprintf("%s.tickEvent", name())); + xc->unserialize(cp, csprintf("%s.xc", section)); + tickEvent.unserialize(cp, csprintf("%s.tickEvent", section)); cacheCompletionEvent - .unserialize(db, csprintf("%s.cacheCompletionEvent", name())); + .unserialize(cp, csprintf("%s.cacheCompletionEvent", section)); } void diff --git a/cpu/simple_cpu/simple_cpu.hh b/cpu/simple_cpu/simple_cpu.hh index 61831cb3c..61c9143ba 100644 --- a/cpu/simple_cpu/simple_cpu.hh +++ b/cpu/simple_cpu/simple_cpu.hh @@ -49,7 +49,7 @@ class GDBListener; #endif // FULL_SYSTEM class MemInterface; -class IniFile; +class Checkpoint; namespace Trace { class InstRecord; @@ -259,7 +259,7 @@ class SimpleCPU : public BaseCPU void processCacheCompletion(); virtual void serialize(std::ostream &os); - virtual void unserialize(const IniFile *db, const std::string §ion); + virtual void unserialize(Checkpoint *cp, const std::string §ion); template <class T> Fault read(Addr addr, T& data, unsigned flags); diff --git a/dev/alpha_access.h b/dev/alpha_access.h index c145fa2a3..eb551a359 100644 --- a/dev/alpha_access.h +++ b/dev/alpha_access.h @@ -44,7 +44,7 @@ typedef uint64_t UINT64; #include <ostream> #include <string> -class IniFile; +class Checkpoint; #endif @@ -82,7 +82,7 @@ struct AlphaAccess #ifndef CONSOLE void serialize(std::ostream &os); - void unserialize(const IniFile *db, const std::string §ion); + void unserialize(Checkpoint *cp, const std::string §ion); #endif }; diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc index 969b1e4c3..6fe57edb5 100644 --- a/dev/alpha_console.cc +++ b/dev/alpha_console.cc @@ -188,7 +188,7 @@ AlphaAccess::serialize(ostream &os) } void -AlphaAccess::unserialize(const IniFile *db, const std::string §ion) +AlphaAccess::unserialize(Checkpoint *cp, const std::string §ion) { UNSERIALIZE_SCALAR(last_offset); UNSERIALIZE_SCALAR(version); @@ -216,9 +216,9 @@ AlphaConsole::serialize(ostream &os) } void -AlphaConsole::unserialize(const IniFile *db, const std::string §ion) +AlphaConsole::unserialize(Checkpoint *cp, const std::string §ion) { - alphaAccess->unserialize(db, section); + alphaAccess->unserialize(cp, section); } BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) diff --git a/dev/alpha_console.hh b/dev/alpha_console.hh index e4aeb2417..9e774773e 100644 --- a/dev/alpha_console.hh +++ b/dev/alpha_console.hh @@ -101,7 +101,7 @@ class AlphaConsole : public MmapDevice * standard serialization routines for checkpointing */ virtual void serialize(std::ostream &os); - virtual void unserialize(const IniFile *db, const std::string §ion); + virtual void unserialize(Checkpoint *cp, const std::string §ion); }; #endif // __ALPHA_CONSOLE_HH__ diff --git a/dev/console.cc b/dev/console.cc index 749add532..2378f8c75 100644 --- a/dev/console.cc +++ b/dev/console.cc @@ -319,7 +319,7 @@ SimConsole::serialize(ostream &os) } void -SimConsole::unserialize(const IniFile *db, const std::string §ion) +SimConsole::unserialize(Checkpoint *cp, const std::string §ion) { } diff --git a/dev/console.hh b/dev/console.hh index 6746f90b6..fd02e7a9a 100644 --- a/dev/console.hh +++ b/dev/console.hh @@ -129,7 +129,7 @@ class SimConsole : public SimObject void setInt(int bits); virtual void serialize(std::ostream &os); - virtual void unserialize(const IniFile *db, const std::string §ion); + virtual void unserialize(Checkpoint *cp, const std::string §ion); }; class ConsoleListener : public SimObject 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 §ion) +Event::unserialize(Checkpoint *cp, const string §ion) { if (scheduled()) deschedule(); @@ -154,39 +154,51 @@ Event::unserialize(const IniFile *db, const string §ion) 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 §ion) +{ + 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 §ion); + virtual void unserialize(Checkpoint *cp, const std::string §ion); }; 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 §ion); }; 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 §ion, +paramIn(Checkpoint *cp, const std::string §ion, 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 §ion, +arrayParamIn(Checkpoint *cp, const std::string §ion, 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 §ion, } +void +objParamIn(Checkpoint *cp, const std::string §ion, + const std::string &name, Serializeable * ¶m) +{ + 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 ¶m); \ +paramOut(ostream &os, const std::string &name, type const ¶m); \ template void \ -paramIn(const IniFile *db, const std::string §ion, \ +paramIn(Checkpoint *cp, const std::string §ion, \ 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 §ion, \ +arrayParamIn(Checkpoint *cp, const std::string §ion, \ 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 §ion) { - // 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 §ion) +{ + 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 §ion, const std::string &entry, + std::string &value) +{ + return db->find(section, entry, value); } + +bool +Checkpoint::findObj(const std::string §ion, 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 §ion, +void paramIn(Checkpoint *cp, const std::string §ion, 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 §ion, +void arrayParamIn(Checkpoint *cp, const std::string §ion, const std::string &name, T *param, int size); +void +objParamIn(Checkpoint *cp, const std::string §ion, + const std::string &name, Serializeable * ¶m); + + // // 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 §ion, #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 §ion, 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 §ion) {} + virtual void unserialize(Checkpoint *cp, const std::string §ion) {} + + static Serializeable *create(Checkpoint *cp, + const std::string §ion); }; 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 §ion); 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 §ion); }; // @@ -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 §ion, const std::string &entry, + std::string &value); + + bool findObj(const std::string §ion, const std::string &entry, + Serializeable *&value); +}; // |