serialize.cc revision 363
111482Sandreas.sandberg@arm.com/*
211482Sandreas.sandberg@arm.com * Copyright (c) 2003 The Regents of The University of Michigan
311482Sandreas.sandberg@arm.com * All rights reserved.
411482Sandreas.sandberg@arm.com *
511482Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without
611482Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are
711482Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright
811482Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer;
911482Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright
1011482Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the
1111482Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution;
1211482Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its
1311482Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from
1411482Sandreas.sandberg@arm.com * this software without specific prior written permission.
1511482Sandreas.sandberg@arm.com *
1611482Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1711482Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1811482Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1911482Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2011482Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2111482Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2211482Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2311482Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2411482Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2511482Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2611482Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2711482Sandreas.sandberg@arm.com */
2811482Sandreas.sandberg@arm.com
2911482Sandreas.sandberg@arm.com#include <sys/time.h>
3011482Sandreas.sandberg@arm.com#include <sys/types.h>
3111482Sandreas.sandberg@arm.com#include <sys/stat.h>
3211482Sandreas.sandberg@arm.com
3311482Sandreas.sandberg@arm.com#include <fstream>
3411482Sandreas.sandberg@arm.com#include <list>
3511482Sandreas.sandberg@arm.com#include <string>
3611482Sandreas.sandberg@arm.com#include <vector>
3711482Sandreas.sandberg@arm.com
3811482Sandreas.sandberg@arm.com#include "base/inifile.hh"
3911482Sandreas.sandberg@arm.com#include "base/misc.hh"
4011482Sandreas.sandberg@arm.com#include "base/str.hh"
4111482Sandreas.sandberg@arm.com#include "base/trace.hh"
4211482Sandreas.sandberg@arm.com#include "sim/config_node.hh"
4311482Sandreas.sandberg@arm.com#include "sim/eventq.hh"
4411482Sandreas.sandberg@arm.com#include "sim/param.hh"
4511482Sandreas.sandberg@arm.com#include "sim/serialize.hh"
4611482Sandreas.sandberg@arm.com#include "sim/sim_events.hh"
4711482Sandreas.sandberg@arm.com#include "sim/sim_object.hh"
4811482Sandreas.sandberg@arm.com
4911482Sandreas.sandberg@arm.comusing namespace std;
5011482Sandreas.sandberg@arm.com
5111482Sandreas.sandberg@arm.comSerializer *Serializeable::serializer = NULL;
5211482Sandreas.sandberg@arm.com
5311482Sandreas.sandberg@arm.comSerializeable::Serializeable()
5411482Sandreas.sandberg@arm.com    : serialized(false)
5511482Sandreas.sandberg@arm.com{ }
5611482Sandreas.sandberg@arm.com
5711482Sandreas.sandberg@arm.comSerializeable::~Serializeable()
5811482Sandreas.sandberg@arm.com{ }
5911482Sandreas.sandberg@arm.com
6011482Sandreas.sandberg@arm.comvoid
6111482Sandreas.sandberg@arm.comSerializeable::mark()
6211482Sandreas.sandberg@arm.com{
6311482Sandreas.sandberg@arm.com    if (!serialized)
6411482Sandreas.sandberg@arm.com        serializer->add_object(this);
6511482Sandreas.sandberg@arm.com
6611482Sandreas.sandberg@arm.com    serialized = true;
6711482Sandreas.sandberg@arm.com}
6811482Sandreas.sandberg@arm.com
6911482Sandreas.sandberg@arm.comvoid
7011482Sandreas.sandberg@arm.comSerializeable::nameOut(ostream &os)
7111482Sandreas.sandberg@arm.com{
7211482Sandreas.sandberg@arm.com    os << "\n[" << name() << "]\n";
7311482Sandreas.sandberg@arm.com}
7411482Sandreas.sandberg@arm.com
7511482Sandreas.sandberg@arm.comvoid
7611482Sandreas.sandberg@arm.comSerializeable::nameOut(ostream &os, const string &_name)
7711482Sandreas.sandberg@arm.com{
7811482Sandreas.sandberg@arm.com    os << "\n[" << _name << "]\n";
7911482Sandreas.sandberg@arm.com}
8011482Sandreas.sandberg@arm.com
8111482Sandreas.sandberg@arm.comtemplate <class T>
8211482Sandreas.sandberg@arm.comvoid
8311482Sandreas.sandberg@arm.comparamOut(ostream &os, const std::string &name, const T& param)
8411482Sandreas.sandberg@arm.com{
8511482Sandreas.sandberg@arm.com    os << name << "=";
8611482Sandreas.sandberg@arm.com    showParam(os, param);
8711482Sandreas.sandberg@arm.com    os << "\n";
8811482Sandreas.sandberg@arm.com}
8911482Sandreas.sandberg@arm.com
9011482Sandreas.sandberg@arm.com
9111482Sandreas.sandberg@arm.comtemplate <class T>
9211482Sandreas.sandberg@arm.comvoid
9311482Sandreas.sandberg@arm.comparamIn(Checkpoint *cp, const std::string &section,
9411482Sandreas.sandberg@arm.com        const std::string &name, T& param)
9511482Sandreas.sandberg@arm.com{
9611482Sandreas.sandberg@arm.com    std::string str;
9711482Sandreas.sandberg@arm.com    if (!cp->find(section, name, str) || !parseParam(str, param)) {
9811482Sandreas.sandberg@arm.com        fatal("Can't unserialize '%s:%s'\n", section, name);
9911482Sandreas.sandberg@arm.com    }
10011482Sandreas.sandberg@arm.com}
10111482Sandreas.sandberg@arm.com
10211482Sandreas.sandberg@arm.com
10311482Sandreas.sandberg@arm.comtemplate <class T>
10411482Sandreas.sandberg@arm.comvoid
10511482Sandreas.sandberg@arm.comarrayParamOut(ostream &os, const std::string &name,
10611482Sandreas.sandberg@arm.com              const T *param, int size)
10711482Sandreas.sandberg@arm.com{
10811482Sandreas.sandberg@arm.com    os << name << "=";
10911482Sandreas.sandberg@arm.com    if (size > 0)
11011482Sandreas.sandberg@arm.com        showParam(os, param[0]);
11111482Sandreas.sandberg@arm.com    for (int i = 1; i < size; ++i) {
11211482Sandreas.sandberg@arm.com        os << " ";
11311482Sandreas.sandberg@arm.com        showParam(os, param[i]);
11411482Sandreas.sandberg@arm.com    }
11511482Sandreas.sandberg@arm.com    os << "\n";
11611482Sandreas.sandberg@arm.com}
11711482Sandreas.sandberg@arm.com
11811482Sandreas.sandberg@arm.com
11911482Sandreas.sandberg@arm.comtemplate <class T>
12011482Sandreas.sandberg@arm.comvoid
12111482Sandreas.sandberg@arm.comarrayParamIn(Checkpoint *cp, const std::string &section,
12211482Sandreas.sandberg@arm.com             const std::string &name, T *param, int size)
12311482Sandreas.sandberg@arm.com{
12411482Sandreas.sandberg@arm.com    std::string str;
12511482Sandreas.sandberg@arm.com    if (!cp->find(section, name, str)) {
12611482Sandreas.sandberg@arm.com        fatal("Can't unserialize '%s:%s'\n", section, name);
12711482Sandreas.sandberg@arm.com    }
12811482Sandreas.sandberg@arm.com
12911482Sandreas.sandberg@arm.com    // code below stolen from VectorParam<T>::parse().
13011482Sandreas.sandberg@arm.com    // it would be nice to unify these somehow...
13111482Sandreas.sandberg@arm.com
13211482Sandreas.sandberg@arm.com    vector<string> tokens;
13311482Sandreas.sandberg@arm.com
13411482Sandreas.sandberg@arm.com    tokenize(tokens, str, ' ');
13511482Sandreas.sandberg@arm.com
13611482Sandreas.sandberg@arm.com    // Need this if we were doing a vector
13711482Sandreas.sandberg@arm.com    // value.resize(tokens.size());
13811482Sandreas.sandberg@arm.com
13911482Sandreas.sandberg@arm.com    if (tokens.size() != size) {
14011482Sandreas.sandberg@arm.com        fatal("Array size mismatch on %s:%s'\n", section, name);
14111482Sandreas.sandberg@arm.com    }
14211482Sandreas.sandberg@arm.com
14311482Sandreas.sandberg@arm.com    for (int i = 0; i < tokens.size(); i++) {
14411482Sandreas.sandberg@arm.com        // need to parse into local variable to handle vector<bool>,
14511482Sandreas.sandberg@arm.com        // for which operator[] returns a special reference class
14611482Sandreas.sandberg@arm.com        // that's not the same as 'bool&', (since it's a packed
14711482Sandreas.sandberg@arm.com        // vector)
14811482Sandreas.sandberg@arm.com        T scalar_value;
14911482Sandreas.sandberg@arm.com        if (!parseParam(tokens[i], scalar_value)) {
15011482Sandreas.sandberg@arm.com            string err("could not parse \"");
15111482Sandreas.sandberg@arm.com
15211482Sandreas.sandberg@arm.com            err += str;
15311482Sandreas.sandberg@arm.com            err += "\"";
15411482Sandreas.sandberg@arm.com
15511482Sandreas.sandberg@arm.com            fatal(err);
15611482Sandreas.sandberg@arm.com        }
15711482Sandreas.sandberg@arm.com
15811482Sandreas.sandberg@arm.com        // assign parsed value to vector
15911482Sandreas.sandberg@arm.com        param[i] = scalar_value;
16011482Sandreas.sandberg@arm.com    }
16111482Sandreas.sandberg@arm.com}
16211482Sandreas.sandberg@arm.com
16311482Sandreas.sandberg@arm.com
16411482Sandreas.sandberg@arm.comvoid
16511482Sandreas.sandberg@arm.comobjParamIn(Checkpoint *cp, const std::string &section,
16611482Sandreas.sandberg@arm.com           const std::string &name, Serializeable * &param)
16711482Sandreas.sandberg@arm.com{
16811482Sandreas.sandberg@arm.com    if (!cp->findObj(section, name, param)) {
16911482Sandreas.sandberg@arm.com        fatal("Can't unserialize '%s:%s'\n", section, name);
17011482Sandreas.sandberg@arm.com    }
17111482Sandreas.sandberg@arm.com}
17211482Sandreas.sandberg@arm.com
17311482Sandreas.sandberg@arm.com
17411482Sandreas.sandberg@arm.com#define INSTANTIATE_PARAM_TEMPLATES(type)				\
17511482Sandreas.sandberg@arm.comtemplate void								\
17611482Sandreas.sandberg@arm.comparamOut(ostream &os, const std::string &name, type const &param);	\
17711482Sandreas.sandberg@arm.comtemplate void								\
17811482Sandreas.sandberg@arm.comparamIn(Checkpoint *cp, const std::string &section,			\
17911482Sandreas.sandberg@arm.com        const std::string &name, type & param);				\
18011482Sandreas.sandberg@arm.comtemplate void								\
18111482Sandreas.sandberg@arm.comarrayParamOut(ostream &os, const std::string &name,			\
18211482Sandreas.sandberg@arm.com              type const *param, int size);				\
18311482Sandreas.sandberg@arm.comtemplate void								\
18411482Sandreas.sandberg@arm.comarrayParamIn(Checkpoint *cp, const std::string &section,		\
18511482Sandreas.sandberg@arm.com             const std::string &name, type *param, int size);
18611482Sandreas.sandberg@arm.com
18711482Sandreas.sandberg@arm.com
18811482Sandreas.sandberg@arm.comINSTANTIATE_PARAM_TEMPLATES(int8_t)
18911482Sandreas.sandberg@arm.comINSTANTIATE_PARAM_TEMPLATES(uint8_t)
19011482Sandreas.sandberg@arm.comINSTANTIATE_PARAM_TEMPLATES(int16_t)
19111482Sandreas.sandberg@arm.comINSTANTIATE_PARAM_TEMPLATES(uint16_t)
19211482Sandreas.sandberg@arm.comINSTANTIATE_PARAM_TEMPLATES(int32_t)
19311482Sandreas.sandberg@arm.comINSTANTIATE_PARAM_TEMPLATES(uint32_t)
19411482Sandreas.sandberg@arm.comINSTANTIATE_PARAM_TEMPLATES(int64_t)
19511482Sandreas.sandberg@arm.comINSTANTIATE_PARAM_TEMPLATES(uint64_t)
19611482Sandreas.sandberg@arm.comINSTANTIATE_PARAM_TEMPLATES(bool)
19711482Sandreas.sandberg@arm.comINSTANTIATE_PARAM_TEMPLATES(string)
19811482Sandreas.sandberg@arm.com
19911482Sandreas.sandberg@arm.com
20011482Sandreas.sandberg@arm.com#if 0
20111482Sandreas.sandberg@arm.com// unneeded?
20211482Sandreas.sandberg@arm.comvoid
20311482Sandreas.sandberg@arm.comSerializeable::childOut(const string &name, Serializeable *child)
20411482Sandreas.sandberg@arm.com{
20511482Sandreas.sandberg@arm.com    child->mark();
20611482Sandreas.sandberg@arm.com    if (child->name() == "")
20711482Sandreas.sandberg@arm.com        panic("child is unnamed");
20811482Sandreas.sandberg@arm.com
20911482Sandreas.sandberg@arm.com    out() << name << "=" << child->name() << "\n";
21011482Sandreas.sandberg@arm.com}
21111482Sandreas.sandberg@arm.com#endif
21211482Sandreas.sandberg@arm.com
21311482Sandreas.sandberg@arm.comSerializer::Serializer()
21411482Sandreas.sandberg@arm.com{ }
21511482Sandreas.sandberg@arm.com
21611542Sandreas.sandberg@arm.comSerializer::~Serializer()
21711542Sandreas.sandberg@arm.com{ }
21811542Sandreas.sandberg@arm.com
21911482Sandreas.sandberg@arm.comostream &
22011482Sandreas.sandberg@arm.comSerializer::out() const
22111482Sandreas.sandberg@arm.com{
22211482Sandreas.sandberg@arm.com    if (!output)
22311482Sandreas.sandberg@arm.com        panic("must set output before serializing");
22411503Sandreas.sandberg@arm.com
22511503Sandreas.sandberg@arm.com    return *output;
22611503Sandreas.sandberg@arm.com}
22711503Sandreas.sandberg@arm.com
22811503Sandreas.sandberg@arm.comvoid
22911482Sandreas.sandberg@arm.comSerializer::add_object(Serializeable *obj)
23011503Sandreas.sandberg@arm.com{
23111503Sandreas.sandberg@arm.com    objects.push_back(obj);
23211503Sandreas.sandberg@arm.com}
23311503Sandreas.sandberg@arm.com
23411503Sandreas.sandberg@arm.comvoid
23511503Sandreas.sandberg@arm.comSerializer::add_objects()
23611503Sandreas.sandberg@arm.com{
23711482Sandreas.sandberg@arm.com    mainEventQueue.mark();
23811482Sandreas.sandberg@arm.com
23911482Sandreas.sandberg@arm.com    SimObject::SimObjectList::iterator i = SimObject::simObjectList.begin();
24011482Sandreas.sandberg@arm.com    SimObject::SimObjectList::iterator end = SimObject::simObjectList.end();
24111482Sandreas.sandberg@arm.com
24211482Sandreas.sandberg@arm.com    while (i != end) {
24311482Sandreas.sandberg@arm.com        (*i)->mark();
24411482Sandreas.sandberg@arm.com        ++i;
24511482Sandreas.sandberg@arm.com    }
24611482Sandreas.sandberg@arm.com}
24711482Sandreas.sandberg@arm.com
24811482Sandreas.sandberg@arm.comvoid
24911482Sandreas.sandberg@arm.comSerializer::serialize()
25011482Sandreas.sandberg@arm.com{
25111482Sandreas.sandberg@arm.com    if (Serializeable::serializer != NULL)
25211482Sandreas.sandberg@arm.com        panic("in process of serializing!");
25311482Sandreas.sandberg@arm.com
25411482Sandreas.sandberg@arm.com    Serializeable::serializer = this;
25511482Sandreas.sandberg@arm.com
25611482Sandreas.sandberg@arm.com    string dir = CheckpointDir();
25711482Sandreas.sandberg@arm.com    if (mkdir(dir.c_str(), 0775) == -1 && errno != EEXIST)
25811482Sandreas.sandberg@arm.com            warn("could mkdir %s\n", dir);
25911482Sandreas.sandberg@arm.com
26011482Sandreas.sandberg@arm.com    string cpt_file = dir + "m5.cpt";
26111482Sandreas.sandberg@arm.com    output = new ofstream(cpt_file.c_str());
26211482Sandreas.sandberg@arm.com    time_t t = time(NULL);
26311482Sandreas.sandberg@arm.com    *output << "// checkpoint generated: " << ctime(&t);
26411503Sandreas.sandberg@arm.com
26511482Sandreas.sandberg@arm.com    serlist_t list;
26611482Sandreas.sandberg@arm.com
26711482Sandreas.sandberg@arm.com    add_objects();
26811482Sandreas.sandberg@arm.com    while (!objects.empty()) {
26911482Sandreas.sandberg@arm.com        Serializeable *obj = objects.front();
27011482Sandreas.sandberg@arm.com        DPRINTF(Serialize, "Serializing %s\n", obj->name());
27111482Sandreas.sandberg@arm.com        obj->nameOut(out());
27211482Sandreas.sandberg@arm.com        obj->serialize(out());
27311482Sandreas.sandberg@arm.com        objects.pop_front();
27411482Sandreas.sandberg@arm.com        list.push_back(obj);
27511482Sandreas.sandberg@arm.com    }
27611482Sandreas.sandberg@arm.com
27711482Sandreas.sandberg@arm.com    while (!list.empty()) {
27811482Sandreas.sandberg@arm.com        list.front()->serialized = false;
27911482Sandreas.sandberg@arm.com        list.pop_front();
28011482Sandreas.sandberg@arm.com    }
28111482Sandreas.sandberg@arm.com
28211482Sandreas.sandberg@arm.com    Serializeable::serializer = NULL;
28311482Sandreas.sandberg@arm.com
28411482Sandreas.sandberg@arm.com    delete output;
28511482Sandreas.sandberg@arm.com    output = NULL;
28611482Sandreas.sandberg@arm.com}
28711482Sandreas.sandberg@arm.com
28811482Sandreas.sandberg@arm.comclass SerializeEvent : public Event
28911482Sandreas.sandberg@arm.com{
29011482Sandreas.sandberg@arm.com  protected:
29111482Sandreas.sandberg@arm.com    Tick repeat;
29211482Sandreas.sandberg@arm.com
29311482Sandreas.sandberg@arm.com  public:
29411482Sandreas.sandberg@arm.com    SerializeEvent(Tick _when, Tick _repeat);
29511482Sandreas.sandberg@arm.com    virtual void process();
29611482Sandreas.sandberg@arm.com    virtual void serialize(std::ostream &os)
29711482Sandreas.sandberg@arm.com    {
29811482Sandreas.sandberg@arm.com        panic("Cannot serialize the SerializeEvent");
29911482Sandreas.sandberg@arm.com    }
30011482Sandreas.sandberg@arm.com
30111482Sandreas.sandberg@arm.com};
30211482Sandreas.sandberg@arm.com
30311482Sandreas.sandberg@arm.comSerializeEvent::SerializeEvent(Tick _when, Tick _repeat)
30411482Sandreas.sandberg@arm.com    : Event(&mainEventQueue, 990), repeat(_repeat)
30511482Sandreas.sandberg@arm.com{
30611482Sandreas.sandberg@arm.com    setFlags(AutoDelete);
30711482Sandreas.sandberg@arm.com    schedule(_when);
30811482Sandreas.sandberg@arm.com}
30911482Sandreas.sandberg@arm.com
31011482Sandreas.sandberg@arm.comvoid
31111482Sandreas.sandberg@arm.comSerializeEvent::process()
31211482Sandreas.sandberg@arm.com{
31311482Sandreas.sandberg@arm.com    Serializer serial;
31411482Sandreas.sandberg@arm.com    serial.serialize();
31511482Sandreas.sandberg@arm.com    if (repeat)
31611482Sandreas.sandberg@arm.com        schedule(curTick + repeat);
31711482Sandreas.sandberg@arm.com}
31811482Sandreas.sandberg@arm.com
31911482Sandreas.sandberg@arm.comstring __CheckpointDirBase;
32011482Sandreas.sandberg@arm.com
32111482Sandreas.sandberg@arm.comstring
32211482Sandreas.sandberg@arm.comCheckpointDir()
32311482Sandreas.sandberg@arm.com{
32411482Sandreas.sandberg@arm.com    if (__CheckpointDirBase.empty())
32511482Sandreas.sandberg@arm.com        return __CheckpointDirBase;
32611482Sandreas.sandberg@arm.com
32711482Sandreas.sandberg@arm.com    return csprintf("%s/m5.%012d/", __CheckpointDirBase, curTick);
32811482Sandreas.sandberg@arm.com}
32911482Sandreas.sandberg@arm.com
33011482Sandreas.sandberg@arm.comvoid
33111511Sandreas.sandberg@arm.comSetupCheckpoint(Tick when, Tick period)
33211511Sandreas.sandberg@arm.com{
33311511Sandreas.sandberg@arm.com    new SerializeEvent(when, period);
33411511Sandreas.sandberg@arm.com}
33511511Sandreas.sandberg@arm.com
33611482Sandreas.sandberg@arm.comclass SerializeParamContext : public ParamContext
33711482Sandreas.sandberg@arm.com{
33811482Sandreas.sandberg@arm.com  private:
33911482Sandreas.sandberg@arm.com    SerializeEvent *event;
34011482Sandreas.sandberg@arm.com
34111482Sandreas.sandberg@arm.com  public:
34211482Sandreas.sandberg@arm.com    SerializeParamContext(const string &section);
34311482Sandreas.sandberg@arm.com    ~SerializeParamContext();
34411482Sandreas.sandberg@arm.com    void checkParams();
34511482Sandreas.sandberg@arm.com};
34611482Sandreas.sandberg@arm.com
34711482Sandreas.sandberg@arm.comSerializeParamContext serialParams("serialize");
34811482Sandreas.sandberg@arm.com
34911482Sandreas.sandberg@arm.comParam<string> serialize_dir(&serialParams,
35011482Sandreas.sandberg@arm.com                             "dir",
35111482Sandreas.sandberg@arm.com                             "dir to stick checkpoint in", ".");
35211482Sandreas.sandberg@arm.com
35311482Sandreas.sandberg@arm.comParam<Counter> serialize_cycle(&serialParams,
35411482Sandreas.sandberg@arm.com                                "cycle",
35511482Sandreas.sandberg@arm.com                                "cycle to serialize",
35611482Sandreas.sandberg@arm.com                                0);
35711482Sandreas.sandberg@arm.com
358Param<Counter> serialize_period(&serialParams,
359                                "period",
360                                "period to repeat serializations",
361                                0);
362
363
364
365SerializeParamContext::SerializeParamContext(const string &section)
366    : ParamContext(section), event(NULL)
367{ }
368
369SerializeParamContext::~SerializeParamContext()
370{
371}
372
373void
374SerializeParamContext::checkParams()
375{
376    __CheckpointDirBase = serialize_dir;
377    if (serialize_cycle > 0)
378        SetupCheckpoint(serialize_cycle, serialize_period);
379}
380
381void
382debug_serialize()
383{
384    Serializer serial;
385    serial.serialize();
386}
387
388void
389debug_serialize(Tick when)
390{
391    new SerializeEvent(when, 0);
392}
393
394////////////////////////////////////////////////////////////////////////
395//
396// SerializeableClass member definitions
397//
398////////////////////////////////////////////////////////////////////////
399
400// Map of class names to SerializeableBuilder creation functions.
401// Need to make this a pointer so we can force initialization on the
402// first reference; otherwise, some SerializeableClass constructors
403// may be invoked before the classMap constructor.
404map<string,SerializeableClass::CreateFunc> *SerializeableClass::classMap = 0;
405
406// SerializeableClass constructor: add mapping to classMap
407SerializeableClass::SerializeableClass(const string &className,
408                                       CreateFunc createFunc)
409{
410    if (classMap == NULL)
411        classMap = new map<string,SerializeableClass::CreateFunc>();
412
413    if ((*classMap)[className])
414    {
415        cerr << "Error: simulation object class " << className << " redefined"
416             << endl;
417        fatal("");
418    }
419
420    // add className --> createFunc to class map
421    (*classMap)[className] = createFunc;
422}
423
424
425//
426//
427Serializeable *
428SerializeableClass::createObject(Checkpoint *cp,
429                                 const std::string &section)
430{
431    string className;
432
433    if (!cp->find(section, "type", className)) {
434        fatal("Serializeable::create: no 'type' entry in section '%s'.\n",
435              section);
436    }
437
438    CreateFunc createFunc = (*classMap)[className];
439
440    if (createFunc == NULL) {
441        fatal("Serializeable::create: no create function for class '%s'.\n",
442              className);
443    }
444
445    Serializeable *object = createFunc(cp, section);
446
447    assert(object != NULL);
448
449    return object;
450}
451
452
453Serializeable *
454Serializeable::create(Checkpoint *cp, const std::string &section)
455{
456    Serializeable *object = SerializeableClass::createObject(cp, section);
457    object->unserialize(cp, section);
458    return object;
459}
460
461
462Checkpoint::Checkpoint(const std::string &filename, const std::string &path,
463                       const ConfigNode *_configNode)
464    : db(new IniFile), basePath(path), configNode(_configNode)
465{
466    if (!db->load(filename)) {
467        fatal("Can't load checkpoint file '%s'\n", filename);
468    }
469
470    mainEventQueue.unserialize(this, "MainEventQueue");
471}
472
473
474bool
475Checkpoint::find(const std::string &section, const std::string &entry,
476                 std::string &value)
477{
478    return db->find(section, entry, value);
479}
480
481
482bool
483Checkpoint::findObj(const std::string &section, const std::string &entry,
484                    Serializeable *&value)
485{
486    string path;
487
488    if (!db->find(section, entry, path))
489        return false;
490
491    if ((value = configNode->resolveSimObject(path)) != NULL)
492        return true;
493
494    if ((value = objMap[path]) != NULL)
495        return true;
496
497    return false;
498}
499
500
501bool
502Checkpoint::sectionExists(const std::string &section)
503{
504    return db->sectionExists(section);
505}
506