serialize.hh revision 1762
13914Ssaidi@eecs.umich.edu/*
23914Ssaidi@eecs.umich.edu * Copyright (c) 2002-2005 The Regents of The University of Michigan
33914Ssaidi@eecs.umich.edu * All rights reserved.
43914Ssaidi@eecs.umich.edu *
53914Ssaidi@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
63914Ssaidi@eecs.umich.edu * modification, are permitted provided that the following conditions are
73914Ssaidi@eecs.umich.edu * met: redistributions of source code must retain the above copyright
83914Ssaidi@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
93914Ssaidi@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
103914Ssaidi@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
113914Ssaidi@eecs.umich.edu * documentation and/or other materials provided with the distribution;
123914Ssaidi@eecs.umich.edu * neither the name of the copyright holders nor the names of its
133914Ssaidi@eecs.umich.edu * contributors may be used to endorse or promote products derived from
143914Ssaidi@eecs.umich.edu * this software without specific prior written permission.
153914Ssaidi@eecs.umich.edu *
163914Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
173914Ssaidi@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
183914Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
193914Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
203914Ssaidi@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
213914Ssaidi@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
223914Ssaidi@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233914Ssaidi@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243914Ssaidi@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253914Ssaidi@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
263914Ssaidi@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273914Ssaidi@eecs.umich.edu */
283914Ssaidi@eecs.umich.edu
293914Ssaidi@eecs.umich.edu/* @file
303914Ssaidi@eecs.umich.edu * Serialization Interface Declarations
313914Ssaidi@eecs.umich.edu */
323914Ssaidi@eecs.umich.edu
333914Ssaidi@eecs.umich.edu#ifndef __SERIALIZE_HH__
343914Ssaidi@eecs.umich.edu#define __SERIALIZE_HH__
353914Ssaidi@eecs.umich.edu
363914Ssaidi@eecs.umich.edu
373914Ssaidi@eecs.umich.edu#include <list>
383914Ssaidi@eecs.umich.edu#include <iostream>
393914Ssaidi@eecs.umich.edu#include <map>
404762Snate@binkert.org
413914Ssaidi@eecs.umich.edu#include "sim/host.hh"
423914Ssaidi@eecs.umich.edu#include "sim/configfile.hh"
433914Ssaidi@eecs.umich.edu
443914Ssaidi@eecs.umich.educlass Serializable;
453914Ssaidi@eecs.umich.educlass Checkpoint;
463914Ssaidi@eecs.umich.edu
473914Ssaidi@eecs.umich.edutemplate <class T>
483914Ssaidi@eecs.umich.eduvoid paramOut(std::ostream &os, const std::string &name, const T &param);
493914Ssaidi@eecs.umich.edu
503914Ssaidi@eecs.umich.edutemplate <class T>
514762Snate@binkert.orgvoid paramIn(Checkpoint *cp, const std::string &section,
523943Sbinkertn@umich.edu             const std::string &name, T &param);
533914Ssaidi@eecs.umich.edu
544762Snate@binkert.orgtemplate <class T>
553990Ssaidi@eecs.umich.eduvoid arrayParamOut(std::ostream &os, const std::string &name,
563990Ssaidi@eecs.umich.edu                   const T *param, int size);
573914Ssaidi@eecs.umich.edu
583914Ssaidi@eecs.umich.edutemplate <class T>
593990Ssaidi@eecs.umich.eduvoid arrayParamIn(Checkpoint *cp, const std::string &section,
603990Ssaidi@eecs.umich.edu                  const std::string &name, T *param, int size);
613990Ssaidi@eecs.umich.edu
623990Ssaidi@eecs.umich.eduvoid
633990Ssaidi@eecs.umich.eduobjParamIn(Checkpoint *cp, const std::string &section,
643990Ssaidi@eecs.umich.edu           const std::string &name, Serializable * &param);
653990Ssaidi@eecs.umich.edu
663990Ssaidi@eecs.umich.edu
673990Ssaidi@eecs.umich.edu//
683943Sbinkertn@umich.edu// These macros are streamlined to use in serialize/unserialize
693914Ssaidi@eecs.umich.edu// functions.  It's assumed that serialize() has a parameter 'os' for
703914Ssaidi@eecs.umich.edu// the ostream, and unserialize() has parameters 'cp' and 'section'.
713914Ssaidi@eecs.umich.edu#define SERIALIZE_SCALAR(scalar)	paramOut(os, #scalar, scalar)
723914Ssaidi@eecs.umich.edu
733914Ssaidi@eecs.umich.edu#define UNSERIALIZE_SCALAR(scalar)	paramIn(cp, section, #scalar, scalar)
743914Ssaidi@eecs.umich.edu
753914Ssaidi@eecs.umich.edu// ENUMs are like SCALARs, but we cast them to ints on the way out
763914Ssaidi@eecs.umich.edu#define SERIALIZE_ENUM(scalar)		paramOut(os, #scalar, (int)scalar)
773914Ssaidi@eecs.umich.edu
783914Ssaidi@eecs.umich.edu#define UNSERIALIZE_ENUM(scalar)		\
793914Ssaidi@eecs.umich.edu do {						\
803914Ssaidi@eecs.umich.edu    int tmp;					\
813914Ssaidi@eecs.umich.edu    paramIn(cp, section, #scalar, tmp);		\
823914Ssaidi@eecs.umich.edu    scalar = (typeof(scalar))tmp;		\
833914Ssaidi@eecs.umich.edu  } while (0)
843914Ssaidi@eecs.umich.edu
853914Ssaidi@eecs.umich.edu#define SERIALIZE_ARRAY(member, size)	\
863914Ssaidi@eecs.umich.edu        arrayParamOut(os, #member, member, size)
873914Ssaidi@eecs.umich.edu
883914Ssaidi@eecs.umich.edu#define UNSERIALIZE_ARRAY(member, size)	\
893914Ssaidi@eecs.umich.edu        arrayParamIn(cp, section, #member, member, size)
903914Ssaidi@eecs.umich.edu
913914Ssaidi@eecs.umich.edu#define SERIALIZE_OBJPTR(objptr)	paramOut(os, #objptr, (objptr)->name())
923914Ssaidi@eecs.umich.edu
933914Ssaidi@eecs.umich.edu#define UNSERIALIZE_OBJPTR(objptr)			\
943990Ssaidi@eecs.umich.edu  do {							\
953990Ssaidi@eecs.umich.edu    Serializable *sptr;				\
963990Ssaidi@eecs.umich.edu    objParamIn(cp, section, #objptr, sptr);		\
973990Ssaidi@eecs.umich.edu    objptr = dynamic_cast<typeof(objptr)>(sptr);	\
983990Ssaidi@eecs.umich.edu  } while (0)
993990Ssaidi@eecs.umich.edu
1003990Ssaidi@eecs.umich.edu/*
1013990Ssaidi@eecs.umich.edu * Basic support for object serialization.
1023990Ssaidi@eecs.umich.edu */
1033990Ssaidi@eecs.umich.educlass Serializable
1043990Ssaidi@eecs.umich.edu{
1053990Ssaidi@eecs.umich.edu  protected:
1064762Snate@binkert.org    void nameOut(std::ostream &os);
1074762Snate@binkert.org    void nameOut(std::ostream &os, const std::string &_name);
1083914Ssaidi@eecs.umich.edu
1094762Snate@binkert.org  public:
1103914Ssaidi@eecs.umich.edu    Serializable() {}
111    virtual ~Serializable() {}
112
113    // manditory virtual function, so objects must provide names
114    virtual const std::string name() const = 0;
115
116    virtual void serialize(std::ostream &os) {}
117    virtual void unserialize(Checkpoint *cp, const std::string &section) {}
118
119    static Serializable *create(Checkpoint *cp,
120                                 const std::string &section);
121
122    static int count;
123    static int maxCount;
124    static void serializeAll();
125    static void unserializeGlobals(Checkpoint *cp);
126};
127
128//
129// A SerializableBuilder serves as an evaluation context for a set of
130// parameters that describe a specific instance of a Serializable.  This
131// evaluation context corresponds to a section in the .ini file (as
132// with the base ParamContext) plus an optional node in the
133// configuration hierarchy (the configNode member) for resolving
134// Serializable references.  SerializableBuilder is an abstract superclass;
135// derived classes specialize the class for particular subclasses of
136// Serializable (e.g., BaseCache).
137//
138// For typical usage, see the definition of
139// SerializableClass::createObject().
140//
141class SerializableBuilder
142{
143  public:
144
145    SerializableBuilder() {}
146
147    virtual ~SerializableBuilder() {}
148
149    // Create the actual Serializable corresponding to the parameter
150    // values in this context.  This function is overridden in derived
151    // classes to call a specific constructor for a particular
152    // subclass of Serializable.
153    virtual Serializable *create() = 0;
154};
155
156//
157// An instance of SerializableClass corresponds to a class derived from
158// Serializable.  The SerializableClass instance serves to bind the string
159// name (found in the config file) to a function that creates an
160// instance of the appropriate derived class.
161//
162// This would be much cleaner in Smalltalk or Objective-C, where types
163// are first-class objects themselves.
164//
165class SerializableClass
166{
167  public:
168
169    // Type CreateFunc is a pointer to a function that creates a new
170    // simulation object builder based on a .ini-file parameter
171    // section (specified by the first string argument), a unique name
172    // for the object (specified by the second string argument), and
173    // an optional config hierarchy node (specified by the third
174    // argument).  A pointer to the new SerializableBuilder is returned.
175    typedef Serializable *(*CreateFunc)(Checkpoint *cp,
176                                         const std::string &section);
177
178    static std::map<std::string,CreateFunc> *classMap;
179
180    // Constructor.  For example:
181    //
182    // SerializableClass baseCacheSerializableClass("BaseCacheSerializable",
183    //                         newBaseCacheSerializableBuilder);
184    //
185    SerializableClass(const std::string &className, CreateFunc createFunc);
186
187    // create Serializable given name of class and pointer to
188    // configuration hierarchy node
189    static Serializable *createObject(Checkpoint *cp,
190                                       const std::string &section);
191};
192
193//
194// Macros to encapsulate the magic of declaring & defining
195// SerializableBuilder and SerializableClass objects
196//
197
198#define REGISTER_SERIALIZEABLE(CLASS_NAME, OBJ_CLASS)			   \
199SerializableClass the##OBJ_CLASS##Class(CLASS_NAME,			   \
200                                         OBJ_CLASS::createForUnserialize);
201
202class Checkpoint
203{
204  private:
205
206    IniFile *db;
207    const std::string basePath;
208    const ConfigNode *configNode;
209    std::map<std::string, Serializable*> objMap;
210
211  public:
212    Checkpoint(const std::string &cpt_dir, const std::string &path,
213               const ConfigNode *_configNode);
214
215    const std::string cptDir;
216
217    bool find(const std::string &section, const std::string &entry,
218              std::string &value);
219
220    bool findObj(const std::string &section, const std::string &entry,
221                 Serializable *&value);
222
223    bool sectionExists(const std::string &section);
224
225    // The following static functions have to do with checkpoint
226    // creation rather than restoration.  This class makes a handy
227    // namespace for them though.
228
229    // Export current checkpoint directory name so other objects can
230    // derive filenames from it (e.g., memory).  The return value is
231    // guaranteed to end in '/' so filenames can be directly appended.
232    // This function is only valid while a checkpoint is being created.
233    static std::string dir();
234
235    // Filename for base checkpoint file within directory.
236    static const char *baseFilename;
237
238    // Set up a checkpoint creation event or series of events.
239    static void setup(Tick when, Tick period = 0);
240};
241
242#endif // __SERIALIZE_HH__
243