serialize.cc revision 502
11060SN/A/*
29814Sandreas.hansson@arm.com * Copyright (c) 2003 The Regents of The University of Michigan
39920Syasuko.eckert@amd.com * All rights reserved.
47944SGiacomo.Gabrielli@arm.com *
57944SGiacomo.Gabrielli@arm.com * Redistribution and use in source and binary forms, with or without
67944SGiacomo.Gabrielli@arm.com * modification, are permitted provided that the following conditions are
77944SGiacomo.Gabrielli@arm.com * met: redistributions of source code must retain the above copyright
87944SGiacomo.Gabrielli@arm.com * notice, this list of conditions and the following disclaimer;
97944SGiacomo.Gabrielli@arm.com * redistributions in binary form must reproduce the above copyright
107944SGiacomo.Gabrielli@arm.com * notice, this list of conditions and the following disclaimer in the
117944SGiacomo.Gabrielli@arm.com * documentation and/or other materials provided with the distribution;
127944SGiacomo.Gabrielli@arm.com * neither the name of the copyright holders nor the names of its
137944SGiacomo.Gabrielli@arm.com * contributors may be used to endorse or promote products derived from
147944SGiacomo.Gabrielli@arm.com * this software without specific prior written permission.
152702Sktlim@umich.edu *
166973Stjones1@inf.ed.ac.uk * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171060SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181060SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191060SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201060SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211060SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221060SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231060SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241060SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251060SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261060SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
271060SN/A */
281060SN/A
291060SN/A#include <sys/time.h>
301060SN/A#include <sys/types.h>
311060SN/A#include <sys/stat.h>
321060SN/A
331060SN/A#include <fstream>
341060SN/A#include <list>
351060SN/A#include <string>
361060SN/A#include <vector>
371060SN/A
381060SN/A#include "base/inifile.hh"
391060SN/A#include "base/misc.hh"
401060SN/A#include "base/str.hh"
412665Ssaidi@eecs.umich.edu#include "base/trace.hh"
422665Ssaidi@eecs.umich.edu#include "sim/config_node.hh"
436973Stjones1@inf.ed.ac.uk#include "sim/eventq.hh"
441060SN/A#include "sim/param.hh"
451060SN/A#include "sim/serialize.hh"
461464SN/A#include "sim/sim_events.hh"
471464SN/A#include "sim/sim_object.hh"
481060SN/A
492731Sktlim@umich.eduusing namespace std;
502292SN/A
511464SN/Avoid
528733Sgeoffrey.blake@arm.comSerializable::nameOut(ostream &os)
531060SN/A{
547720Sgblack@eecs.umich.edu    os << "\n[" << name() << "]\n";
551060SN/A}
566658Snate@binkert.org
578887Sgeoffrey.blake@arm.comvoid
583770Sgblack@eecs.umich.eduSerializable::nameOut(ostream &os, const string &_name)
5910319SAndreas.Sandberg@ARM.com{
601464SN/A    os << "\n[" << _name << "]\n";
611464SN/A}
622669Sktlim@umich.edu
631060SN/Atemplate <class T>
646973Stjones1@inf.ed.ac.ukvoid
652669Sktlim@umich.eduparamOut(ostream &os, const std::string &name, const T &param)
667678Sgblack@eecs.umich.edu{
672292SN/A    os << name << "=";
686023Snate@binkert.org    showParam(os, param);
691060SN/A    os << "\n";
701060SN/A}
711060SN/A
721060SN/A
731060SN/Atemplate <class T>
741060SN/Avoid
751060SN/AparamIn(Checkpoint *cp, const std::string &section,
7610319SAndreas.Sandberg@ARM.com        const std::string &name, T &param)
771060SN/A{
781060SN/A    std::string str;
791060SN/A    if (!cp->find(section, name, str) || !parseParam(str, param)) {
802733Sktlim@umich.edu        fatal("Can't unserialize '%s:%s'\n", section, name);
812733Sktlim@umich.edu    }
821060SN/A}
832292SN/A
842107SN/A
851060SN/Atemplate <class T>
862292SN/Avoid
872292SN/AarrayParamOut(ostream &os, const std::string &name,
888486Sgblack@eecs.umich.edu              const T *param, int size)
892292SN/A{
902292SN/A    os << name << "=";
912292SN/A    if (size > 0)
922292SN/A        showParam(os, param[0]);
931060SN/A    for (int i = 1; i < size; ++i) {
945543Ssaidi@eecs.umich.edu        os << " ";
958902Sandreas.hansson@arm.com        showParam(os, param[i]);
961060SN/A    }
971060SN/A    os << "\n";
989046SAli.Saidi@ARM.com}
999046SAli.Saidi@ARM.com
1009046SAli.Saidi@ARM.com
1019046SAli.Saidi@ARM.comtemplate <class T>
1029046SAli.Saidi@ARM.comvoid
1039046SAli.Saidi@ARM.comarrayParamIn(Checkpoint *cp, const std::string &section,
1049046SAli.Saidi@ARM.com             const std::string &name, T *param, int size)
1059046SAli.Saidi@ARM.com{
1069046SAli.Saidi@ARM.com    std::string str;
1079046SAli.Saidi@ARM.com    if (!cp->find(section, name, str)) {
1089046SAli.Saidi@ARM.com        fatal("Can't unserialize '%s:%s'\n", section, name);
1099046SAli.Saidi@ARM.com    }
1109046SAli.Saidi@ARM.com
1119046SAli.Saidi@ARM.com    // code below stolen from VectorParam<T>::parse().
1129046SAli.Saidi@ARM.com    // it would be nice to unify these somehow...
1139046SAli.Saidi@ARM.com
1149046SAli.Saidi@ARM.com    vector<string> tokens;
1159046SAli.Saidi@ARM.com
1169046SAli.Saidi@ARM.com    tokenize(tokens, str, ' ');
1179046SAli.Saidi@ARM.com
1189046SAli.Saidi@ARM.com    // Need this if we were doing a vector
1199046SAli.Saidi@ARM.com    // value.resize(tokens.size());
1209046SAli.Saidi@ARM.com
1219046SAli.Saidi@ARM.com    if (tokens.size() != size) {
1229046SAli.Saidi@ARM.com        fatal("Array size mismatch on %s:%s'\n", section, name);
1239046SAli.Saidi@ARM.com    }
1249046SAli.Saidi@ARM.com
1259046SAli.Saidi@ARM.com    for (int i = 0; i < tokens.size(); i++) {
1269046SAli.Saidi@ARM.com        // need to parse into local variable to handle vector<bool>,
1279046SAli.Saidi@ARM.com        // for which operator[] returns a special reference class
1289046SAli.Saidi@ARM.com        // that's not the same as 'bool&', (since it's a packed
1299046SAli.Saidi@ARM.com        // vector)
1309046SAli.Saidi@ARM.com        T scalar_value;
1319046SAli.Saidi@ARM.com        if (!parseParam(tokens[i], scalar_value)) {
1329046SAli.Saidi@ARM.com            string err("could not parse \"");
1339046SAli.Saidi@ARM.com
1349046SAli.Saidi@ARM.com            err += str;
1359046SAli.Saidi@ARM.com            err += "\"";
1369046SAli.Saidi@ARM.com
1379046SAli.Saidi@ARM.com            fatal(err);
1389046SAli.Saidi@ARM.com        }
1399046SAli.Saidi@ARM.com
1409046SAli.Saidi@ARM.com        // assign parsed value to vector
1419046SAli.Saidi@ARM.com        param[i] = scalar_value;
1429046SAli.Saidi@ARM.com    }
1439046SAli.Saidi@ARM.com}
1449046SAli.Saidi@ARM.com
1459046SAli.Saidi@ARM.com
1469046SAli.Saidi@ARM.comvoid
1479046SAli.Saidi@ARM.comobjParamIn(Checkpoint *cp, const std::string &section,
1489046SAli.Saidi@ARM.com           const std::string &name, Serializable * &param)
1499046SAli.Saidi@ARM.com{
1509046SAli.Saidi@ARM.com    if (!cp->findObj(section, name, param)) {
1519046SAli.Saidi@ARM.com        fatal("Can't unserialize '%s:%s'\n", section, name);
1529046SAli.Saidi@ARM.com    }
1539046SAli.Saidi@ARM.com}
1549046SAli.Saidi@ARM.com
1559046SAli.Saidi@ARM.com
1569046SAli.Saidi@ARM.com#define INSTANTIATE_PARAM_TEMPLATES(type)				\
1572292SN/Atemplate void								\
15810417Sandreas.hansson@arm.comparamOut(ostream &os, const std::string &name, type const &param);	\
1599046SAli.Saidi@ARM.comtemplate void								\
1609046SAli.Saidi@ARM.comparamIn(Checkpoint *cp, const std::string &section,			\
1619046SAli.Saidi@ARM.com        const std::string &name, type & param);				\
1629046SAli.Saidi@ARM.comtemplate void								\
16310030SAli.Saidi@ARM.comarrayParamOut(ostream &os, const std::string &name,			\
16410030SAli.Saidi@ARM.com              type const *param, int size);				\
1659046SAli.Saidi@ARM.comtemplate void								\
1669046SAli.Saidi@ARM.comarrayParamIn(Checkpoint *cp, const std::string &section,		\
1679046SAli.Saidi@ARM.com             const std::string &name, type *param, int size);
1689046SAli.Saidi@ARM.com
1699046SAli.Saidi@ARM.com
1709046SAli.Saidi@ARM.comINSTANTIATE_PARAM_TEMPLATES(int8_t)
1719046SAli.Saidi@ARM.comINSTANTIATE_PARAM_TEMPLATES(uint8_t)
1729046SAli.Saidi@ARM.comINSTANTIATE_PARAM_TEMPLATES(int16_t)
1739046SAli.Saidi@ARM.comINSTANTIATE_PARAM_TEMPLATES(uint16_t)
1749046SAli.Saidi@ARM.comINSTANTIATE_PARAM_TEMPLATES(int32_t)
1759046SAli.Saidi@ARM.comINSTANTIATE_PARAM_TEMPLATES(uint32_t)
1769046SAli.Saidi@ARM.comINSTANTIATE_PARAM_TEMPLATES(int64_t)
1779046SAli.Saidi@ARM.comINSTANTIATE_PARAM_TEMPLATES(uint64_t)
1789046SAli.Saidi@ARM.comINSTANTIATE_PARAM_TEMPLATES(bool)
1799046SAli.Saidi@ARM.comINSTANTIATE_PARAM_TEMPLATES(string)
1809046SAli.Saidi@ARM.com
1819046SAli.Saidi@ARM.com
1829046SAli.Saidi@ARM.com/////////////////////////////
1839046SAli.Saidi@ARM.com
1849046SAli.Saidi@ARM.com/// Container for serializing global variables (not associated with
1859046SAli.Saidi@ARM.com/// any serialized object).
1869046SAli.Saidi@ARM.comclass Globals : public Serializable
1879046SAli.Saidi@ARM.com{
1889046SAli.Saidi@ARM.com  public:
1899046SAli.Saidi@ARM.com    string name() const;
1909046SAli.Saidi@ARM.com    void serialize(ostream& os);
1919046SAli.Saidi@ARM.com    void unserialize(Checkpoint *cp);
1929046SAli.Saidi@ARM.com};
1939046SAli.Saidi@ARM.com
1949046SAli.Saidi@ARM.com/// The one and only instance of the Globals class.
1959046SAli.Saidi@ARM.comGlobals globals;
1969046SAli.Saidi@ARM.com
1979046SAli.Saidi@ARM.comstring
1989046SAli.Saidi@ARM.comGlobals::name() const
1999046SAli.Saidi@ARM.com{
2009046SAli.Saidi@ARM.com    return "Globals";
2019046SAli.Saidi@ARM.com}
2029046SAli.Saidi@ARM.com
2039046SAli.Saidi@ARM.comvoid
2049046SAli.Saidi@ARM.comGlobals::serialize(ostream& os)
2059046SAli.Saidi@ARM.com{
20610417Sandreas.hansson@arm.com    nameOut(os);
2071060SN/A    SERIALIZE_SCALAR(curTick);
2089046SAli.Saidi@ARM.com
2099046SAli.Saidi@ARM.com    nameOut(os, "MainEventQueue");
2109046SAli.Saidi@ARM.com    mainEventQueue.serialize(os);
2119046SAli.Saidi@ARM.com}
2129046SAli.Saidi@ARM.com
2139046SAli.Saidi@ARM.comvoid
2149046SAli.Saidi@ARM.comGlobals::unserialize(Checkpoint *cp)
2159046SAli.Saidi@ARM.com{
2169046SAli.Saidi@ARM.com    const string &section = name();
2179046SAli.Saidi@ARM.com    UNSERIALIZE_SCALAR(curTick);
2189046SAli.Saidi@ARM.com
2199046SAli.Saidi@ARM.com    mainEventQueue.unserialize(cp, "MainEventQueue");
2209046SAli.Saidi@ARM.com}
2219046SAli.Saidi@ARM.com
2229046SAli.Saidi@ARM.comvoid
2239046SAli.Saidi@ARM.comSerializable::serializeAll()
2249046SAli.Saidi@ARM.com{
2259046SAli.Saidi@ARM.com    string dir = Checkpoint::dir();
2269046SAli.Saidi@ARM.com    if (mkdir(dir.c_str(), 0775) == -1 && errno != EEXIST)
2279046SAli.Saidi@ARM.com            fatal("couldn't mkdir %s\n", dir);
2289046SAli.Saidi@ARM.com
2299046SAli.Saidi@ARM.com    string cpt_file = dir + Checkpoint::baseFilename;
2309046SAli.Saidi@ARM.com    ofstream outstream(cpt_file.c_str());
2319046SAli.Saidi@ARM.com    time_t t = time(NULL);
2329046SAli.Saidi@ARM.com    outstream << "// checkpoint generated: " << ctime(&t);
2339046SAli.Saidi@ARM.com
2349046SAli.Saidi@ARM.com    globals.serialize(outstream);
2359046SAli.Saidi@ARM.com    SimObject::serializeAll(outstream);
2369046SAli.Saidi@ARM.com}
2379046SAli.Saidi@ARM.com
2389046SAli.Saidi@ARM.com
2399046SAli.Saidi@ARM.comvoid
2409046SAli.Saidi@ARM.comSerializable::unserializeGlobals(Checkpoint *cp)
2419046SAli.Saidi@ARM.com{
2429046SAli.Saidi@ARM.com    globals.unserialize(cp);
2439046SAli.Saidi@ARM.com}
2449046SAli.Saidi@ARM.com
2459046SAli.Saidi@ARM.com
2469046SAli.Saidi@ARM.comclass SerializeEvent : public Event
2479046SAli.Saidi@ARM.com{
2489046SAli.Saidi@ARM.com  protected:
2499046SAli.Saidi@ARM.com    Tick repeat;
2509046SAli.Saidi@ARM.com
2519046SAli.Saidi@ARM.com  public:
2529046SAli.Saidi@ARM.com    SerializeEvent(Tick _when, Tick _repeat);
2539046SAli.Saidi@ARM.com    virtual void process();
2549046SAli.Saidi@ARM.com    virtual void serialize(std::ostream &os)
2559046SAli.Saidi@ARM.com    {
2569046SAli.Saidi@ARM.com        panic("Cannot serialize the SerializeEvent");
2579046SAli.Saidi@ARM.com    }
2589046SAli.Saidi@ARM.com
2599046SAli.Saidi@ARM.com};
2609046SAli.Saidi@ARM.com
2619046SAli.Saidi@ARM.comSerializeEvent::SerializeEvent(Tick _when, Tick _repeat)
2629046SAli.Saidi@ARM.com    : Event(&mainEventQueue, Serialize_Pri), repeat(_repeat)
2639046SAli.Saidi@ARM.com{
2649046SAli.Saidi@ARM.com    setFlags(AutoDelete);
2659046SAli.Saidi@ARM.com    schedule(_when);
2669046SAli.Saidi@ARM.com}
2679046SAli.Saidi@ARM.com
2689046SAli.Saidi@ARM.comvoid
2699046SAli.Saidi@ARM.comSerializeEvent::process()
2709046SAli.Saidi@ARM.com{
2719046SAli.Saidi@ARM.com    Serializable::serializeAll();
2729046SAli.Saidi@ARM.com    if (repeat)
2739046SAli.Saidi@ARM.com        schedule(curTick + repeat);
2749046SAli.Saidi@ARM.com}
2759046SAli.Saidi@ARM.com
2769046SAli.Saidi@ARM.comconst char *Checkpoint::baseFilename = "m5.cpt";
2779046SAli.Saidi@ARM.com
2789046SAli.Saidi@ARM.comstatic string checkpointDirBase;
2799046SAli.Saidi@ARM.com
2809046SAli.Saidi@ARM.comstring
2819046SAli.Saidi@ARM.comCheckpoint::dir()
2829046SAli.Saidi@ARM.com{
2839046SAli.Saidi@ARM.com    // use csprintf to insert curTick into directory name if it
2849046SAli.Saidi@ARM.com    // appears to have a format placeholder in it.
2859046SAli.Saidi@ARM.com    return (checkpointDirBase.find("%") != string::npos) ?
2869046SAli.Saidi@ARM.com        csprintf(checkpointDirBase, curTick) : checkpointDirBase;
2879046SAli.Saidi@ARM.com}
2889046SAli.Saidi@ARM.com
2899046SAli.Saidi@ARM.comvoid
2909046SAli.Saidi@ARM.comCheckpoint::setup(Tick when, Tick period)
2911060SN/A{
2921060SN/A    new SerializeEvent(when, period);
2931060SN/A}
2941060SN/A
2951060SN/Aclass SerializeParamContext : public ParamContext
2961060SN/A{
2975358Sgblack@eecs.umich.edu  private:
2985358Sgblack@eecs.umich.edu    SerializeEvent *event;
2995358Sgblack@eecs.umich.edu
3005358Sgblack@eecs.umich.edu  public:
3015358Sgblack@eecs.umich.edu    SerializeParamContext(const string &section);
3025358Sgblack@eecs.umich.edu    ~SerializeParamContext();
3035358Sgblack@eecs.umich.edu    void checkParams();
3045358Sgblack@eecs.umich.edu};
3055358Sgblack@eecs.umich.edu
3065358Sgblack@eecs.umich.eduSerializeParamContext serialParams("serialize");
3075358Sgblack@eecs.umich.edu
3085358Sgblack@eecs.umich.eduParam<string> serialize_dir(&serialParams, "dir",
3095358Sgblack@eecs.umich.edu                            "dir to stick checkpoint in "
3108444Sgblack@eecs.umich.edu                            "(sprintf format with cycle #)");
3117520Sgblack@eecs.umich.edu
3128444Sgblack@eecs.umich.eduParam<Counter> serialize_cycle(&serialParams,
3138444Sgblack@eecs.umich.edu                                "cycle",
3147520Sgblack@eecs.umich.edu                                "cycle to serialize",
3156974Stjones1@inf.ed.ac.uk                                0);
3166974Stjones1@inf.ed.ac.uk
3176974Stjones1@inf.ed.ac.ukParam<Counter> serialize_period(&serialParams,
3186974Stjones1@inf.ed.ac.uk                                "period",
3196973Stjones1@inf.ed.ac.uk                                "period to repeat serializations",
3206974Stjones1@inf.ed.ac.uk                                0);
3216974Stjones1@inf.ed.ac.uk
3226973Stjones1@inf.ed.ac.uk
3236973Stjones1@inf.ed.ac.uk
3246973Stjones1@inf.ed.ac.ukSerializeParamContext::SerializeParamContext(const string &section)
3256973Stjones1@inf.ed.ac.uk    : ParamContext(section), event(NULL)
3261060SN/A{ }
3277944SGiacomo.Gabrielli@arm.com
3289046SAli.Saidi@ARM.comSerializeParamContext::~SerializeParamContext()
3299046SAli.Saidi@ARM.com{
3307944SGiacomo.Gabrielli@arm.com}
3317944SGiacomo.Gabrielli@arm.com
3329046SAli.Saidi@ARM.comvoid
3339046SAli.Saidi@ARM.comSerializeParamContext::checkParams()
3347944SGiacomo.Gabrielli@arm.com{
3358545Ssaidi@eecs.umich.edu    if (serialize_dir.isValid()) {
3368545Ssaidi@eecs.umich.edu        checkpointDirBase = serialize_dir;
3378545Ssaidi@eecs.umich.edu    } else {
3388545Ssaidi@eecs.umich.edu        if (outputDirectory.empty())
3398545Ssaidi@eecs.umich.edu            checkpointDirBase = "m5.%012d";
3409046SAli.Saidi@ARM.com        else
3419046SAli.Saidi@ARM.com            checkpointDirBase = outputDirectory + "cpt.%012d";
3428545Ssaidi@eecs.umich.edu    }
3438545Ssaidi@eecs.umich.edu
3448545Ssaidi@eecs.umich.edu    // guarantee that directory ends with a '/'
3458545Ssaidi@eecs.umich.edu    if (checkpointDirBase[checkpointDirBase.size() - 1] != '/')
3468545Ssaidi@eecs.umich.edu        checkpointDirBase += "/";
3479046SAli.Saidi@ARM.com
3489046SAli.Saidi@ARM.com    if (serialize_cycle > 0)
3498545Ssaidi@eecs.umich.edu        Checkpoint::setup(serialize_cycle, serialize_period);
3507944SGiacomo.Gabrielli@arm.com}
3517944SGiacomo.Gabrielli@arm.com
3527944SGiacomo.Gabrielli@arm.comvoid
3537944SGiacomo.Gabrielli@arm.comdebug_serialize()
3547944SGiacomo.Gabrielli@arm.com{
3557944SGiacomo.Gabrielli@arm.com    Serializable::serializeAll();
3569046SAli.Saidi@ARM.com}
3577944SGiacomo.Gabrielli@arm.com
3587944SGiacomo.Gabrielli@arm.comvoid
3591060SN/Adebug_serialize(Tick when)
3602292SN/A{
3612292SN/A    new SerializeEvent(when, 0);
3622292SN/A}
3632292SN/A
3643770Sgblack@eecs.umich.edu////////////////////////////////////////////////////////////////////////
3653770Sgblack@eecs.umich.edu//
3663770Sgblack@eecs.umich.edu// SerializableClass member definitions
3673770Sgblack@eecs.umich.edu//
3683770Sgblack@eecs.umich.edu////////////////////////////////////////////////////////////////////////
3693770Sgblack@eecs.umich.edu
3703770Sgblack@eecs.umich.edu// Map of class names to SerializableBuilder creation functions.
3713770Sgblack@eecs.umich.edu// Need to make this a pointer so we can force initialization on the
3723770Sgblack@eecs.umich.edu// first reference; otherwise, some SerializableClass constructors
3733770Sgblack@eecs.umich.edu// may be invoked before the classMap constructor.
3743770Sgblack@eecs.umich.edumap<string,SerializableClass::CreateFunc> *SerializableClass::classMap = 0;
3759046SAli.Saidi@ARM.com
3763770Sgblack@eecs.umich.edu// SerializableClass constructor: add mapping to classMap
3773770Sgblack@eecs.umich.eduSerializableClass::SerializableClass(const string &className,
3783770Sgblack@eecs.umich.edu                                       CreateFunc createFunc)
3793770Sgblack@eecs.umich.edu{
3803770Sgblack@eecs.umich.edu    if (classMap == NULL)
3813770Sgblack@eecs.umich.edu        classMap = new map<string,SerializableClass::CreateFunc>();
3823770Sgblack@eecs.umich.edu
3833770Sgblack@eecs.umich.edu    if ((*classMap)[className])
3843770Sgblack@eecs.umich.edu    {
3853770Sgblack@eecs.umich.edu        cerr << "Error: simulation object class " << className << " redefined"
3863770Sgblack@eecs.umich.edu             << endl;
3873770Sgblack@eecs.umich.edu        fatal("");
3883770Sgblack@eecs.umich.edu    }
3893770Sgblack@eecs.umich.edu
3903770Sgblack@eecs.umich.edu    // add className --> createFunc to class map
3913770Sgblack@eecs.umich.edu    (*classMap)[className] = createFunc;
3923770Sgblack@eecs.umich.edu}
3933770Sgblack@eecs.umich.edu
3943770Sgblack@eecs.umich.edu
3953770Sgblack@eecs.umich.edu//
3963770Sgblack@eecs.umich.edu//
3973770Sgblack@eecs.umich.eduSerializable *
3983770Sgblack@eecs.umich.eduSerializableClass::createObject(Checkpoint *cp,
3993770Sgblack@eecs.umich.edu                                 const std::string &section)
4003770Sgblack@eecs.umich.edu{
4013770Sgblack@eecs.umich.edu    string className;
4023770Sgblack@eecs.umich.edu
4033770Sgblack@eecs.umich.edu    if (!cp->find(section, "type", className)) {
4043770Sgblack@eecs.umich.edu        fatal("Serializable::create: no 'type' entry in section '%s'.\n",
4053770Sgblack@eecs.umich.edu              section);
4063770Sgblack@eecs.umich.edu    }
4073770Sgblack@eecs.umich.edu
4083770Sgblack@eecs.umich.edu    CreateFunc createFunc = (*classMap)[className];
4093770Sgblack@eecs.umich.edu
4103770Sgblack@eecs.umich.edu    if (createFunc == NULL) {
4113770Sgblack@eecs.umich.edu        fatal("Serializable::create: no create function for class '%s'.\n",
4123770Sgblack@eecs.umich.edu              className);
4133770Sgblack@eecs.umich.edu    }
4143770Sgblack@eecs.umich.edu
4153770Sgblack@eecs.umich.edu    Serializable *object = createFunc(cp, section);
4163770Sgblack@eecs.umich.edu
4173770Sgblack@eecs.umich.edu    assert(object != NULL);
4183770Sgblack@eecs.umich.edu
4193770Sgblack@eecs.umich.edu    return object;
4203770Sgblack@eecs.umich.edu}
4213770Sgblack@eecs.umich.edu
4224636Sgblack@eecs.umich.edu
4234636Sgblack@eecs.umich.eduSerializable *
4247720Sgblack@eecs.umich.eduSerializable::create(Checkpoint *cp, const std::string &section)
4257720Sgblack@eecs.umich.edu{
4264636Sgblack@eecs.umich.edu    Serializable *object = SerializableClass::createObject(cp, section);
4274636Sgblack@eecs.umich.edu    object->unserialize(cp, section);
4284636Sgblack@eecs.umich.edu    return object;
42910417Sandreas.hansson@arm.com}
4308502Sgblack@eecs.umich.edu
4318502Sgblack@eecs.umich.edu
4323770Sgblack@eecs.umich.eduCheckpoint::Checkpoint(const std::string &cpt_dir, const std::string &path,
4332292SN/A                       const ConfigNode *_configNode)
4342292SN/A    : db(new IniFile), basePath(path), configNode(_configNode)
4352292SN/A{
43610417Sandreas.hansson@arm.com    string filename = cpt_dir + "/" + Checkpoint::baseFilename;
4371060SN/A    if (!db->load(filename)) {
4381060SN/A        fatal("Can't load checkpoint file '%s'\n", filename);
4391060SN/A    }
4401060SN/A}
4411464SN/A
4421684SN/A
4431464SN/Abool
4441060SN/ACheckpoint::find(const std::string &section, const std::string &entry,
4451464SN/A                 std::string &value)
4461060SN/A{
4471060SN/A    return db->find(section, entry, value);
4481060SN/A}
4491060SN/A
4501060SN/A
4511060SN/Abool
4523326Sktlim@umich.eduCheckpoint::findObj(const std::string &section, const std::string &entry,
45310110Sandreas.hansson@arm.com                    Serializable *&value)
4543326Sktlim@umich.edu{
45510190Sakash.bagdia@arm.com    string path;
45610190Sakash.bagdia@arm.com
45710190Sakash.bagdia@arm.com    if (!db->find(section, entry, path))
4588832SAli.Saidi@ARM.com        return false;
45910110Sandreas.hansson@arm.com
4608832SAli.Saidi@ARM.com    if ((value = configNode->resolveSimObject(path)) != NULL)
4615714Shsul@eecs.umich.edu        return true;
46210110Sandreas.hansson@arm.com
4635714Shsul@eecs.umich.edu    if ((value = objMap[path]) != NULL)
4641060SN/A        return true;
46510110Sandreas.hansson@arm.com
4661060SN/A    return false;
4671060SN/A}
4681060SN/A
4691060SN/A
4702292SN/Abool
4711060SN/ACheckpoint::sectionExists(const std::string &section)
4721060SN/A{
4731060SN/A    return db->sectionExists(section);
4747720Sgblack@eecs.umich.edu}
4757720Sgblack@eecs.umich.edu