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 §ion); 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 §ion) 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