serialize.hh revision 10459
12SN/A/*
21762SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
32SN/A * All rights reserved.
42SN/A *
52SN/A * Redistribution and use in source and binary forms, with or without
62SN/A * modification, are permitted provided that the following conditions are
72SN/A * met: redistributions of source code must retain the above copyright
82SN/A * notice, this list of conditions and the following disclaimer;
92SN/A * redistributions in binary form must reproduce the above copyright
102SN/A * notice, this list of conditions and the following disclaimer in the
112SN/A * documentation and/or other materials provided with the distribution;
122SN/A * neither the name of the copyright holders nor the names of its
132SN/A * contributors may be used to endorse or promote products derived from
142SN/A * this software without specific prior written permission.
152SN/A *
162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282760Sbinkertn@umich.edu * Authors: Nathan Binkert
292760Sbinkertn@umich.edu *          Erik Hallnor
302665Ssaidi@eecs.umich.edu *          Steve Reinhardt
312SN/A */
322SN/A
332SN/A/* @file
342SN/A * Serialization Interface Declarations
352SN/A */
362SN/A
372SN/A#ifndef __SERIALIZE_HH__
382SN/A#define __SERIALIZE_HH__
392SN/A
402SN/A
418229Snate@binkert.org#include <iostream>
422SN/A#include <list>
438229Snate@binkert.org#include <map>
444841Ssaidi@eecs.umich.edu#include <vector>
452SN/A
4610459SAndreas.Sandberg@ARM.com#include "base/bitunion.hh"
476214Snate@binkert.org#include "base/types.hh"
482SN/A
492738Sstever@eecs.umich.educlass IniFile;
50395SN/Aclass Serializable;
51237SN/Aclass Checkpoint;
524000Ssaidi@eecs.umich.educlass SimObject;
539983Sstever@gmail.comclass EventQueue;
542SN/A
559048SAli.Saidi@ARM.com/** The current version of the checkpoint format.
569048SAli.Saidi@ARM.com * This should be incremented by 1 and only 1 for every new version, where a new
579056SAli.Saidi@ARM.com * version is defined as a checkpoint created before this version won't work on
589048SAli.Saidi@ARM.com * the current version until the checkpoint format is updated. Adding a new
599048SAli.Saidi@ARM.com * SimObject shouldn't cause the version number to increase, only changes to
609056SAli.Saidi@ARM.com * existing objects such as serializing/unserializing more state, changing sizes
619048SAli.Saidi@ARM.com * of serialized arrays, etc. */
6210338SCurtis.Dunham@arm.comstatic const uint64_t gem5CheckpointVersion = 0x000000000000000d;
639048SAli.Saidi@ARM.com
64217SN/Atemplate <class T>
65502SN/Avoid paramOut(std::ostream &os, const std::string &name, const T &param);
66217SN/A
6710459SAndreas.Sandberg@ARM.comtemplate <typename DataType, typename BitUnion>
6810459SAndreas.Sandberg@ARM.comvoid paramOut(std::ostream &os, const std::string &name,
6910459SAndreas.Sandberg@ARM.com              const BitfieldBackend::BitUnionOperators<DataType, BitUnion> &p)
7010459SAndreas.Sandberg@ARM.com{
7110459SAndreas.Sandberg@ARM.com    paramOut(os, name, p.__data);
7210459SAndreas.Sandberg@ARM.com}
7310459SAndreas.Sandberg@ARM.com
74217SN/Atemplate <class T>
75237SN/Avoid paramIn(Checkpoint *cp, const std::string &section,
76502SN/A             const std::string &name, T &param);
77217SN/A
7810459SAndreas.Sandberg@ARM.comtemplate <typename DataType, typename BitUnion>
7910459SAndreas.Sandberg@ARM.comvoid paramIn(Checkpoint *cp, const std::string &section,
8010459SAndreas.Sandberg@ARM.com             const std::string &name,
8110459SAndreas.Sandberg@ARM.com             BitfieldBackend::BitUnionOperators<DataType, BitUnion> &p)
8210459SAndreas.Sandberg@ARM.com{
8310459SAndreas.Sandberg@ARM.com    paramIn(cp, section, name, p.__data);
8410459SAndreas.Sandberg@ARM.com}
8510459SAndreas.Sandberg@ARM.com
86217SN/Atemplate <class T>
876820SLisa.Hsu@amd.combool optParamIn(Checkpoint *cp, const std::string &section,
886820SLisa.Hsu@amd.com             const std::string &name, T &param);
896820SLisa.Hsu@amd.com
9010459SAndreas.Sandberg@ARM.comtemplate <typename DataType, typename BitUnion>
9110459SAndreas.Sandberg@ARM.combool optParamIn(Checkpoint *cp, const std::string &section,
9210459SAndreas.Sandberg@ARM.com                const std::string &name,
9310459SAndreas.Sandberg@ARM.com                BitfieldBackend::BitUnionOperators<DataType, BitUnion> &p)
9410459SAndreas.Sandberg@ARM.com{
9510459SAndreas.Sandberg@ARM.com    return optParamIn(cp, section, name, p.__data);
9610459SAndreas.Sandberg@ARM.com}
9710459SAndreas.Sandberg@ARM.com
986820SLisa.Hsu@amd.comtemplate <class T>
99217SN/Avoid arrayParamOut(std::ostream &os, const std::string &name,
1006227Snate@binkert.org                   const T *param, unsigned size);
101217SN/A
102217SN/Atemplate <class T>
1034841Ssaidi@eecs.umich.eduvoid arrayParamOut(std::ostream &os, const std::string &name,
1044841Ssaidi@eecs.umich.edu                   const std::vector<T> &param);
1054841Ssaidi@eecs.umich.edu
1064841Ssaidi@eecs.umich.edutemplate <class T>
1077948SAli.Saidi@ARM.comvoid arrayParamOut(std::ostream &os, const std::string &name,
1087948SAli.Saidi@ARM.com                   const std::list<T> &param);
1097948SAli.Saidi@ARM.com
1107948SAli.Saidi@ARM.comtemplate <class T>
111237SN/Avoid arrayParamIn(Checkpoint *cp, const std::string &section,
1126227Snate@binkert.org                  const std::string &name, T *param, unsigned size);
113217SN/A
1144841Ssaidi@eecs.umich.edutemplate <class T>
1154841Ssaidi@eecs.umich.eduvoid arrayParamIn(Checkpoint *cp, const std::string &section,
1164841Ssaidi@eecs.umich.edu                  const std::string &name, std::vector<T> &param);
1174841Ssaidi@eecs.umich.edu
1187948SAli.Saidi@ARM.comtemplate <class T>
1197948SAli.Saidi@ARM.comvoid arrayParamIn(Checkpoint *cp, const std::string &section,
1207948SAli.Saidi@ARM.com                  const std::string &name, std::list<T> &param);
1217948SAli.Saidi@ARM.com
122237SN/Avoid
123237SN/AobjParamIn(Checkpoint *cp, const std::string &section,
1244000Ssaidi@eecs.umich.edu           const std::string &name, SimObject * &param);
125237SN/A
1268902Sandreas.hansson@arm.comtemplate <typename T>
1278902Sandreas.hansson@arm.comvoid fromInt(T &t, int i)
1288902Sandreas.hansson@arm.com{
1298902Sandreas.hansson@arm.com    t = (T)i;
1308902Sandreas.hansson@arm.com}
1318902Sandreas.hansson@arm.com
1328902Sandreas.hansson@arm.comtemplate <typename T>
1338902Sandreas.hansson@arm.comvoid fromSimObject(T &t, SimObject *s)
1348902Sandreas.hansson@arm.com{
1358902Sandreas.hansson@arm.com    t = dynamic_cast<T>(s);
1368902Sandreas.hansson@arm.com}
137237SN/A
138217SN/A//
139217SN/A// These macros are streamlined to use in serialize/unserialize
140217SN/A// functions.  It's assumed that serialize() has a parameter 'os' for
141237SN/A// the ostream, and unserialize() has parameters 'cp' and 'section'.
1425543Ssaidi@eecs.umich.edu#define SERIALIZE_SCALAR(scalar)        paramOut(os, #scalar, scalar)
143217SN/A
1445543Ssaidi@eecs.umich.edu#define UNSERIALIZE_SCALAR(scalar)      paramIn(cp, section, #scalar, scalar)
1456820SLisa.Hsu@amd.com#define UNSERIALIZE_OPT_SCALAR(scalar)      optParamIn(cp, section, #scalar, scalar)
146217SN/A
147223SN/A// ENUMs are like SCALARs, but we cast them to ints on the way out
1485543Ssaidi@eecs.umich.edu#define SERIALIZE_ENUM(scalar)          paramOut(os, #scalar, (int)scalar)
149223SN/A
1505543Ssaidi@eecs.umich.edu#define UNSERIALIZE_ENUM(scalar)                \
1515543Ssaidi@eecs.umich.edu do {                                           \
1525543Ssaidi@eecs.umich.edu    int tmp;                                    \
1535543Ssaidi@eecs.umich.edu    paramIn(cp, section, #scalar, tmp);         \
1548902Sandreas.hansson@arm.com    fromInt(scalar, tmp);                    \
155223SN/A  } while (0)
156223SN/A
1575543Ssaidi@eecs.umich.edu#define SERIALIZE_ARRAY(member, size)           \
158217SN/A        arrayParamOut(os, #member, member, size)
159217SN/A
1605543Ssaidi@eecs.umich.edu#define UNSERIALIZE_ARRAY(member, size)         \
161237SN/A        arrayParamIn(cp, section, #member, member, size)
162237SN/A
1635543Ssaidi@eecs.umich.edu#define SERIALIZE_OBJPTR(objptr)        paramOut(os, #objptr, (objptr)->name())
164237SN/A
1655543Ssaidi@eecs.umich.edu#define UNSERIALIZE_OBJPTR(objptr)                      \
1665543Ssaidi@eecs.umich.edu  do {                                                  \
1675543Ssaidi@eecs.umich.edu    SimObject *sptr;                                    \
1685543Ssaidi@eecs.umich.edu    objParamIn(cp, section, #objptr, sptr);             \
1698902Sandreas.hansson@arm.com    fromSimObject(objptr, sptr);                        \
170237SN/A  } while (0)
171217SN/A
1729342SAndreas.Sandberg@arm.com/**
1732SN/A * Basic support for object serialization.
1749342SAndreas.Sandberg@arm.com *
1759342SAndreas.Sandberg@arm.com * @note Many objects that support serialization need to be put in a
1769342SAndreas.Sandberg@arm.com * consistent state when serialization takes place. We refer to the
1779342SAndreas.Sandberg@arm.com * action of forcing an object into a consistent state as
1789342SAndreas.Sandberg@arm.com * 'draining'. Objects that need draining inherit from Drainable. See
1799342SAndreas.Sandberg@arm.com * Drainable for more information.
1802SN/A */
181395SN/Aclass Serializable
1822SN/A{
1832SN/A  protected:
184510SN/A    void nameOut(std::ostream &os);
185510SN/A    void nameOut(std::ostream &os, const std::string &_name);
1862SN/A
1872SN/A  public:
1885739Snate@binkert.org    Serializable();
1895739Snate@binkert.org    virtual ~Serializable();
1902SN/A
191265SN/A    // manditory virtual function, so objects must provide names
192512SN/A    virtual const std::string name() const = 0;
1932SN/A
1945739Snate@binkert.org    virtual void serialize(std::ostream &os);
1955739Snate@binkert.org    virtual void unserialize(Checkpoint *cp, const std::string &section);
196237SN/A
1975739Snate@binkert.org    static Serializable *create(Checkpoint *cp, const std::string &section);
1982SN/A
1992287SN/A    static int ckptCount;
2002287SN/A    static int ckptMaxCount;
2012287SN/A    static int ckptPrevCount;
2022868Sktlim@umich.edu    static void serializeAll(const std::string &cpt_dir);
203395SN/A    static void unserializeGlobals(Checkpoint *cp);
2042SN/A};
2052SN/A
2069554Sandreas.hansson@arm.comvoid debug_serialize(const std::string &cpt_dir);
2079554Sandreas.hansson@arm.com
2082SN/A//
209395SN/A// A SerializableBuilder serves as an evaluation context for a set of
210395SN/A// parameters that describe a specific instance of a Serializable.  This
2112SN/A// evaluation context corresponds to a section in the .ini file (as
2122SN/A// with the base ParamContext) plus an optional node in the
2132SN/A// configuration hierarchy (the configNode member) for resolving
214395SN/A// Serializable references.  SerializableBuilder is an abstract superclass;
2152SN/A// derived classes specialize the class for particular subclasses of
216395SN/A// Serializable (e.g., BaseCache).
2172SN/A//
2182SN/A// For typical usage, see the definition of
219395SN/A// SerializableClass::createObject().
2202SN/A//
221395SN/Aclass SerializableBuilder
2222SN/A{
2232SN/A  public:
2242SN/A
225395SN/A    SerializableBuilder() {}
2262SN/A
227395SN/A    virtual ~SerializableBuilder() {}
2282SN/A
229395SN/A    // Create the actual Serializable corresponding to the parameter
2302SN/A    // values in this context.  This function is overridden in derived
2312SN/A    // classes to call a specific constructor for a particular
232395SN/A    // subclass of Serializable.
233395SN/A    virtual Serializable *create() = 0;
2342SN/A};
2352SN/A
2362SN/A//
237395SN/A// An instance of SerializableClass corresponds to a class derived from
238395SN/A// Serializable.  The SerializableClass instance serves to bind the string
2392SN/A// name (found in the config file) to a function that creates an
2402SN/A// instance of the appropriate derived class.
2412SN/A//
2422SN/A// This would be much cleaner in Smalltalk or Objective-C, where types
2432SN/A// are first-class objects themselves.
2442SN/A//
245395SN/Aclass SerializableClass
2462SN/A{
2472SN/A  public:
2482SN/A
2492SN/A    // Type CreateFunc is a pointer to a function that creates a new
2502SN/A    // simulation object builder based on a .ini-file parameter
2512SN/A    // section (specified by the first string argument), a unique name
2522SN/A    // for the object (specified by the second string argument), and
2532SN/A    // an optional config hierarchy node (specified by the third
254395SN/A    // argument).  A pointer to the new SerializableBuilder is returned.
255395SN/A    typedef Serializable *(*CreateFunc)(Checkpoint *cp,
2562738Sstever@eecs.umich.edu                                        const std::string &section);
2572SN/A
2582SN/A    static std::map<std::string,CreateFunc> *classMap;
2592SN/A
2602SN/A    // Constructor.  For example:
2612SN/A    //
262395SN/A    // SerializableClass baseCacheSerializableClass("BaseCacheSerializable",
263395SN/A    //                         newBaseCacheSerializableBuilder);
2642SN/A    //
265395SN/A    SerializableClass(const std::string &className, CreateFunc createFunc);
2662SN/A
267395SN/A    // create Serializable given name of class and pointer to
2682SN/A    // configuration hierarchy node
269395SN/A    static Serializable *createObject(Checkpoint *cp,
2702738Sstever@eecs.umich.edu                                      const std::string &section);
2712SN/A};
2722SN/A
2732SN/A//
2742SN/A// Macros to encapsulate the magic of declaring & defining
275395SN/A// SerializableBuilder and SerializableClass objects
2762SN/A//
2772SN/A
2785543Ssaidi@eecs.umich.edu#define REGISTER_SERIALIZEABLE(CLASS_NAME, OBJ_CLASS)                      \
2795543Ssaidi@eecs.umich.eduSerializableClass the##OBJ_CLASS##Class(CLASS_NAME,                        \
280237SN/A                                         OBJ_CLASS::createForUnserialize);
2812SN/A
28210453SAndrew.Bardsley@arm.com// Base class to wrap object resolving functionality.  This can be
28310453SAndrew.Bardsley@arm.com// provided to Checkpoint to allow it to map object names onto
28410453SAndrew.Bardsley@arm.com// object C++ objects in which to unserialize
28510453SAndrew.Bardsley@arm.comclass SimObjectResolver
28610453SAndrew.Bardsley@arm.com{
28710453SAndrew.Bardsley@arm.com  public:
28810453SAndrew.Bardsley@arm.com    virtual ~SimObjectResolver() { }
28910453SAndrew.Bardsley@arm.com
29010453SAndrew.Bardsley@arm.com    // Find a SimObject given a full path name
29110453SAndrew.Bardsley@arm.com    virtual SimObject *resolveSimObject(const std::string &name) = 0;
29210453SAndrew.Bardsley@arm.com};
29310453SAndrew.Bardsley@arm.com
294237SN/Aclass Checkpoint
295237SN/A{
296237SN/A  private:
297237SN/A
298237SN/A    IniFile *db;
299237SN/A
30010453SAndrew.Bardsley@arm.com    SimObjectResolver &objNameResolver;
30110453SAndrew.Bardsley@arm.com
302237SN/A  public:
30310453SAndrew.Bardsley@arm.com    Checkpoint(const std::string &cpt_dir, SimObjectResolver &resolver);
3049086Sandreas.hansson@arm.com    ~Checkpoint();
305237SN/A
306937SN/A    const std::string cptDir;
307937SN/A
308237SN/A    bool find(const std::string &section, const std::string &entry,
309237SN/A              std::string &value);
310237SN/A
311237SN/A    bool findObj(const std::string &section, const std::string &entry,
3124000Ssaidi@eecs.umich.edu                 SimObject *&value);
313304SN/A
314304SN/A    bool sectionExists(const std::string &section);
315449SN/A
316449SN/A    // The following static functions have to do with checkpoint
317449SN/A    // creation rather than restoration.  This class makes a handy
3187491Ssteve.reinhardt@amd.com    // namespace for them though.  Currently no Checkpoint object is
3197491Ssteve.reinhardt@amd.com    // created on serialization (only unserialization) so we track the
3207491Ssteve.reinhardt@amd.com    // directory name as a global.  It would be nice to change this
3217491Ssteve.reinhardt@amd.com    // someday
3227491Ssteve.reinhardt@amd.com
3237491Ssteve.reinhardt@amd.com  private:
3247491Ssteve.reinhardt@amd.com    // current directory we're serializing into.
3257491Ssteve.reinhardt@amd.com    static std::string currentDirectory;
3267491Ssteve.reinhardt@amd.com
3277491Ssteve.reinhardt@amd.com  public:
3287491Ssteve.reinhardt@amd.com    // Set the current directory.  This function takes care of
3297823Ssteve.reinhardt@amd.com    // inserting curTick() if there's a '%d' in the argument, and
3307491Ssteve.reinhardt@amd.com    // appends a '/' if necessary.  The final name is returned.
3317491Ssteve.reinhardt@amd.com    static std::string setDir(const std::string &base_name);
332449SN/A
333449SN/A    // Export current checkpoint directory name so other objects can
334449SN/A    // derive filenames from it (e.g., memory).  The return value is
335449SN/A    // guaranteed to end in '/' so filenames can be directly appended.
336449SN/A    // This function is only valid while a checkpoint is being created.
337449SN/A    static std::string dir();
338449SN/A
339449SN/A    // Filename for base checkpoint file within directory.
340449SN/A    static const char *baseFilename;
341237SN/A};
3422SN/A
3432SN/A#endif // __SERIALIZE_HH__
344