serialize.cc revision 4841
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#include <sys/time.h> 34363SN/A#include <sys/types.h> 35363SN/A#include <sys/stat.h> 361354SN/A#include <errno.h> 372SN/A 382SN/A#include <fstream> 392SN/A#include <list> 402SN/A#include <string> 412SN/A#include <vector> 422SN/A 434841Ssaidi@eecs.umich.edu#include "base/annotate.hh" 44363SN/A#include "base/inifile.hh" 4556SN/A#include "base/misc.hh" 461388SN/A#include "base/output.hh" 47217SN/A#include "base/str.hh" 48363SN/A#include "base/trace.hh" 4956SN/A#include "sim/eventq.hh" 5056SN/A#include "sim/serialize.hh" 5156SN/A#include "sim/sim_events.hh" 521638SN/A#include "sim/sim_exit.hh" 5356SN/A#include "sim/sim_object.hh" 542SN/A 552356SN/A// For stat reset hack 562356SN/A#include "sim/stat_control.hh" 572356SN/A 582SN/Ausing namespace std; 592SN/A 604000Ssaidi@eecs.umich.eduextern SimObject *resolveSimObject(const string &); 614000Ssaidi@eecs.umich.edu 624762Snate@binkert.org// 634762Snate@binkert.org// The base implementations use to_number for parsing and '<<' for 644762Snate@binkert.org// displaying, suitable for integer types. 654762Snate@binkert.org// 664762Snate@binkert.orgtemplate <class T> 674762Snate@binkert.orgbool 684762Snate@binkert.orgparseParam(const string &s, T &value) 694762Snate@binkert.org{ 704762Snate@binkert.org return to_number(s, value); 714762Snate@binkert.org} 724762Snate@binkert.org 734762Snate@binkert.orgtemplate <class T> 744762Snate@binkert.orgvoid 754762Snate@binkert.orgshowParam(ostream &os, const T &value) 764762Snate@binkert.org{ 774762Snate@binkert.org os << value; 784762Snate@binkert.org} 794762Snate@binkert.org 804762Snate@binkert.org// 814762Snate@binkert.org// Template specializations: 824762Snate@binkert.org// - char (8-bit integer) 834762Snate@binkert.org// - floating-point types 844762Snate@binkert.org// - bool 854762Snate@binkert.org// - string 864762Snate@binkert.org// 874762Snate@binkert.org 884762Snate@binkert.org// Treat 8-bit ints (chars) as ints on output, not as chars 894762Snate@binkert.orgtemplate <> 904762Snate@binkert.orgvoid 914762Snate@binkert.orgshowParam(ostream &os, const char &value) 924762Snate@binkert.org{ 934762Snate@binkert.org os << (int)value; 944762Snate@binkert.org} 954762Snate@binkert.org 964762Snate@binkert.org 974762Snate@binkert.orgtemplate <> 984762Snate@binkert.orgvoid 994762Snate@binkert.orgshowParam(ostream &os, const unsigned char &value) 1004762Snate@binkert.org{ 1014762Snate@binkert.org os << (unsigned int)value; 1024762Snate@binkert.org} 1034762Snate@binkert.org 1044762Snate@binkert.org 1054762Snate@binkert.org// Use sscanf() for FP types as to_number() only handles integers 1064762Snate@binkert.orgtemplate <> 1074762Snate@binkert.orgbool 1084762Snate@binkert.orgparseParam(const string &s, float &value) 1094762Snate@binkert.org{ 1104762Snate@binkert.org return (sscanf(s.c_str(), "%f", &value) == 1); 1114762Snate@binkert.org} 1124762Snate@binkert.org 1134762Snate@binkert.orgtemplate <> 1144762Snate@binkert.orgbool 1154762Snate@binkert.orgparseParam(const string &s, double &value) 1164762Snate@binkert.org{ 1174762Snate@binkert.org return (sscanf(s.c_str(), "%lf", &value) == 1); 1184762Snate@binkert.org} 1194762Snate@binkert.org 1204762Snate@binkert.orgtemplate <> 1214762Snate@binkert.orgbool 1224762Snate@binkert.orgparseParam(const string &s, bool &value) 1234762Snate@binkert.org{ 1244762Snate@binkert.org const string &ls = to_lower(s); 1254762Snate@binkert.org 1264762Snate@binkert.org if (ls == "true") { 1274762Snate@binkert.org value = true; 1284762Snate@binkert.org return true; 1294762Snate@binkert.org } 1304762Snate@binkert.org 1314762Snate@binkert.org if (ls == "false") { 1324762Snate@binkert.org value = false; 1334762Snate@binkert.org return true; 1344762Snate@binkert.org } 1354762Snate@binkert.org 1364762Snate@binkert.org return false; 1374762Snate@binkert.org} 1384762Snate@binkert.org 1394762Snate@binkert.org// Display bools as strings 1404762Snate@binkert.orgtemplate <> 1414762Snate@binkert.orgvoid 1424762Snate@binkert.orgshowParam(ostream &os, const bool &value) 1434762Snate@binkert.org{ 1444762Snate@binkert.org os << (value ? "true" : "false"); 1454762Snate@binkert.org} 1464762Snate@binkert.org 1474762Snate@binkert.org 1484762Snate@binkert.org// String requires no processing to speak of 1494762Snate@binkert.orgtemplate <> 1504762Snate@binkert.orgbool 1514762Snate@binkert.orgparseParam(const string &s, string &value) 1524762Snate@binkert.org{ 1534762Snate@binkert.org value = s; 1544762Snate@binkert.org return true; 1554762Snate@binkert.org} 1564762Snate@binkert.org 1572287SN/Aint Serializable::ckptMaxCount = 0; 1582287SN/Aint Serializable::ckptCount = 0; 1592287SN/Aint Serializable::ckptPrevCount = -1; 1601637SN/A 1612SN/Avoid 162395SN/ASerializable::nameOut(ostream &os) 1632SN/A{ 164217SN/A os << "\n[" << name() << "]\n"; 1652SN/A} 1662SN/A 1672SN/Avoid 168395SN/ASerializable::nameOut(ostream &os, const string &_name) 1692SN/A{ 170217SN/A os << "\n[" << _name << "]\n"; 1712SN/A} 1722SN/A 173217SN/Atemplate <class T> 1742SN/Avoid 175502SN/AparamOut(ostream &os, const std::string &name, const T ¶m) 1762SN/A{ 177217SN/A os << name << "="; 178217SN/A showParam(os, param); 179217SN/A os << "\n"; 1802SN/A} 1812SN/A 1824841Ssaidi@eecs.umich.edutemplate <class T> 1834841Ssaidi@eecs.umich.eduvoid 1844841Ssaidi@eecs.umich.eduarrayParamOut(ostream &os, const std::string &name, 1854841Ssaidi@eecs.umich.edu const std::vector<T> ¶m) 1864841Ssaidi@eecs.umich.edu{ 1874841Ssaidi@eecs.umich.edu int size = param.size(); 1884841Ssaidi@eecs.umich.edu os << name << "="; 1894841Ssaidi@eecs.umich.edu if (size > 0) 1904841Ssaidi@eecs.umich.edu showParam(os, param[0]); 1914841Ssaidi@eecs.umich.edu for (int i = 1; i < size; ++i) { 1924841Ssaidi@eecs.umich.edu os << " "; 1934841Ssaidi@eecs.umich.edu showParam(os, param[i]); 1944841Ssaidi@eecs.umich.edu } 1954841Ssaidi@eecs.umich.edu os << "\n"; 1964841Ssaidi@eecs.umich.edu} 1974841Ssaidi@eecs.umich.edu 198217SN/A 199217SN/Atemplate <class T> 200217SN/Avoid 201237SN/AparamIn(Checkpoint *cp, const std::string §ion, 202502SN/A const std::string &name, T ¶m) 2032SN/A{ 204217SN/A std::string str; 205237SN/A if (!cp->find(section, name, str) || !parseParam(str, param)) { 206217SN/A fatal("Can't unserialize '%s:%s'\n", section, name); 207217SN/A } 2082SN/A} 2092SN/A 210217SN/A 211217SN/Atemplate <class T> 212217SN/Avoid 213217SN/AarrayParamOut(ostream &os, const std::string &name, 214217SN/A const T *param, int size) 215217SN/A{ 216217SN/A os << name << "="; 217217SN/A if (size > 0) 218217SN/A showParam(os, param[0]); 219217SN/A for (int i = 1; i < size; ++i) { 220217SN/A os << " "; 221217SN/A showParam(os, param[i]); 222217SN/A } 223217SN/A os << "\n"; 224217SN/A} 225217SN/A 226217SN/A 227217SN/Atemplate <class T> 228217SN/Avoid 229237SN/AarrayParamIn(Checkpoint *cp, const std::string §ion, 230217SN/A const std::string &name, T *param, int size) 231217SN/A{ 232217SN/A std::string str; 233237SN/A if (!cp->find(section, name, str)) { 234217SN/A fatal("Can't unserialize '%s:%s'\n", section, name); 235217SN/A } 236217SN/A 237217SN/A // code below stolen from VectorParam<T>::parse(). 238217SN/A // it would be nice to unify these somehow... 239217SN/A 240217SN/A vector<string> tokens; 241217SN/A 242217SN/A tokenize(tokens, str, ' '); 243217SN/A 244217SN/A // Need this if we were doing a vector 245217SN/A // value.resize(tokens.size()); 246217SN/A 247217SN/A if (tokens.size() != size) { 248217SN/A fatal("Array size mismatch on %s:%s'\n", section, name); 249217SN/A } 250217SN/A 251217SN/A for (int i = 0; i < tokens.size(); i++) { 252217SN/A // need to parse into local variable to handle vector<bool>, 253217SN/A // for which operator[] returns a special reference class 254217SN/A // that's not the same as 'bool&', (since it's a packed 255217SN/A // vector) 256217SN/A T scalar_value; 257217SN/A if (!parseParam(tokens[i], scalar_value)) { 258217SN/A string err("could not parse \""); 259217SN/A 260217SN/A err += str; 261217SN/A err += "\""; 262217SN/A 263217SN/A fatal(err); 264217SN/A } 265217SN/A 266217SN/A // assign parsed value to vector 267217SN/A param[i] = scalar_value; 268217SN/A } 269217SN/A} 270217SN/A 2714841Ssaidi@eecs.umich.edutemplate <class T> 2724841Ssaidi@eecs.umich.eduvoid 2734841Ssaidi@eecs.umich.eduarrayParamIn(Checkpoint *cp, const std::string §ion, 2744841Ssaidi@eecs.umich.edu const std::string &name, std::vector<T> ¶m) 2754841Ssaidi@eecs.umich.edu{ 2764841Ssaidi@eecs.umich.edu std::string str; 2774841Ssaidi@eecs.umich.edu if (!cp->find(section, name, str)) { 2784841Ssaidi@eecs.umich.edu fatal("Can't unserialize '%s:%s'\n", section, name); 2794841Ssaidi@eecs.umich.edu } 2804841Ssaidi@eecs.umich.edu 2814841Ssaidi@eecs.umich.edu // code below stolen from VectorParam<T>::parse(). 2824841Ssaidi@eecs.umich.edu // it would be nice to unify these somehow... 2834841Ssaidi@eecs.umich.edu 2844841Ssaidi@eecs.umich.edu vector<string> tokens; 2854841Ssaidi@eecs.umich.edu 2864841Ssaidi@eecs.umich.edu tokenize(tokens, str, ' '); 2874841Ssaidi@eecs.umich.edu 2884841Ssaidi@eecs.umich.edu // Need this if we were doing a vector 2894841Ssaidi@eecs.umich.edu // value.resize(tokens.size()); 2904841Ssaidi@eecs.umich.edu 2914841Ssaidi@eecs.umich.edu param.resize(tokens.size()); 2924841Ssaidi@eecs.umich.edu 2934841Ssaidi@eecs.umich.edu for (int i = 0; i < tokens.size(); i++) { 2944841Ssaidi@eecs.umich.edu // need to parse into local variable to handle vector<bool>, 2954841Ssaidi@eecs.umich.edu // for which operator[] returns a special reference class 2964841Ssaidi@eecs.umich.edu // that's not the same as 'bool&', (since it's a packed 2974841Ssaidi@eecs.umich.edu // vector) 2984841Ssaidi@eecs.umich.edu T scalar_value; 2994841Ssaidi@eecs.umich.edu if (!parseParam(tokens[i], scalar_value)) { 3004841Ssaidi@eecs.umich.edu string err("could not parse \""); 3014841Ssaidi@eecs.umich.edu 3024841Ssaidi@eecs.umich.edu err += str; 3034841Ssaidi@eecs.umich.edu err += "\""; 3044841Ssaidi@eecs.umich.edu 3054841Ssaidi@eecs.umich.edu fatal(err); 3064841Ssaidi@eecs.umich.edu } 3074841Ssaidi@eecs.umich.edu 3084841Ssaidi@eecs.umich.edu // assign parsed value to vector 3094841Ssaidi@eecs.umich.edu param[i] = scalar_value; 3104841Ssaidi@eecs.umich.edu } 3114841Ssaidi@eecs.umich.edu} 3124841Ssaidi@eecs.umich.edu 3134841Ssaidi@eecs.umich.edu 314217SN/A 315237SN/Avoid 316237SN/AobjParamIn(Checkpoint *cp, const std::string §ion, 3174000Ssaidi@eecs.umich.edu const std::string &name, SimObject * ¶m) 318237SN/A{ 319237SN/A if (!cp->findObj(section, name, param)) { 320237SN/A fatal("Can't unserialize '%s:%s'\n", section, name); 321237SN/A } 322237SN/A} 323237SN/A 324237SN/A 325221SN/A#define INSTANTIATE_PARAM_TEMPLATES(type) \ 326221SN/Atemplate void \ 327237SN/AparamOut(ostream &os, const std::string &name, type const ¶m); \ 328221SN/Atemplate void \ 329237SN/AparamIn(Checkpoint *cp, const std::string §ion, \ 330221SN/A const std::string &name, type & param); \ 331221SN/Atemplate void \ 332221SN/AarrayParamOut(ostream &os, const std::string &name, \ 333237SN/A type const *param, int size); \ 334221SN/Atemplate void \ 335237SN/AarrayParamIn(Checkpoint *cp, const std::string §ion, \ 3364841Ssaidi@eecs.umich.edu const std::string &name, type *param, int size); \ 3374841Ssaidi@eecs.umich.edutemplate void \ 3384841Ssaidi@eecs.umich.eduarrayParamOut(ostream &os, const std::string &name, \ 3394841Ssaidi@eecs.umich.edu const std::vector<type> ¶m); \ 3404841Ssaidi@eecs.umich.edutemplate void \ 3414841Ssaidi@eecs.umich.eduarrayParamIn(Checkpoint *cp, const std::string §ion, \ 3424841Ssaidi@eecs.umich.edu const std::string &name, std::vector<type> ¶m); 343217SN/A 3441642SN/AINSTANTIATE_PARAM_TEMPLATES(signed char) 3451642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned char) 3461642SN/AINSTANTIATE_PARAM_TEMPLATES(signed short) 3471642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned short) 3481642SN/AINSTANTIATE_PARAM_TEMPLATES(signed int) 3491642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned int) 3501642SN/AINSTANTIATE_PARAM_TEMPLATES(signed long) 3511642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned long) 3521642SN/AINSTANTIATE_PARAM_TEMPLATES(signed long long) 3531642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned long long) 354219SN/AINSTANTIATE_PARAM_TEMPLATES(bool) 355217SN/AINSTANTIATE_PARAM_TEMPLATES(string) 356217SN/A 357217SN/A 358395SN/A///////////////////////////// 359395SN/A 360395SN/A/// Container for serializing global variables (not associated with 361395SN/A/// any serialized object). 362395SN/Aclass Globals : public Serializable 3632SN/A{ 364395SN/A public: 365512SN/A const string name() const; 366510SN/A void serialize(ostream &os); 367395SN/A void unserialize(Checkpoint *cp); 368395SN/A}; 3692SN/A 370395SN/A/// The one and only instance of the Globals class. 371395SN/AGlobals globals; 3722SN/A 373512SN/Aconst string 374395SN/AGlobals::name() const 3752SN/A{ 376395SN/A return "Globals"; 3772SN/A} 3782SN/A 3792SN/Avoid 380510SN/AGlobals::serialize(ostream &os) 3812SN/A{ 382395SN/A nameOut(os); 383395SN/A SERIALIZE_SCALAR(curTick); 384395SN/A 385395SN/A nameOut(os, "MainEventQueue"); 386395SN/A mainEventQueue.serialize(os); 3872SN/A} 3882SN/A 3892SN/Avoid 390395SN/AGlobals::unserialize(Checkpoint *cp) 3912SN/A{ 392395SN/A const string §ion = name(); 393395SN/A UNSERIALIZE_SCALAR(curTick); 3942SN/A 395395SN/A mainEventQueue.unserialize(cp, "MainEventQueue"); 3962SN/A} 3972SN/A 3982SN/Avoid 3992868Sktlim@umich.eduSerializable::serializeAll(const std::string &cpt_dir) 4002SN/A{ 4012868Sktlim@umich.edu setCheckpointDir(cpt_dir); 402449SN/A string dir = Checkpoint::dir(); 403363SN/A if (mkdir(dir.c_str(), 0775) == -1 && errno != EEXIST) 404449SN/A fatal("couldn't mkdir %s\n", dir); 405363SN/A 406449SN/A string cpt_file = dir + Checkpoint::baseFilename; 407395SN/A ofstream outstream(cpt_file.c_str()); 4082SN/A time_t t = time(NULL); 409395SN/A outstream << "// checkpoint generated: " << ctime(&t); 4102SN/A 411395SN/A globals.serialize(outstream); 4124841Ssaidi@eecs.umich.edu Annotate::annotations.serialize(outstream); 413395SN/A SimObject::serializeAll(outstream); 414395SN/A} 4152SN/A 4162797Sktlim@umich.eduvoid 4172868Sktlim@umich.eduSerializable::unserializeAll(const std::string &cpt_dir) 4182797Sktlim@umich.edu{ 4192868Sktlim@umich.edu setCheckpointDir(cpt_dir); 4202797Sktlim@umich.edu string dir = Checkpoint::dir(); 4212797Sktlim@umich.edu string cpt_file = dir + Checkpoint::baseFilename; 4222797Sktlim@umich.edu string section = ""; 4232797Sktlim@umich.edu 4242797Sktlim@umich.edu DPRINTFR(Config, "Loading checkpoint dir '%s'\n", 4252797Sktlim@umich.edu dir); 4262797Sktlim@umich.edu Checkpoint *cp = new Checkpoint(dir, section); 4272797Sktlim@umich.edu unserializeGlobals(cp); 4284841Ssaidi@eecs.umich.edu Annotate::annotations.unserialize(cp); 4292797Sktlim@umich.edu SimObject::unserializeAll(cp); 4302797Sktlim@umich.edu} 4312SN/A 432395SN/Avoid 433395SN/ASerializable::unserializeGlobals(Checkpoint *cp) 434395SN/A{ 435395SN/A globals.unserialize(cp); 436395SN/A} 4372SN/A 438449SN/Aconst char *Checkpoint::baseFilename = "m5.cpt"; 439449SN/A 440449SN/Astatic string checkpointDirBase; 441294SN/A 4422797Sktlim@umich.eduvoid 4432797Sktlim@umich.edusetCheckpointDir(const std::string &name) 4442797Sktlim@umich.edu{ 4452797Sktlim@umich.edu checkpointDirBase = name; 4462797Sktlim@umich.edu if (checkpointDirBase[checkpointDirBase.size() - 1] != '/') 4472797Sktlim@umich.edu checkpointDirBase += "/"; 4482797Sktlim@umich.edu} 4492797Sktlim@umich.edu 450294SN/Astring 451449SN/ACheckpoint::dir() 452294SN/A{ 453449SN/A // use csprintf to insert curTick into directory name if it 454449SN/A // appears to have a format placeholder in it. 455449SN/A return (checkpointDirBase.find("%") != string::npos) ? 456449SN/A csprintf(checkpointDirBase, curTick) : checkpointDirBase; 4572SN/A} 4582SN/A 4592SN/Avoid 4602868Sktlim@umich.edudebug_serialize(const std::string &cpt_dir) 4612SN/A{ 4622868Sktlim@umich.edu Serializable::serializeAll(cpt_dir); 4632SN/A} 4642SN/A 4652SN/A 4662SN/A//////////////////////////////////////////////////////////////////////// 4672SN/A// 468395SN/A// SerializableClass member definitions 4692SN/A// 4702SN/A//////////////////////////////////////////////////////////////////////// 4712SN/A 472395SN/A// Map of class names to SerializableBuilder creation functions. 4732SN/A// Need to make this a pointer so we can force initialization on the 474395SN/A// first reference; otherwise, some SerializableClass constructors 4752SN/A// may be invoked before the classMap constructor. 476395SN/Amap<string,SerializableClass::CreateFunc> *SerializableClass::classMap = 0; 4772SN/A 478395SN/A// SerializableClass constructor: add mapping to classMap 479395SN/ASerializableClass::SerializableClass(const string &className, 4802SN/A CreateFunc createFunc) 4812SN/A{ 4822SN/A if (classMap == NULL) 483395SN/A classMap = new map<string,SerializableClass::CreateFunc>(); 4842SN/A 4852SN/A if ((*classMap)[className]) 4862SN/A { 4872SN/A cerr << "Error: simulation object class " << className << " redefined" 4882SN/A << endl; 4892SN/A fatal(""); 4902SN/A } 4912SN/A 4922SN/A // add className --> createFunc to class map 4932SN/A (*classMap)[className] = createFunc; 4942SN/A} 4952SN/A 4962SN/A 4972SN/A// 4982SN/A// 499395SN/ASerializable * 500395SN/ASerializableClass::createObject(Checkpoint *cp, 501237SN/A const std::string §ion) 5022SN/A{ 503237SN/A string className; 5042SN/A 505237SN/A if (!cp->find(section, "type", className)) { 506395SN/A fatal("Serializable::create: no 'type' entry in section '%s'.\n", 507237SN/A section); 5082SN/A } 5092SN/A 510237SN/A CreateFunc createFunc = (*classMap)[className]; 511237SN/A 512237SN/A if (createFunc == NULL) { 513395SN/A fatal("Serializable::create: no create function for class '%s'.\n", 514237SN/A className); 5152SN/A } 5162SN/A 517395SN/A Serializable *object = createFunc(cp, section); 5182SN/A 5192SN/A assert(object != NULL); 5202SN/A 5212SN/A return object; 5222SN/A} 5232SN/A 524237SN/A 525395SN/ASerializable * 526395SN/ASerializable::create(Checkpoint *cp, const std::string §ion) 527237SN/A{ 528395SN/A Serializable *object = SerializableClass::createObject(cp, section); 529237SN/A object->unserialize(cp, section); 530237SN/A return object; 531237SN/A} 532237SN/A 533237SN/A 5342738Sstever@eecs.umich.eduCheckpoint::Checkpoint(const std::string &cpt_dir, const std::string &path) 5352738Sstever@eecs.umich.edu : db(new IniFile), basePath(path), cptDir(cpt_dir) 536237SN/A{ 537449SN/A string filename = cpt_dir + "/" + Checkpoint::baseFilename; 538237SN/A if (!db->load(filename)) { 539237SN/A fatal("Can't load checkpoint file '%s'\n", filename); 540237SN/A } 541237SN/A} 542237SN/A 543237SN/A 544237SN/Abool 545237SN/ACheckpoint::find(const std::string §ion, const std::string &entry, 546237SN/A std::string &value) 547237SN/A{ 548237SN/A return db->find(section, entry, value); 549237SN/A} 550237SN/A 551237SN/A 552237SN/Abool 553237SN/ACheckpoint::findObj(const std::string §ion, const std::string &entry, 5544000Ssaidi@eecs.umich.edu SimObject *&value) 555237SN/A{ 556237SN/A string path; 557237SN/A 558237SN/A if (!db->find(section, entry, path)) 559237SN/A return false; 560237SN/A 5614000Ssaidi@eecs.umich.edu value = resolveSimObject(path); 5624000Ssaidi@eecs.umich.edu return true; 563237SN/A} 564304SN/A 565304SN/A 566304SN/Abool 567304SN/ACheckpoint::sectionExists(const std::string §ion) 568304SN/A{ 569304SN/A return db->sectionExists(section); 570304SN/A} 571