serialize.hh revision 10453
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 466214Snate@binkert.org#include "base/types.hh" 472SN/A 482738Sstever@eecs.umich.educlass IniFile; 49395SN/Aclass Serializable; 50237SN/Aclass Checkpoint; 514000Ssaidi@eecs.umich.educlass SimObject; 529983Sstever@gmail.comclass EventQueue; 532SN/A 549048SAli.Saidi@ARM.com/** The current version of the checkpoint format. 559048SAli.Saidi@ARM.com * This should be incremented by 1 and only 1 for every new version, where a new 569056SAli.Saidi@ARM.com * version is defined as a checkpoint created before this version won't work on 579048SAli.Saidi@ARM.com * the current version until the checkpoint format is updated. Adding a new 589048SAli.Saidi@ARM.com * SimObject shouldn't cause the version number to increase, only changes to 599056SAli.Saidi@ARM.com * existing objects such as serializing/unserializing more state, changing sizes 609048SAli.Saidi@ARM.com * of serialized arrays, etc. */ 6110338SCurtis.Dunham@arm.comstatic const uint64_t gem5CheckpointVersion = 0x000000000000000d; 629048SAli.Saidi@ARM.com 63217SN/Atemplate <class T> 64502SN/Avoid paramOut(std::ostream &os, const std::string &name, const T ¶m); 65217SN/A 66217SN/Atemplate <class T> 67237SN/Avoid paramIn(Checkpoint *cp, const std::string §ion, 68502SN/A const std::string &name, T ¶m); 69217SN/A 70217SN/Atemplate <class T> 716820SLisa.Hsu@amd.combool optParamIn(Checkpoint *cp, const std::string §ion, 726820SLisa.Hsu@amd.com const std::string &name, T ¶m); 736820SLisa.Hsu@amd.com 746820SLisa.Hsu@amd.comtemplate <class T> 75217SN/Avoid arrayParamOut(std::ostream &os, const std::string &name, 766227Snate@binkert.org const T *param, unsigned size); 77217SN/A 78217SN/Atemplate <class T> 794841Ssaidi@eecs.umich.eduvoid arrayParamOut(std::ostream &os, const std::string &name, 804841Ssaidi@eecs.umich.edu const std::vector<T> ¶m); 814841Ssaidi@eecs.umich.edu 824841Ssaidi@eecs.umich.edutemplate <class T> 837948SAli.Saidi@ARM.comvoid arrayParamOut(std::ostream &os, const std::string &name, 847948SAli.Saidi@ARM.com const std::list<T> ¶m); 857948SAli.Saidi@ARM.com 867948SAli.Saidi@ARM.comtemplate <class T> 87237SN/Avoid arrayParamIn(Checkpoint *cp, const std::string §ion, 886227Snate@binkert.org const std::string &name, T *param, unsigned size); 89217SN/A 904841Ssaidi@eecs.umich.edutemplate <class T> 914841Ssaidi@eecs.umich.eduvoid arrayParamIn(Checkpoint *cp, const std::string §ion, 924841Ssaidi@eecs.umich.edu const std::string &name, std::vector<T> ¶m); 934841Ssaidi@eecs.umich.edu 947948SAli.Saidi@ARM.comtemplate <class T> 957948SAli.Saidi@ARM.comvoid arrayParamIn(Checkpoint *cp, const std::string §ion, 967948SAli.Saidi@ARM.com const std::string &name, std::list<T> ¶m); 977948SAli.Saidi@ARM.com 98237SN/Avoid 99237SN/AobjParamIn(Checkpoint *cp, const std::string §ion, 1004000Ssaidi@eecs.umich.edu const std::string &name, SimObject * ¶m); 101237SN/A 1028902Sandreas.hansson@arm.comtemplate <typename T> 1038902Sandreas.hansson@arm.comvoid fromInt(T &t, int i) 1048902Sandreas.hansson@arm.com{ 1058902Sandreas.hansson@arm.com t = (T)i; 1068902Sandreas.hansson@arm.com} 1078902Sandreas.hansson@arm.com 1088902Sandreas.hansson@arm.comtemplate <typename T> 1098902Sandreas.hansson@arm.comvoid fromSimObject(T &t, SimObject *s) 1108902Sandreas.hansson@arm.com{ 1118902Sandreas.hansson@arm.com t = dynamic_cast<T>(s); 1128902Sandreas.hansson@arm.com} 113237SN/A 114217SN/A// 115217SN/A// These macros are streamlined to use in serialize/unserialize 116217SN/A// functions. It's assumed that serialize() has a parameter 'os' for 117237SN/A// the ostream, and unserialize() has parameters 'cp' and 'section'. 1185543Ssaidi@eecs.umich.edu#define SERIALIZE_SCALAR(scalar) paramOut(os, #scalar, scalar) 119217SN/A 1205543Ssaidi@eecs.umich.edu#define UNSERIALIZE_SCALAR(scalar) paramIn(cp, section, #scalar, scalar) 1216820SLisa.Hsu@amd.com#define UNSERIALIZE_OPT_SCALAR(scalar) optParamIn(cp, section, #scalar, scalar) 122217SN/A 123223SN/A// ENUMs are like SCALARs, but we cast them to ints on the way out 1245543Ssaidi@eecs.umich.edu#define SERIALIZE_ENUM(scalar) paramOut(os, #scalar, (int)scalar) 125223SN/A 1265543Ssaidi@eecs.umich.edu#define UNSERIALIZE_ENUM(scalar) \ 1275543Ssaidi@eecs.umich.edu do { \ 1285543Ssaidi@eecs.umich.edu int tmp; \ 1295543Ssaidi@eecs.umich.edu paramIn(cp, section, #scalar, tmp); \ 1308902Sandreas.hansson@arm.com fromInt(scalar, tmp); \ 131223SN/A } while (0) 132223SN/A 1335543Ssaidi@eecs.umich.edu#define SERIALIZE_ARRAY(member, size) \ 134217SN/A arrayParamOut(os, #member, member, size) 135217SN/A 1365543Ssaidi@eecs.umich.edu#define UNSERIALIZE_ARRAY(member, size) \ 137237SN/A arrayParamIn(cp, section, #member, member, size) 138237SN/A 1395543Ssaidi@eecs.umich.edu#define SERIALIZE_OBJPTR(objptr) paramOut(os, #objptr, (objptr)->name()) 140237SN/A 1415543Ssaidi@eecs.umich.edu#define UNSERIALIZE_OBJPTR(objptr) \ 1425543Ssaidi@eecs.umich.edu do { \ 1435543Ssaidi@eecs.umich.edu SimObject *sptr; \ 1445543Ssaidi@eecs.umich.edu objParamIn(cp, section, #objptr, sptr); \ 1458902Sandreas.hansson@arm.com fromSimObject(objptr, sptr); \ 146237SN/A } while (0) 147217SN/A 1489342SAndreas.Sandberg@arm.com/** 1492SN/A * Basic support for object serialization. 1509342SAndreas.Sandberg@arm.com * 1519342SAndreas.Sandberg@arm.com * @note Many objects that support serialization need to be put in a 1529342SAndreas.Sandberg@arm.com * consistent state when serialization takes place. We refer to the 1539342SAndreas.Sandberg@arm.com * action of forcing an object into a consistent state as 1549342SAndreas.Sandberg@arm.com * 'draining'. Objects that need draining inherit from Drainable. See 1559342SAndreas.Sandberg@arm.com * Drainable for more information. 1562SN/A */ 157395SN/Aclass Serializable 1582SN/A{ 1592SN/A protected: 160510SN/A void nameOut(std::ostream &os); 161510SN/A void nameOut(std::ostream &os, const std::string &_name); 1622SN/A 1632SN/A public: 1645739Snate@binkert.org Serializable(); 1655739Snate@binkert.org virtual ~Serializable(); 1662SN/A 167265SN/A // manditory virtual function, so objects must provide names 168512SN/A virtual const std::string name() const = 0; 1692SN/A 1705739Snate@binkert.org virtual void serialize(std::ostream &os); 1715739Snate@binkert.org virtual void unserialize(Checkpoint *cp, const std::string §ion); 172237SN/A 1735739Snate@binkert.org static Serializable *create(Checkpoint *cp, const std::string §ion); 1742SN/A 1752287SN/A static int ckptCount; 1762287SN/A static int ckptMaxCount; 1772287SN/A static int ckptPrevCount; 1782868Sktlim@umich.edu static void serializeAll(const std::string &cpt_dir); 179395SN/A static void unserializeGlobals(Checkpoint *cp); 1802SN/A}; 1812SN/A 1829554Sandreas.hansson@arm.comvoid debug_serialize(const std::string &cpt_dir); 1839554Sandreas.hansson@arm.com 1842SN/A// 185395SN/A// A SerializableBuilder serves as an evaluation context for a set of 186395SN/A// parameters that describe a specific instance of a Serializable. This 1872SN/A// evaluation context corresponds to a section in the .ini file (as 1882SN/A// with the base ParamContext) plus an optional node in the 1892SN/A// configuration hierarchy (the configNode member) for resolving 190395SN/A// Serializable references. SerializableBuilder is an abstract superclass; 1912SN/A// derived classes specialize the class for particular subclasses of 192395SN/A// Serializable (e.g., BaseCache). 1932SN/A// 1942SN/A// For typical usage, see the definition of 195395SN/A// SerializableClass::createObject(). 1962SN/A// 197395SN/Aclass SerializableBuilder 1982SN/A{ 1992SN/A public: 2002SN/A 201395SN/A SerializableBuilder() {} 2022SN/A 203395SN/A virtual ~SerializableBuilder() {} 2042SN/A 205395SN/A // Create the actual Serializable corresponding to the parameter 2062SN/A // values in this context. This function is overridden in derived 2072SN/A // classes to call a specific constructor for a particular 208395SN/A // subclass of Serializable. 209395SN/A virtual Serializable *create() = 0; 2102SN/A}; 2112SN/A 2122SN/A// 213395SN/A// An instance of SerializableClass corresponds to a class derived from 214395SN/A// Serializable. The SerializableClass instance serves to bind the string 2152SN/A// name (found in the config file) to a function that creates an 2162SN/A// instance of the appropriate derived class. 2172SN/A// 2182SN/A// This would be much cleaner in Smalltalk or Objective-C, where types 2192SN/A// are first-class objects themselves. 2202SN/A// 221395SN/Aclass SerializableClass 2222SN/A{ 2232SN/A public: 2242SN/A 2252SN/A // Type CreateFunc is a pointer to a function that creates a new 2262SN/A // simulation object builder based on a .ini-file parameter 2272SN/A // section (specified by the first string argument), a unique name 2282SN/A // for the object (specified by the second string argument), and 2292SN/A // an optional config hierarchy node (specified by the third 230395SN/A // argument). A pointer to the new SerializableBuilder is returned. 231395SN/A typedef Serializable *(*CreateFunc)(Checkpoint *cp, 2322738Sstever@eecs.umich.edu const std::string §ion); 2332SN/A 2342SN/A static std::map<std::string,CreateFunc> *classMap; 2352SN/A 2362SN/A // Constructor. For example: 2372SN/A // 238395SN/A // SerializableClass baseCacheSerializableClass("BaseCacheSerializable", 239395SN/A // newBaseCacheSerializableBuilder); 2402SN/A // 241395SN/A SerializableClass(const std::string &className, CreateFunc createFunc); 2422SN/A 243395SN/A // create Serializable given name of class and pointer to 2442SN/A // configuration hierarchy node 245395SN/A static Serializable *createObject(Checkpoint *cp, 2462738Sstever@eecs.umich.edu const std::string §ion); 2472SN/A}; 2482SN/A 2492SN/A// 2502SN/A// Macros to encapsulate the magic of declaring & defining 251395SN/A// SerializableBuilder and SerializableClass objects 2522SN/A// 2532SN/A 2545543Ssaidi@eecs.umich.edu#define REGISTER_SERIALIZEABLE(CLASS_NAME, OBJ_CLASS) \ 2555543Ssaidi@eecs.umich.eduSerializableClass the##OBJ_CLASS##Class(CLASS_NAME, \ 256237SN/A OBJ_CLASS::createForUnserialize); 2572SN/A 25810453SAndrew.Bardsley@arm.com// Base class to wrap object resolving functionality. This can be 25910453SAndrew.Bardsley@arm.com// provided to Checkpoint to allow it to map object names onto 26010453SAndrew.Bardsley@arm.com// object C++ objects in which to unserialize 26110453SAndrew.Bardsley@arm.comclass SimObjectResolver 26210453SAndrew.Bardsley@arm.com{ 26310453SAndrew.Bardsley@arm.com public: 26410453SAndrew.Bardsley@arm.com virtual ~SimObjectResolver() { } 26510453SAndrew.Bardsley@arm.com 26610453SAndrew.Bardsley@arm.com // Find a SimObject given a full path name 26710453SAndrew.Bardsley@arm.com virtual SimObject *resolveSimObject(const std::string &name) = 0; 26810453SAndrew.Bardsley@arm.com}; 26910453SAndrew.Bardsley@arm.com 270237SN/Aclass Checkpoint 271237SN/A{ 272237SN/A private: 273237SN/A 274237SN/A IniFile *db; 275237SN/A 27610453SAndrew.Bardsley@arm.com SimObjectResolver &objNameResolver; 27710453SAndrew.Bardsley@arm.com 278237SN/A public: 27910453SAndrew.Bardsley@arm.com Checkpoint(const std::string &cpt_dir, SimObjectResolver &resolver); 2809086Sandreas.hansson@arm.com ~Checkpoint(); 281237SN/A 282937SN/A const std::string cptDir; 283937SN/A 284237SN/A bool find(const std::string §ion, const std::string &entry, 285237SN/A std::string &value); 286237SN/A 287237SN/A bool findObj(const std::string §ion, const std::string &entry, 2884000Ssaidi@eecs.umich.edu SimObject *&value); 289304SN/A 290304SN/A bool sectionExists(const std::string §ion); 291449SN/A 292449SN/A // The following static functions have to do with checkpoint 293449SN/A // creation rather than restoration. This class makes a handy 2947491Ssteve.reinhardt@amd.com // namespace for them though. Currently no Checkpoint object is 2957491Ssteve.reinhardt@amd.com // created on serialization (only unserialization) so we track the 2967491Ssteve.reinhardt@amd.com // directory name as a global. It would be nice to change this 2977491Ssteve.reinhardt@amd.com // someday 2987491Ssteve.reinhardt@amd.com 2997491Ssteve.reinhardt@amd.com private: 3007491Ssteve.reinhardt@amd.com // current directory we're serializing into. 3017491Ssteve.reinhardt@amd.com static std::string currentDirectory; 3027491Ssteve.reinhardt@amd.com 3037491Ssteve.reinhardt@amd.com public: 3047491Ssteve.reinhardt@amd.com // Set the current directory. This function takes care of 3057823Ssteve.reinhardt@amd.com // inserting curTick() if there's a '%d' in the argument, and 3067491Ssteve.reinhardt@amd.com // appends a '/' if necessary. The final name is returned. 3077491Ssteve.reinhardt@amd.com static std::string setDir(const std::string &base_name); 308449SN/A 309449SN/A // Export current checkpoint directory name so other objects can 310449SN/A // derive filenames from it (e.g., memory). The return value is 311449SN/A // guaranteed to end in '/' so filenames can be directly appended. 312449SN/A // This function is only valid while a checkpoint is being created. 313449SN/A static std::string dir(); 314449SN/A 315449SN/A // Filename for base checkpoint file within directory. 316449SN/A static const char *baseFilename; 317237SN/A}; 3182SN/A 3192SN/A#endif // __SERIALIZE_HH__ 320