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 &param)
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> &param)
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 &section,
202502SN/A        const std::string &name, T &param)
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 &section,
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 &section,
2744841Ssaidi@eecs.umich.edu             const std::string &name, std::vector<T> &param)
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 &section,
3174000Ssaidi@eecs.umich.edu           const std::string &name, SimObject * &param)
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 &param);	\
328221SN/Atemplate void								\
329237SN/AparamIn(Checkpoint *cp, const std::string &section,			\
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 &section,		\
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> &param);				\
3404841Ssaidi@eecs.umich.edutemplate void								\
3414841Ssaidi@eecs.umich.eduarrayParamIn(Checkpoint *cp, const std::string &section,		\
3424841Ssaidi@eecs.umich.edu             const std::string &name, std::vector<type> &param);
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 &section = 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 &section)
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 &section)
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 &section, 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 &section, 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 &section)
568304SN/A{
569304SN/A    return db->sectionExists(section);
570304SN/A}
571