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 ¶m); 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 §ion, 76502SN/A const std::string &name, T ¶m); 77217SN/A 7810459SAndreas.Sandberg@ARM.comtemplate <typename DataType, typename BitUnion> 7910459SAndreas.Sandberg@ARM.comvoid paramIn(Checkpoint *cp, const std::string §ion, 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 §ion, 886820SLisa.Hsu@amd.com const std::string &name, T ¶m); 896820SLisa.Hsu@amd.com 9010459SAndreas.Sandberg@ARM.comtemplate <typename DataType, typename BitUnion> 9110459SAndreas.Sandberg@ARM.combool optParamIn(Checkpoint *cp, const std::string §ion, 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> ¶m); 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> ¶m); 1097948SAli.Saidi@ARM.com 1107948SAli.Saidi@ARM.comtemplate <class T> 111237SN/Avoid arrayParamIn(Checkpoint *cp, const std::string §ion, 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 §ion, 1164841Ssaidi@eecs.umich.edu const std::string &name, std::vector<T> ¶m); 1174841Ssaidi@eecs.umich.edu 1187948SAli.Saidi@ARM.comtemplate <class T> 1197948SAli.Saidi@ARM.comvoid arrayParamIn(Checkpoint *cp, const std::string §ion, 1207948SAli.Saidi@ARM.com const std::string &name, std::list<T> ¶m); 1217948SAli.Saidi@ARM.com 122237SN/Avoid 123237SN/AobjParamIn(Checkpoint *cp, const std::string §ion, 1244000Ssaidi@eecs.umich.edu const std::string &name, SimObject * ¶m); 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 §ion); 196237SN/A 1975739Snate@binkert.org static Serializable *create(Checkpoint *cp, const std::string §ion); 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 §ion); 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 §ion); 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 §ion, const std::string &entry, 309237SN/A std::string &value); 310237SN/A 311237SN/A bool findObj(const std::string §ion, const std::string &entry, 3124000Ssaidi@eecs.umich.edu SimObject *&value); 313304SN/A 314304SN/A bool sectionExists(const std::string §ion); 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