serialize.cc revision 4000
12810SN/A/*
212724Snikos.nikoleris@arm.com * Copyright (c) 2002-2005 The Regents of The University of Michigan
38856Sandreas.hansson@arm.com * All rights reserved.
48856Sandreas.hansson@arm.com *
58856Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
68856Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
78856Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
88856Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
98856Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
108856Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
118856Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
128856Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
138856Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from
142810SN/A * this software without specific prior written permission.
152810SN/A *
162810SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172810SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182810SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192810SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202810SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212810SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222810SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232810SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242810SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252810SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262810SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272810SN/A *
282810SN/A * Authors: Nathan Binkert
292810SN/A *          Erik Hallnor
302810SN/A *          Steve Reinhardt
312810SN/A */
322810SN/A
332810SN/A#include <sys/time.h>
342810SN/A#include <sys/types.h>
352810SN/A#include <sys/stat.h>
362810SN/A#include <errno.h>
372810SN/A
382810SN/A#include <fstream>
392810SN/A#include <list>
402810SN/A#include <string>
4112724Snikos.nikoleris@arm.com#include <vector>
422810SN/A
432810SN/A#include "base/inifile.hh"
442810SN/A#include "base/misc.hh"
452810SN/A#include "base/output.hh"
462810SN/A#include "base/str.hh"
472810SN/A#include "base/trace.hh"
482810SN/A#include "sim/eventq.hh"
4911486Snikos.nikoleris@arm.com#include "sim/param.hh"
5011486Snikos.nikoleris@arm.com#include "sim/serialize.hh"
5112724Snikos.nikoleris@arm.com#include "sim/sim_events.hh"
5212724Snikos.nikoleris@arm.com#include "sim/sim_exit.hh"
538232Snate@binkert.org#include "sim/sim_object.hh"
5412724Snikos.nikoleris@arm.com
5512724Snikos.nikoleris@arm.com// For stat reset hack
5611486Snikos.nikoleris@arm.com#include "sim/stat_control.hh"
5712724Snikos.nikoleris@arm.com
5812724Snikos.nikoleris@arm.comusing namespace std;
5912724Snikos.nikoleris@arm.com
6012724Snikos.nikoleris@arm.comextern SimObject *resolveSimObject(const string &);
6112724Snikos.nikoleris@arm.com
6212724Snikos.nikoleris@arm.comint Serializable::ckptMaxCount = 0;
6312724Snikos.nikoleris@arm.comint Serializable::ckptCount = 0;
642810SN/Aint Serializable::ckptPrevCount = -1;
652810SN/A
662810SN/Avoid
678856Sandreas.hansson@arm.comSerializable::nameOut(ostream &os)
688856Sandreas.hansson@arm.com{
698856Sandreas.hansson@arm.com    os << "\n[" << name() << "]\n";
708922Swilliam.wang@arm.com}
7112084Sspwilson2@wisc.edu
7212084Sspwilson2@wisc.eduvoid
738856Sandreas.hansson@arm.comSerializable::nameOut(ostream &os, const string &_name)
748856Sandreas.hansson@arm.com{
754475SN/A    os << "\n[" << _name << "]\n";
7611053Sandreas.hansson@arm.com}
775034SN/A
7812724Snikos.nikoleris@arm.comtemplate <class T>
7912724Snikos.nikoleris@arm.comvoid
8011377Sandreas.hansson@arm.comparamOut(ostream &os, const std::string &name, const T &param)
8111377Sandreas.hansson@arm.com{
8212724Snikos.nikoleris@arm.com    os << name << "=";
8312724Snikos.nikoleris@arm.com    showParam(os, param);
8412724Snikos.nikoleris@arm.com    os << "\n";
8512724Snikos.nikoleris@arm.com}
8612724Snikos.nikoleris@arm.com
8712724Snikos.nikoleris@arm.com
8812724Snikos.nikoleris@arm.comtemplate <class T>
8912724Snikos.nikoleris@arm.comvoid
9011053Sandreas.hansson@arm.comparamIn(Checkpoint *cp, const std::string &section,
9111722Ssophiane.senni@gmail.com        const std::string &name, T &param)
9211722Ssophiane.senni@gmail.com{
9311722Ssophiane.senni@gmail.com    std::string str;
9411722Ssophiane.senni@gmail.com    if (!cp->find(section, name, str) || !parseParam(str, param)) {
959263Smrinmoy.ghosh@arm.com        fatal("Can't unserialize '%s:%s'\n", section, name);
965034SN/A    }
9711331Sandreas.hansson@arm.com}
9812724Snikos.nikoleris@arm.com
9910884Sandreas.hansson@arm.com
1004626SN/Atemplate <class T>
10110360Sandreas.hansson@arm.comvoid
10211484Snikos.nikoleris@arm.comarrayParamOut(ostream &os, const std::string &name,
1035034SN/A              const T *param, int size)
1048883SAli.Saidi@ARM.com{
1058833Sdam.sunwoo@arm.com    os << name << "=";
1064458SN/A    if (size > 0)
10711377Sandreas.hansson@arm.com        showParam(os, param[0]);
10811377Sandreas.hansson@arm.com    for (int i = 1; i < size; ++i) {
10911377Sandreas.hansson@arm.com        os << " ";
11011377Sandreas.hansson@arm.com        showParam(os, param[i]);
11111377Sandreas.hansson@arm.com    }
11211377Sandreas.hansson@arm.com    os << "\n";
11311331Sandreas.hansson@arm.com}
11411331Sandreas.hansson@arm.com
11512724Snikos.nikoleris@arm.com
11612843Srmk35@cl.cam.ac.uktemplate <class T>
11712724Snikos.nikoleris@arm.comvoid
11812724Snikos.nikoleris@arm.comarrayParamIn(Checkpoint *cp, const std::string &section,
11912724Snikos.nikoleris@arm.com             const std::string &name, T *param, int size)
12012724Snikos.nikoleris@arm.com{
12112724Snikos.nikoleris@arm.com    std::string str;
12212724Snikos.nikoleris@arm.com    if (!cp->find(section, name, str)) {
12312724Snikos.nikoleris@arm.com        fatal("Can't unserialize '%s:%s'\n", section, name);
12412724Snikos.nikoleris@arm.com    }
12512724Snikos.nikoleris@arm.com
1262810SN/A    // code below stolen from VectorParam<T>::parse().
1272810SN/A    // it would be nice to unify these somehow...
1283013SN/A
1298856Sandreas.hansson@arm.com    vector<string> tokens;
1302810SN/A
1313013SN/A    tokenize(tokens, str, ' ');
13210714Sandreas.hansson@arm.com
1332810SN/A    // Need this if we were doing a vector
1349614Srene.dejong@arm.com    // value.resize(tokens.size());
1359614Srene.dejong@arm.com
1369614Srene.dejong@arm.com    if (tokens.size() != size) {
13710345SCurtis.Dunham@arm.com        fatal("Array size mismatch on %s:%s'\n", section, name);
13810714Sandreas.hansson@arm.com    }
13910345SCurtis.Dunham@arm.com
1409614Srene.dejong@arm.com    for (int i = 0; i < tokens.size(); i++) {
1412810SN/A        // need to parse into local variable to handle vector<bool>,
1422810SN/A        // for which operator[] returns a special reference class
1432810SN/A        // that's not the same as 'bool&', (since it's a packed
1448856Sandreas.hansson@arm.com        // vector)
1452810SN/A        T scalar_value;
1463013SN/A        if (!parseParam(tokens[i], scalar_value)) {
14710714Sandreas.hansson@arm.com            string err("could not parse \"");
1483013SN/A
1498856Sandreas.hansson@arm.com            err += str;
15010714Sandreas.hansson@arm.com            err += "\"";
1518922Swilliam.wang@arm.com
1522897SN/A            fatal(err);
1532810SN/A        }
1542810SN/A
15510344Sandreas.hansson@arm.com        // assign parsed value to vector
15610344Sandreas.hansson@arm.com        param[i] = scalar_value;
15710344Sandreas.hansson@arm.com    }
15810714Sandreas.hansson@arm.com}
15910344Sandreas.hansson@arm.com
16010344Sandreas.hansson@arm.com
16110344Sandreas.hansson@arm.comvoid
16210713Sandreas.hansson@arm.comobjParamIn(Checkpoint *cp, const std::string &section,
16310344Sandreas.hansson@arm.com           const std::string &name, SimObject * &param)
1642844SN/A{
16512730Sodanrc@yahoo.com.br    if (!cp->findObj(section, name, param)) {
16612730Sodanrc@yahoo.com.br        fatal("Can't unserialize '%s:%s'\n", section, name);
16712730Sodanrc@yahoo.com.br    }
16812730Sodanrc@yahoo.com.br}
16912730Sodanrc@yahoo.com.br
17012730Sodanrc@yahoo.com.br
17112730Sodanrc@yahoo.com.br#define INSTANTIATE_PARAM_TEMPLATES(type)				\
17212730Sodanrc@yahoo.com.brtemplate void								\
17312730Sodanrc@yahoo.com.brparamOut(ostream &os, const std::string &name, type const &param);	\
17412730Sodanrc@yahoo.com.brtemplate void								\
1752810SN/AparamIn(Checkpoint *cp, const std::string &section,			\
1762858SN/A        const std::string &name, type & param);				\
1772858SN/Atemplate void								\
17812724Snikos.nikoleris@arm.comarrayParamOut(ostream &os, const std::string &name,			\
1798922Swilliam.wang@arm.com              type const *param, int size);				\
18012724Snikos.nikoleris@arm.comtemplate void								\
18112724Snikos.nikoleris@arm.comarrayParamIn(Checkpoint *cp, const std::string &section,		\
1822858SN/A             const std::string &name, type *param, int size);
1832858SN/A
1849294Sandreas.hansson@arm.comINSTANTIATE_PARAM_TEMPLATES(signed char)
1859294Sandreas.hansson@arm.comINSTANTIATE_PARAM_TEMPLATES(unsigned char)
1868922Swilliam.wang@arm.comINSTANTIATE_PARAM_TEMPLATES(signed short)
1878922Swilliam.wang@arm.comINSTANTIATE_PARAM_TEMPLATES(unsigned short)
18812724Snikos.nikoleris@arm.comINSTANTIATE_PARAM_TEMPLATES(signed int)
1898922Swilliam.wang@arm.comINSTANTIATE_PARAM_TEMPLATES(unsigned int)
1908922Swilliam.wang@arm.comINSTANTIATE_PARAM_TEMPLATES(signed long)
1918922Swilliam.wang@arm.comINSTANTIATE_PARAM_TEMPLATES(unsigned long)
1928922Swilliam.wang@arm.comINSTANTIATE_PARAM_TEMPLATES(signed long long)
1938922Swilliam.wang@arm.comINSTANTIATE_PARAM_TEMPLATES(unsigned long long)
1949294Sandreas.hansson@arm.comINSTANTIATE_PARAM_TEMPLATES(bool)
1959294Sandreas.hansson@arm.comINSTANTIATE_PARAM_TEMPLATES(string)
1968922Swilliam.wang@arm.com
1978922Swilliam.wang@arm.com
19812724Snikos.nikoleris@arm.com/////////////////////////////
1998922Swilliam.wang@arm.com
2008922Swilliam.wang@arm.com/// Container for serializing global variables (not associated with
2018922Swilliam.wang@arm.com/// any serialized object).
2028922Swilliam.wang@arm.comclass Globals : public Serializable
2034628SN/A{
20410821Sandreas.hansson@arm.com  public:
20510821Sandreas.hansson@arm.com    const string name() const;
20610821Sandreas.hansson@arm.com    void serialize(ostream &os);
20710821Sandreas.hansson@arm.com    void unserialize(Checkpoint *cp);
20810821Sandreas.hansson@arm.com};
20910821Sandreas.hansson@arm.com
21010821Sandreas.hansson@arm.com/// The one and only instance of the Globals class.
21110821Sandreas.hansson@arm.comGlobals globals;
21210821Sandreas.hansson@arm.com
21310821Sandreas.hansson@arm.comconst string
21410821Sandreas.hansson@arm.comGlobals::name() const
2152858SN/A{
21612724Snikos.nikoleris@arm.com    return "Globals";
21712724Snikos.nikoleris@arm.com}
21812724Snikos.nikoleris@arm.com
21912724Snikos.nikoleris@arm.comvoid
22012724Snikos.nikoleris@arm.comGlobals::serialize(ostream &os)
22112724Snikos.nikoleris@arm.com{
22212724Snikos.nikoleris@arm.com    nameOut(os);
22312724Snikos.nikoleris@arm.com    SERIALIZE_SCALAR(curTick);
22412724Snikos.nikoleris@arm.com
22512724Snikos.nikoleris@arm.com    nameOut(os, "MainEventQueue");
22612724Snikos.nikoleris@arm.com    mainEventQueue.serialize(os);
22712724Snikos.nikoleris@arm.com}
22812724Snikos.nikoleris@arm.com
22912724Snikos.nikoleris@arm.comvoid
23012724Snikos.nikoleris@arm.comGlobals::unserialize(Checkpoint *cp)
23112724Snikos.nikoleris@arm.com{
23212724Snikos.nikoleris@arm.com    const string &section = name();
23312724Snikos.nikoleris@arm.com    UNSERIALIZE_SCALAR(curTick);
23412724Snikos.nikoleris@arm.com
23512724Snikos.nikoleris@arm.com    mainEventQueue.unserialize(cp, "MainEventQueue");
23612724Snikos.nikoleris@arm.com}
23712724Snikos.nikoleris@arm.com
23812724Snikos.nikoleris@arm.comvoid
23912724Snikos.nikoleris@arm.comSerializable::serializeAll(const std::string &cpt_dir)
24012724Snikos.nikoleris@arm.com{
24112724Snikos.nikoleris@arm.com    setCheckpointDir(cpt_dir);
24212724Snikos.nikoleris@arm.com    string dir = Checkpoint::dir();
24312724Snikos.nikoleris@arm.com    if (mkdir(dir.c_str(), 0775) == -1 && errno != EEXIST)
24412724Snikos.nikoleris@arm.com            fatal("couldn't mkdir %s\n", dir);
24512724Snikos.nikoleris@arm.com
24612724Snikos.nikoleris@arm.com    string cpt_file = dir + Checkpoint::baseFilename;
24712724Snikos.nikoleris@arm.com    ofstream outstream(cpt_file.c_str());
24812724Snikos.nikoleris@arm.com    time_t t = time(NULL);
24912724Snikos.nikoleris@arm.com    outstream << "// checkpoint generated: " << ctime(&t);
25012724Snikos.nikoleris@arm.com
25112724Snikos.nikoleris@arm.com    globals.serialize(outstream);
25212724Snikos.nikoleris@arm.com    SimObject::serializeAll(outstream);
25312724Snikos.nikoleris@arm.com}
25412724Snikos.nikoleris@arm.com
25512724Snikos.nikoleris@arm.comvoid
25612724Snikos.nikoleris@arm.comSerializable::unserializeAll(const std::string &cpt_dir)
25712724Snikos.nikoleris@arm.com{
25812724Snikos.nikoleris@arm.com    setCheckpointDir(cpt_dir);
25912724Snikos.nikoleris@arm.com    string dir = Checkpoint::dir();
26012724Snikos.nikoleris@arm.com    string cpt_file = dir + Checkpoint::baseFilename;
26112724Snikos.nikoleris@arm.com    string section = "";
26212724Snikos.nikoleris@arm.com
26312724Snikos.nikoleris@arm.com    DPRINTFR(Config, "Loading checkpoint dir '%s'\n",
26412724Snikos.nikoleris@arm.com             dir);
26512724Snikos.nikoleris@arm.com    Checkpoint *cp = new Checkpoint(dir, section);
26612724Snikos.nikoleris@arm.com    unserializeGlobals(cp);
26712724Snikos.nikoleris@arm.com
26812724Snikos.nikoleris@arm.com    SimObject::unserializeAll(cp);
26912724Snikos.nikoleris@arm.com}
27012724Snikos.nikoleris@arm.com
27112724Snikos.nikoleris@arm.comvoid
27212724Snikos.nikoleris@arm.comSerializable::unserializeGlobals(Checkpoint *cp)
27312724Snikos.nikoleris@arm.com{
27412724Snikos.nikoleris@arm.com    globals.unserialize(cp);
27512724Snikos.nikoleris@arm.com}
27612724Snikos.nikoleris@arm.com
27712724Snikos.nikoleris@arm.comconst char *Checkpoint::baseFilename = "m5.cpt";
27812724Snikos.nikoleris@arm.com
27912724Snikos.nikoleris@arm.comstatic string checkpointDirBase;
28012724Snikos.nikoleris@arm.com
28112724Snikos.nikoleris@arm.comvoid
28212724Snikos.nikoleris@arm.comsetCheckpointDir(const std::string &name)
28312724Snikos.nikoleris@arm.com{
28412724Snikos.nikoleris@arm.com    checkpointDirBase = name;
28512724Snikos.nikoleris@arm.com    if (checkpointDirBase[checkpointDirBase.size() - 1] != '/')
28612724Snikos.nikoleris@arm.com        checkpointDirBase += "/";
28712724Snikos.nikoleris@arm.com}
28812724Snikos.nikoleris@arm.com
28912724Snikos.nikoleris@arm.comstring
29012724Snikos.nikoleris@arm.comCheckpoint::dir()
29112724Snikos.nikoleris@arm.com{
29212724Snikos.nikoleris@arm.com    // use csprintf to insert curTick into directory name if it
29312724Snikos.nikoleris@arm.com    // appears to have a format placeholder in it.
29412724Snikos.nikoleris@arm.com    return (checkpointDirBase.find("%") != string::npos) ?
29512724Snikos.nikoleris@arm.com        csprintf(checkpointDirBase, curTick) : checkpointDirBase;
29612724Snikos.nikoleris@arm.com}
29712724Snikos.nikoleris@arm.com
29812724Snikos.nikoleris@arm.comvoid
29912724Snikos.nikoleris@arm.comdebug_serialize(const std::string &cpt_dir)
30012724Snikos.nikoleris@arm.com{
30112724Snikos.nikoleris@arm.com    Serializable::serializeAll(cpt_dir);
30212724Snikos.nikoleris@arm.com}
30312724Snikos.nikoleris@arm.com
30412724Snikos.nikoleris@arm.com
30512724Snikos.nikoleris@arm.com////////////////////////////////////////////////////////////////////////
30612724Snikos.nikoleris@arm.com//
30712724Snikos.nikoleris@arm.com// SerializableClass member definitions
30812724Snikos.nikoleris@arm.com//
30912724Snikos.nikoleris@arm.com////////////////////////////////////////////////////////////////////////
31012724Snikos.nikoleris@arm.com
31112724Snikos.nikoleris@arm.com// Map of class names to SerializableBuilder creation functions.
31212724Snikos.nikoleris@arm.com// Need to make this a pointer so we can force initialization on the
31312724Snikos.nikoleris@arm.com// first reference; otherwise, some SerializableClass constructors
31412724Snikos.nikoleris@arm.com// may be invoked before the classMap constructor.
31512724Snikos.nikoleris@arm.commap<string,SerializableClass::CreateFunc> *SerializableClass::classMap = 0;
31612724Snikos.nikoleris@arm.com
31712724Snikos.nikoleris@arm.com// SerializableClass constructor: add mapping to classMap
31812724Snikos.nikoleris@arm.comSerializableClass::SerializableClass(const string &className,
31912724Snikos.nikoleris@arm.com                                       CreateFunc createFunc)
32012724Snikos.nikoleris@arm.com{
32112724Snikos.nikoleris@arm.com    if (classMap == NULL)
32212724Snikos.nikoleris@arm.com        classMap = new map<string,SerializableClass::CreateFunc>();
32312724Snikos.nikoleris@arm.com
32412724Snikos.nikoleris@arm.com    if ((*classMap)[className])
32512724Snikos.nikoleris@arm.com    {
32612724Snikos.nikoleris@arm.com        cerr << "Error: simulation object class " << className << " redefined"
32712724Snikos.nikoleris@arm.com             << endl;
32812724Snikos.nikoleris@arm.com        fatal("");
32912724Snikos.nikoleris@arm.com    }
33012724Snikos.nikoleris@arm.com
33112724Snikos.nikoleris@arm.com    // add className --> createFunc to class map
33212724Snikos.nikoleris@arm.com    (*classMap)[className] = createFunc;
33312724Snikos.nikoleris@arm.com}
33412724Snikos.nikoleris@arm.com
33512724Snikos.nikoleris@arm.com
33612724Snikos.nikoleris@arm.com//
33712724Snikos.nikoleris@arm.com//
33812724Snikos.nikoleris@arm.comSerializable *
33912724Snikos.nikoleris@arm.comSerializableClass::createObject(Checkpoint *cp,
34012724Snikos.nikoleris@arm.com                                 const std::string &section)
34112724Snikos.nikoleris@arm.com{
34212724Snikos.nikoleris@arm.com    string className;
34312724Snikos.nikoleris@arm.com
34412724Snikos.nikoleris@arm.com    if (!cp->find(section, "type", className)) {
34512724Snikos.nikoleris@arm.com        fatal("Serializable::create: no 'type' entry in section '%s'.\n",
34612724Snikos.nikoleris@arm.com              section);
34712724Snikos.nikoleris@arm.com    }
34812724Snikos.nikoleris@arm.com
34912820Srmk35@cl.cam.ac.uk    CreateFunc createFunc = (*classMap)[className];
35012724Snikos.nikoleris@arm.com
35112724Snikos.nikoleris@arm.com    if (createFunc == NULL) {
35212724Snikos.nikoleris@arm.com        fatal("Serializable::create: no create function for class '%s'.\n",
35312724Snikos.nikoleris@arm.com              className);
35412724Snikos.nikoleris@arm.com    }
35512724Snikos.nikoleris@arm.com
35612724Snikos.nikoleris@arm.com    Serializable *object = createFunc(cp, section);
35712724Snikos.nikoleris@arm.com
35812724Snikos.nikoleris@arm.com    assert(object != NULL);
35912724Snikos.nikoleris@arm.com
36012724Snikos.nikoleris@arm.com    return object;
36112724Snikos.nikoleris@arm.com}
36212724Snikos.nikoleris@arm.com
36312724Snikos.nikoleris@arm.com
36412724Snikos.nikoleris@arm.comSerializable *
36512724Snikos.nikoleris@arm.comSerializable::create(Checkpoint *cp, const std::string &section)
36612724Snikos.nikoleris@arm.com{
36712724Snikos.nikoleris@arm.com    Serializable *object = SerializableClass::createObject(cp, section);
36812724Snikos.nikoleris@arm.com    object->unserialize(cp, section);
36912724Snikos.nikoleris@arm.com    return object;
37012724Snikos.nikoleris@arm.com}
37112724Snikos.nikoleris@arm.com
37212724Snikos.nikoleris@arm.com
37312724Snikos.nikoleris@arm.comCheckpoint::Checkpoint(const std::string &cpt_dir, const std::string &path)
37412724Snikos.nikoleris@arm.com    : db(new IniFile), basePath(path), cptDir(cpt_dir)
37512724Snikos.nikoleris@arm.com{
37612724Snikos.nikoleris@arm.com    string filename = cpt_dir + "/" + Checkpoint::baseFilename;
37712724Snikos.nikoleris@arm.com    if (!db->load(filename)) {
37812724Snikos.nikoleris@arm.com        fatal("Can't load checkpoint file '%s'\n", filename);
37912724Snikos.nikoleris@arm.com    }
38012724Snikos.nikoleris@arm.com}
38112724Snikos.nikoleris@arm.com
38212724Snikos.nikoleris@arm.com
38312724Snikos.nikoleris@arm.combool
38412724Snikos.nikoleris@arm.comCheckpoint::find(const std::string &section, const std::string &entry,
38512724Snikos.nikoleris@arm.com                 std::string &value)
38612724Snikos.nikoleris@arm.com{
38712724Snikos.nikoleris@arm.com    return db->find(section, entry, value);
38812724Snikos.nikoleris@arm.com}
38912724Snikos.nikoleris@arm.com
39012724Snikos.nikoleris@arm.com
39112724Snikos.nikoleris@arm.combool
39212724Snikos.nikoleris@arm.comCheckpoint::findObj(const std::string &section, const std::string &entry,
39312724Snikos.nikoleris@arm.com                    SimObject *&value)
39412724Snikos.nikoleris@arm.com{
39512724Snikos.nikoleris@arm.com    string path;
39612724Snikos.nikoleris@arm.com
39712724Snikos.nikoleris@arm.com    if (!db->find(section, entry, path))
39812724Snikos.nikoleris@arm.com        return false;
39912724Snikos.nikoleris@arm.com
40012724Snikos.nikoleris@arm.com    value = resolveSimObject(path);
40112724Snikos.nikoleris@arm.com    return true;
40212724Snikos.nikoleris@arm.com}
40312724Snikos.nikoleris@arm.com
40412724Snikos.nikoleris@arm.com
40512724Snikos.nikoleris@arm.combool
40612724Snikos.nikoleris@arm.comCheckpoint::sectionExists(const std::string &section)
40712724Snikos.nikoleris@arm.com{
40812724Snikos.nikoleris@arm.com    return db->sectionExists(section);
40912724Snikos.nikoleris@arm.com}
41012724Snikos.nikoleris@arm.com
41112724Snikos.nikoleris@arm.com/** Hacked stat reset event */
41212724Snikos.nikoleris@arm.com
41312724Snikos.nikoleris@arm.comclass StatresetParamContext : public ParamContext
41412724Snikos.nikoleris@arm.com{
41512724Snikos.nikoleris@arm.com  public:
41612724Snikos.nikoleris@arm.com    StatresetParamContext(const string &section);
41712724Snikos.nikoleris@arm.com    ~StatresetParamContext();
41812724Snikos.nikoleris@arm.com    void startup();
41912724Snikos.nikoleris@arm.com};
42012724Snikos.nikoleris@arm.com
42112724Snikos.nikoleris@arm.comStatresetParamContext statParams("statsreset");
42212724Snikos.nikoleris@arm.com
42312724Snikos.nikoleris@arm.comParam<Tick> reset_cycle(&statParams, "reset_cycle",
42412724Snikos.nikoleris@arm.com                        "Cycle to reset stats on", 0);
42512724Snikos.nikoleris@arm.com
42612724Snikos.nikoleris@arm.comStatresetParamContext::StatresetParamContext(const string &section)
42712724Snikos.nikoleris@arm.com    : ParamContext(section)
42812724Snikos.nikoleris@arm.com{ }
42912724Snikos.nikoleris@arm.com
43012724Snikos.nikoleris@arm.comStatresetParamContext::~StatresetParamContext()
43112724Snikos.nikoleris@arm.com{
43212724Snikos.nikoleris@arm.com}
43312724Snikos.nikoleris@arm.com
43412724Snikos.nikoleris@arm.comvoid
43512724Snikos.nikoleris@arm.comStatresetParamContext::startup()
43612724Snikos.nikoleris@arm.com{
43712724Snikos.nikoleris@arm.com    if (reset_cycle > 0) {
43812724Snikos.nikoleris@arm.com        Stats::SetupEvent(Stats::Reset, curTick + reset_cycle, 0);
43912724Snikos.nikoleris@arm.com        cprintf("Stats reset event scheduled for %lli\n",
44012724Snikos.nikoleris@arm.com                curTick + reset_cycle);
44112724Snikos.nikoleris@arm.com    }
44212724Snikos.nikoleris@arm.com}
44312724Snikos.nikoleris@arm.com