Stats & serialization tweaks & cleanup. Unserializing from
authorSteve Reinhardt <stever@eecs.umich.edu>
Thu, 11 Dec 2003 08:16:46 +0000 (00:16 -0800)
committerSteve Reinhardt <stever@eecs.umich.edu>
Thu, 11 Dec 2003 08:16:46 +0000 (00:16 -0800)
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

arch/alpha/isa_traits.hh
dev/etherlink.hh
kern/tru64/tru64_system.cc
sim/eventq.cc
sim/eventq.hh
sim/main.cc
sim/process.cc
sim/serialize.cc
sim/serialize.hh
sim/sim_object.cc
sim/sim_object.hh

index 406ffb6f3c95bb893a4d346c581836de914a08e7..ecca91d43e096cd9def23da6283aee52b3871afb 100644 (file)
@@ -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,
index ea7bdcbccd796c229033168acd6724b6bb64efe8..ef587faf72d86b74da0a7149c5a63f2428a71113 100644 (file)
@@ -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;
 
index 6fe5fb81b20553d09821647c913588c7ef48c7e3..99d99afd43fa482e72f6304da27168b7adaf6607 100644 (file)
@@ -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);
index 52f7dfaff11eca8eefe56af2c929065590d71595..a0aac4fee20966c3cf4342413dc2838a9012bac2 100644 (file)
@@ -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);
     }
 }
 
index 475c4facedce0192dd16e6ae032af9d9b1b7bd4c..dc1b2d9afd9e241231e050fcb0e98efbe14afdc7 100644 (file)
@@ -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;
index f697aebce1c760cd012a41e9cc34530d41e224a2..287b3d6e6bb6a62753a6d40f1cd719c9a83db8d6 100644 (file)
@@ -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;
 }
index 0d7c3403d870b29f24363c05b9ba6ebf79506304..c5eee4527b5e5e37e2088f476d7a6c862f548d2b 100644 (file)
@@ -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
index 9738029c2132ecd903f73f54523a06452d530559..82d295384f1a9830016d8ed3263bd85c5bcec02e 100644 (file)
 
 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;
 
index 077931d8c5dd16b70a48ca5b463c549d8d92252a..60e06f94befd949b190fed3f1fc67a311fa8e976 100644 (file)
@@ -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);
 };
index 90ad786482f29e3c2eb6a7709ca5d8e24df5e359..364dbe035a73a62e8f3051b7d27df40a908e9d96 100644 (file)
@@ -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);
+   }
+}
index 6b26a1cb0710c70acddf39ed36ac3e24b2a14b59..937ff94278c2637c21d717cde7278a00f8a5ad03 100644 (file)
@@ -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__