serialize.cc revision 56
19814Sandreas.hansson@arm.com/*
22292SN/A * Copyright (c) 2003 The Regents of The University of Michigan
313590Srekai.gonzalezalberquilla@arm.com * All rights reserved.
410239Sbinhpham@cs.rutgers.edu *
57597Sminkyu.jeong@arm.com * Redistribution and use in source and binary forms, with or without
67597Sminkyu.jeong@arm.com * modification, are permitted provided that the following conditions are
77597Sminkyu.jeong@arm.com * met: redistributions of source code must retain the above copyright
87597Sminkyu.jeong@arm.com * notice, this list of conditions and the following disclaimer;
97597Sminkyu.jeong@arm.com * redistributions in binary form must reproduce the above copyright
107597Sminkyu.jeong@arm.com * notice, this list of conditions and the following disclaimer in the
117597Sminkyu.jeong@arm.com * documentation and/or other materials provided with the distribution;
127597Sminkyu.jeong@arm.com * neither the name of the copyright holders nor the names of its
137597Sminkyu.jeong@arm.com * contributors may be used to endorse or promote products derived from
147597Sminkyu.jeong@arm.com * this software without specific prior written permission.
157597Sminkyu.jeong@arm.com *
162292SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172292SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182292SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192292SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202292SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212292SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222292SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232292SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242292SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252292SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262292SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272292SN/A */
282292SN/A
292292SN/A#include <sys/time.h>
302292SN/A
312292SN/A#include <fstream>
322292SN/A#include <list>
332292SN/A#include <string>
342292SN/A#include <vector>
352292SN/A
362292SN/A#include "base/misc.hh"
372292SN/A
382292SN/A#include "sim/eventq.hh"
392292SN/A#include "sim/param.hh"
402292SN/A#include "sim/serialize.hh"
412689Sktlim@umich.edu#include "base/inifile.hh"
422689Sktlim@umich.edu#include "sim/sim_events.hh"
432689Sktlim@umich.edu#include "sim/sim_object.hh"
442292SN/A#include "base/trace.hh"
452292SN/A
469944Smatt.horsnell@ARM.comusing namespace std;
479944Smatt.horsnell@ARM.com
489944Smatt.horsnell@ARM.comSerializer *Serializeable::serializer = NULL;
498591Sgblack@eecs.umich.edu
503326Sktlim@umich.eduSerializeable::Serializeable(const string &n)
518229Snate@binkert.org    : proxy(this), objName(n), serialized(false)
526658Snate@binkert.org{ }
538887Sgeoffrey.blake@arm.com
542907Sktlim@umich.eduSerializeable::~Serializeable()
552292SN/A{ }
568232Snate@binkert.org
578232Snate@binkert.orgvoid
588232Snate@binkert.orgSerializeable::mark()
599527SMatt.Horsnell@arm.com{
602722Sktlim@umich.edu    if (!serialized)
612669Sktlim@umich.edu        serializer->add_object(this);
622292SN/A
632669Sktlim@umich.edu    serialized = true;
6413429Srekai.gonzalezalberquilla@arm.com}
6513429Srekai.gonzalezalberquilla@arm.com
668581Ssteve.reinhardt@amd.comostream &
678581Ssteve.reinhardt@amd.comSerializeable::out() const
682292SN/A{
6913590Srekai.gonzalezalberquilla@arm.com    return serializer->out();
7013590Srekai.gonzalezalberquilla@arm.com}
712292SN/A
722292SN/Avoid
732669Sktlim@umich.eduSerializeable::nameOut()
742292SN/A{
752678Sktlim@umich.edu    out() << "\n[" << name() << "]\n";
762292SN/A}
779444SAndreas.Sandberg@ARM.com
789444SAndreas.Sandberg@ARM.comvoid
799444SAndreas.Sandberg@ARM.comSerializeable::nameOut(const string &_name)
804319Sktlim@umich.edu{
8113590Srekai.gonzalezalberquilla@arm.com    out() << "\n[" << _name << "]\n";
8213590Srekai.gonzalezalberquilla@arm.com}
832678Sktlim@umich.edu
842678Sktlim@umich.edutemplate<> void
852292SN/ASerializeable::paramOut(const string &name, const uint64_t& param)
862678Sktlim@umich.edu{
872678Sktlim@umich.edu    out() << name << "=0x" << hex << param << dec << "\n";
885336Shines@cs.fsu.edu}
892678Sktlim@umich.edu
904873Sstever@eecs.umich.eduvoid
912678Sktlim@umich.eduSerializeable::childOut(const string &name, Serializeable *child)
922292SN/A{
9313590Srekai.gonzalezalberquilla@arm.com    child->mark();
9413590Srekai.gonzalezalberquilla@arm.com    if (child->name() == "")
9513590Srekai.gonzalezalberquilla@arm.com        panic("child is unnamed");
9613590Srekai.gonzalezalberquilla@arm.com
9713590Srekai.gonzalezalberquilla@arm.com    out() << name << "=" << child->name() << "\n";
9813590Srekai.gonzalezalberquilla@arm.com}
9913590Srekai.gonzalezalberquilla@arm.com
10013590Srekai.gonzalezalberquilla@arm.comvoid
10113590Srekai.gonzalezalberquilla@arm.comSerializeable::setName(const string &name)
10213590Srekai.gonzalezalberquilla@arm.com{
10313590Srekai.gonzalezalberquilla@arm.com    if (objName != "")
10413590Srekai.gonzalezalberquilla@arm.com        panic("Cannot change object name");
10513590Srekai.gonzalezalberquilla@arm.com
10613590Srekai.gonzalezalberquilla@arm.com    objName = name;
10713590Srekai.gonzalezalberquilla@arm.com}
10813590Srekai.gonzalezalberquilla@arm.com
10913590Srekai.gonzalezalberquilla@arm.comSerializer::Serializer()
11013590Srekai.gonzalezalberquilla@arm.com{ }
1112678Sktlim@umich.edu
1122678Sktlim@umich.eduSerializer::~Serializer()
1132678Sktlim@umich.edu{ }
1142678Sktlim@umich.edu
1152678Sktlim@umich.eduostream &
1162678Sktlim@umich.eduSerializer::out() const
1172344SN/A{
11813590Srekai.gonzalezalberquilla@arm.com    if (!output)
1192678Sktlim@umich.edu        panic("must set output before serializing");
12013590Srekai.gonzalezalberquilla@arm.com
12113590Srekai.gonzalezalberquilla@arm.com    return *output;
12213590Srekai.gonzalezalberquilla@arm.com}
1236974Stjones1@inf.ed.ac.uk
1249444SAndreas.Sandberg@ARM.comvoid
12510327Smitch.hayenga@arm.comSerializer::add_object(Serializeable *obj)
12613590Srekai.gonzalezalberquilla@arm.com{
12713652Sqtt2@cornell.edu    objects.push_back(obj);
12812216Snikos.nikoleris@arm.com}
12913652Sqtt2@cornell.edu
13013652Sqtt2@cornell.eduvoid
13113590Srekai.gonzalezalberquilla@arm.comSerializer::add_objects()
13213652Sqtt2@cornell.edu{
13313590Srekai.gonzalezalberquilla@arm.com    mainEventQueue.mark();
13413590Srekai.gonzalezalberquilla@arm.com
13513590Srekai.gonzalezalberquilla@arm.com    SimObject::SimObjectList::iterator i = SimObject::simObjectList.begin();
1366974Stjones1@inf.ed.ac.uk    SimObject::SimObjectList::iterator end = SimObject::simObjectList.end();
13713590Srekai.gonzalezalberquilla@arm.com
13813652Sqtt2@cornell.edu    while (i != end) {
13913652Sqtt2@cornell.edu        (*i)->mark();
14013590Srekai.gonzalezalberquilla@arm.com        ++i;
1412678Sktlim@umich.edu    }
1422344SN/A}
1432292SN/A
1442292SN/Avoid
1452292SN/ASerializer::serialize(const string &f)
14613472Srekai.gonzalezalberquilla@arm.com{
14713472Srekai.gonzalezalberquilla@arm.com    if (Serializeable::serializer != NULL)
14813472Srekai.gonzalezalberquilla@arm.com        panic("in process of serializing!");
14913590Srekai.gonzalezalberquilla@arm.com
15013590Srekai.gonzalezalberquilla@arm.com    Serializeable::serializer = this;
1512292SN/A
1522292SN/A    file = f;
1532292SN/A    string cpt_file = file + ".cpt";
1542292SN/A    output = new ofstream(cpt_file.c_str());
1552292SN/A    time_t t = time(NULL);
1565529Snate@binkert.org    *output << "// checkpoint generated: " << ctime(&t);
15713472Srekai.gonzalezalberquilla@arm.com
1582292SN/A    serlist_t list;
15913472Srekai.gonzalezalberquilla@arm.com
16013472Srekai.gonzalezalberquilla@arm.com    add_objects();
1614329Sktlim@umich.edu    while (!objects.empty()) {
1624329Sktlim@umich.edu        Serializeable *serial = objects.front();
1634329Sktlim@umich.edu        DPRINTF(Serialize, "Name Children of %s\n", serial->name());
1642907Sktlim@umich.edu        serial->nameChildren();
1652907Sktlim@umich.edu        objects.pop_front();
16613472Srekai.gonzalezalberquilla@arm.com        list.push_back(serial);
1672292SN/A    }
1688199SAli.Saidi@ARM.com
1698199SAli.Saidi@ARM.com    while (!list.empty()) {
1709444SAndreas.Sandberg@ARM.com        list.front()->serialized = false;
1719444SAndreas.Sandberg@ARM.com        list.pop_front();
1729444SAndreas.Sandberg@ARM.com    }
1739444SAndreas.Sandberg@ARM.com
1749444SAndreas.Sandberg@ARM.com    add_objects();
1759444SAndreas.Sandberg@ARM.com    while (!objects.empty()) {
1769444SAndreas.Sandberg@ARM.com        Serializeable *serial = objects.front();
1779444SAndreas.Sandberg@ARM.com        DPRINTF(Serialize, "Name Children of %s\n", serial->name());
1789444SAndreas.Sandberg@ARM.com        serial->serialize();
1799444SAndreas.Sandberg@ARM.com        objects.pop_front();
1809444SAndreas.Sandberg@ARM.com        list.push_back(serial);
1818199SAli.Saidi@ARM.com    }
1822292SN/A
18313590Srekai.gonzalezalberquilla@arm.com    while (!list.empty()) {
1842292SN/A        list.front()->serialized = false;
1853492Sktlim@umich.edu        list.pop_front();
1862329SN/A    }
1872292SN/A
1889444SAndreas.Sandberg@ARM.com    Serializeable::serializer = NULL;
1899444SAndreas.Sandberg@ARM.com
1909814Sandreas.hansson@arm.com    delete output;
1912292SN/A    output = NULL;
1922292SN/A    file = "";
1932292SN/A}
1942292SN/A
1952292SN/Aclass SerializeEvent : public Event
1962292SN/A{
1972292SN/A  protected:
1982292SN/A    string file;
1992292SN/A
20010386Sandreas.hansson@arm.com  public:
2012292SN/A    SerializeEvent(EventQueue *q, Tick when, const string &file);
2022292SN/A    ~SerializeEvent();
2032292SN/A
2042292SN/A    virtual void process();
2052292SN/A    virtual void serialize();
2062727Sktlim@umich.edu};
2072727Sktlim@umich.edu
2082727Sktlim@umich.eduSerializeEvent::SerializeEvent(EventQueue *q, Tick when, const string &f)
2092727Sktlim@umich.edu    : Event(q), file(f)
2102727Sktlim@umich.edu{
2112727Sktlim@umich.edu    setFlags(AutoDelete);
2122727Sktlim@umich.edu    schedule(when);
2132727Sktlim@umich.edu}
2142727Sktlim@umich.edu
2152727Sktlim@umich.eduSerializeEvent::~SerializeEvent()
2162727Sktlim@umich.edu{
2172727Sktlim@umich.edu}
2182727Sktlim@umich.edu
2192727Sktlim@umich.eduvoid
2202727Sktlim@umich.eduSerializeEvent::process()
2212727Sktlim@umich.edu{
2222727Sktlim@umich.edu    Serializer serial;
2232727Sktlim@umich.edu    serial.serialize(file);
2242361SN/A    new SimExitEvent("Serialization caused exit");
2252361SN/A}
2262361SN/A
2272361SN/Avoid
2282727Sktlim@umich.eduSerializeEvent::serialize()
2292727Sktlim@umich.edu{
2302727Sktlim@umich.edu    panic("Cannot serialize the SerializeEvent");
2312727Sktlim@umich.edu}
2322727Sktlim@umich.edu
2332727Sktlim@umich.educlass SerializeParamContext : public ParamContext
2342727Sktlim@umich.edu{
2352727Sktlim@umich.edu  private:
2362727Sktlim@umich.edu    SerializeEvent *event;
2372727Sktlim@umich.edu
2382727Sktlim@umich.edu  public:
2392727Sktlim@umich.edu    SerializeParamContext(const string &section);
2402727Sktlim@umich.edu    ~SerializeParamContext();
2412727Sktlim@umich.edu    void checkParams();
2422727Sktlim@umich.edu};
2432727Sktlim@umich.edu
2442727Sktlim@umich.eduSerializeParamContext serialParams("serialize");
2452727Sktlim@umich.edu
2462727Sktlim@umich.eduParam<Counter> serialize_cycle(&serialParams,
2472727Sktlim@umich.edu                                "cycle",
2482727Sktlim@umich.edu                                "cycle to serialize",
2492727Sktlim@umich.edu                                0);
2502727Sktlim@umich.edu
2518922Swilliam.wang@arm.comParam<string> serialize_file(&serialParams,
2524329Sktlim@umich.edu                             "file",
2534329Sktlim@umich.edu                             "file to write to", "");
2544329Sktlim@umich.edu
2554329Sktlim@umich.eduSerializeParamContext::SerializeParamContext(const string &section)
2564329Sktlim@umich.edu    : ParamContext(section), event(NULL)
2574329Sktlim@umich.edu{ }
2589444SAndreas.Sandberg@ARM.com
2592307SN/ASerializeParamContext::~SerializeParamContext()
26013590Srekai.gonzalezalberquilla@arm.com{
26113590Srekai.gonzalezalberquilla@arm.com}
2622307SN/A
2632329SN/Avoid
2649444SAndreas.Sandberg@ARM.comSerializeParamContext::checkParams()
2652307SN/A{
2662307SN/A    if (!((string)serialize_file).empty() && serialize_cycle > 0)
2672307SN/A    event = new SerializeEvent(&mainEventQueue, serialize_cycle,
2682307SN/A                               serialize_file);
2692307SN/A}
2702307SN/A
2719444SAndreas.Sandberg@ARM.comvoid
2722307SN/Adebug_serialize(const char *file)
2732307SN/A{
2742292SN/A    Serializer serial;
2752292SN/A    serial.serialize(file);
27613429Srekai.gonzalezalberquilla@arm.com    new SimExitEvent("Serialization caused exit");
2772292SN/A}
2782292SN/A
2792292SN/A
28013652Sqtt2@cornell.edu
2812292SN/A
2822292SN/A////////////////////////////////////////////////////////////////////////
2832292SN/A//
2842292SN/A// SerializeableClass member definitions
2852292SN/A//
2862292SN/A////////////////////////////////////////////////////////////////////////
2872292SN/A
2882292SN/A// Map of class names to SerializeableBuilder creation functions.
2892292SN/A// Need to make this a pointer so we can force initialization on the
2902292SN/A// first reference; otherwise, some SerializeableClass constructors
2912292SN/A// may be invoked before the classMap constructor.
2922292SN/Amap<string,SerializeableClass::CreateFunc> *SerializeableClass::classMap = 0;
29313429Srekai.gonzalezalberquilla@arm.com
2942292SN/A// SerializeableClass constructor: add mapping to classMap
29513590Srekai.gonzalezalberquilla@arm.comSerializeableClass::SerializeableClass(const string &className,
29613590Srekai.gonzalezalberquilla@arm.com                                       CreateFunc createFunc)
2972292SN/A{
2987720Sgblack@eecs.umich.edu    if (classMap == NULL)
29913590Srekai.gonzalezalberquilla@arm.com        classMap = new map<string,SerializeableClass::CreateFunc>();
3002292SN/A
30113590Srekai.gonzalezalberquilla@arm.com    if ((*classMap)[className])
30213590Srekai.gonzalezalberquilla@arm.com    {
3032292SN/A        cerr << "Error: simulation object class " << className << " redefined"
30413590Srekai.gonzalezalberquilla@arm.com             << endl;
3052292SN/A        fatal("");
30613590Srekai.gonzalezalberquilla@arm.com    }
30713590Srekai.gonzalezalberquilla@arm.com
30813590Srekai.gonzalezalberquilla@arm.com    // add className --> createFunc to class map
30913590Srekai.gonzalezalberquilla@arm.com    (*classMap)[className] = createFunc;
3102292SN/A}
3112292SN/A
3122292SN/A
3132292SN/A//
3142292SN/A//
3152292SN/ASerializeable *
31613590Srekai.gonzalezalberquilla@arm.comSerializeableClass::createObject(IniFile &configDB,
3172292SN/A                                 const string &configClassName)
3182292SN/A{
31913590Srekai.gonzalezalberquilla@arm.com    // find simulation object class name from configuration class
32013590Srekai.gonzalezalberquilla@arm.com    // (specified by 'type=' parameter)
3212292SN/A    string simObjClassName;
3227720Sgblack@eecs.umich.edu
32313590Srekai.gonzalezalberquilla@arm.com    if (!configDB.findDefault(configClassName, "type", simObjClassName)) {
32413590Srekai.gonzalezalberquilla@arm.com        cerr << "Configuration class '" << configClassName << "' not found."
3252292SN/A             << endl;
32613590Srekai.gonzalezalberquilla@arm.com        abort();
32713590Srekai.gonzalezalberquilla@arm.com    }
32813590Srekai.gonzalezalberquilla@arm.com
3292292SN/A    // look up className to get appropriate createFunc
33013590Srekai.gonzalezalberquilla@arm.com    if (classMap->find(simObjClassName) == classMap->end()) {
3312292SN/A        cerr << "Simulator object class '" << simObjClassName << "' not found."
3322292SN/A             << endl;
3332292SN/A        abort();
3342292SN/A    }
3352292SN/A
3362292SN/A    CreateFunc createFunc = (*classMap)[simObjClassName];
3372292SN/A
3382292SN/A    // builder instance
3392292SN/A    SerializeableBuilder *objectBuilder = (*createFunc)();
3402292SN/A
3412292SN/A    assert(objectBuilder != NULL);
3422292SN/A
3432292SN/A    // now create the actual simulation object
3442292SN/A    Serializeable *object = objectBuilder->create();
3452292SN/A
3462292SN/A    assert(object != NULL);
3472292SN/A
34810239Sbinhpham@cs.rutgers.edu    // done with the SerializeableBuilder now
3492292SN/A    delete objectBuilder;
35010239Sbinhpham@cs.rutgers.edu
35110239Sbinhpham@cs.rutgers.edu    return object;
35213590Srekai.gonzalezalberquilla@arm.com}
35313590Srekai.gonzalezalberquilla@arm.com
35413590Srekai.gonzalezalberquilla@arm.com