Revamp serialization to make it easier.
--HG-- extra : convert_revision : c57a538d7cf606dbdf5fa244f92da46bd830e335
This commit is contained in:
parent
cec7f73abf
commit
b90f810575
15 changed files with 262 additions and 177 deletions
|
@ -192,13 +192,13 @@ AlphaTlb::flushAddr(Addr vaddr, uint8_t asn)
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AlphaTlb::serialize()
|
AlphaTlb::serialize(ostream &os)
|
||||||
{
|
{
|
||||||
nameOut();
|
SERIALIZE_MEMBER(size);
|
||||||
|
SERIALIZE_MEMBER(nlu);
|
||||||
paramOut("size", size);
|
|
||||||
paramOut("nlu", nlu);
|
|
||||||
|
|
||||||
|
// should just add serialize/unserialize methods to AlphaPTE
|
||||||
|
#if 0
|
||||||
stringstream buf;
|
stringstream buf;
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
buf.str("");
|
buf.str("");
|
||||||
|
@ -237,19 +237,18 @@ AlphaTlb::serialize()
|
||||||
ccprintf(buf, "pte%02d.asn", i);
|
ccprintf(buf, "pte%02d.asn", i);
|
||||||
paramOut(buf.str(), table[i].asn);
|
paramOut(buf.str(), table[i].asn);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AlphaTlb::unserialize(IniFile &db, const string &category, ConfigNode *node)
|
AlphaTlb::unserialize(IniFile &db, const string §ion)
|
||||||
{
|
{
|
||||||
|
UNSERIALIZE_MEMBER(size);
|
||||||
|
UNSERIALIZE_MEMBER(nlu);
|
||||||
|
|
||||||
|
#if 0
|
||||||
string data;
|
string data;
|
||||||
stringstream buf;
|
stringstream buf;
|
||||||
|
|
||||||
db.findDefault(category,"size",data);
|
|
||||||
to_number(data,size);
|
|
||||||
db.findDefault(category,"nlu",data);
|
|
||||||
to_number(data,nlu);
|
|
||||||
|
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
buf.str("");
|
buf.str("");
|
||||||
ccprintf(buf, "pte%02d.valid", i);
|
ccprintf(buf, "pte%02d.valid", i);
|
||||||
|
@ -296,6 +295,7 @@ AlphaTlb::unserialize(IniFile &db, const string &category, ConfigNode *node)
|
||||||
db.findDefault(category, buf.str(), data);
|
db.findDefault(category, buf.str(), data);
|
||||||
to_number(data, table[i].asn);
|
to_number(data, table[i].asn);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -73,9 +73,8 @@ class AlphaTlb : public SimObject
|
||||||
static void checkCacheability(MemReqPtr req);
|
static void checkCacheability(MemReqPtr req);
|
||||||
|
|
||||||
// Checkpointing
|
// Checkpointing
|
||||||
virtual void serialize();
|
virtual void serialize(std::ostream &os);
|
||||||
virtual void unserialize(IniFile &db, const std::string &category,
|
virtual void unserialize(IniFile &db, const std::string §ion);
|
||||||
ConfigNode *node);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -97,6 +97,22 @@ ExecContext::takeOverFrom(ExecContext *oldContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ExecContext::serialize(ostream &os)
|
||||||
|
{
|
||||||
|
SERIALIZE_ARRAY(regs.intRegFile, NumIntRegs);
|
||||||
|
SERIALIZE_ARRAY(regs.floatRegFile.q, NumFloatRegs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ExecContext::unserialize(IniFile &db, const std::string §ion)
|
||||||
|
{
|
||||||
|
UNSERIALIZE_ARRAY(regs.intRegFile, NumIntRegs);
|
||||||
|
UNSERIALIZE_ARRAY(regs.floatRegFile.q, NumFloatRegs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ExecContext::setStatus(Status new_status)
|
ExecContext::setStatus(Status new_status)
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
|
|
||||||
#include "sim/host.hh"
|
#include "sim/host.hh"
|
||||||
#include "mem/mem_req.hh"
|
#include "mem/mem_req.hh"
|
||||||
|
#include "sim/serialize.hh"
|
||||||
|
|
||||||
// forward declaration: see functional_memory.hh
|
// forward declaration: see functional_memory.hh
|
||||||
class FunctionalMemory;
|
class FunctionalMemory;
|
||||||
|
@ -140,6 +141,9 @@ class ExecContext
|
||||||
|
|
||||||
void regStats(const std::string &name);
|
void regStats(const std::string &name);
|
||||||
|
|
||||||
|
void serialize(std::ostream &os);
|
||||||
|
void unserialize(IniFile &db, const std::string §ion);
|
||||||
|
|
||||||
#ifdef FULL_SYSTEM
|
#ifdef FULL_SYSTEM
|
||||||
bool validInstAddr(Addr addr) { return true; }
|
bool validInstAddr(Addr addr) { return true; }
|
||||||
bool validDataAddr(Addr addr) { return true; }
|
bool validDataAddr(Addr addr) { return true; }
|
||||||
|
|
|
@ -240,34 +240,13 @@ SimpleCPU::regStats()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SimpleCPU::serialize()
|
SimpleCPU::serialize(ostream &os)
|
||||||
{
|
{
|
||||||
nameOut();
|
xc->serialize(os);
|
||||||
|
|
||||||
#ifdef FULL_SYSTEM
|
|
||||||
#if 0
|
|
||||||
// do we need this anymore?? egh
|
|
||||||
childOut("itb", xc->itb);
|
|
||||||
childOut("dtb", xc->dtb);
|
|
||||||
childOut("physmem", physmem);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (int i = 0; i < NumIntRegs; i++) {
|
|
||||||
stringstream buf;
|
|
||||||
ccprintf(buf, "R%02d", i);
|
|
||||||
paramOut(buf.str(), xc->regs.intRegFile[i]);
|
|
||||||
}
|
|
||||||
for (int i = 0; i < NumFloatRegs; i++) {
|
|
||||||
stringstream buf;
|
|
||||||
ccprintf(buf, "F%02d", i);
|
|
||||||
paramOut(buf.str(), xc->regs.floatRegFile.q[i]);
|
|
||||||
}
|
|
||||||
// CPUTraitsType::serializeSpecialRegs(getProxy(), xc->regs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SimpleCPU::unserialize(IniFile &db, const string &category, ConfigNode *node)
|
SimpleCPU::unserialize(IniFile &db, const string &category)
|
||||||
{
|
{
|
||||||
string data;
|
string data;
|
||||||
|
|
||||||
|
|
|
@ -259,9 +259,8 @@ class SimpleCPU : public BaseCPU
|
||||||
|
|
||||||
void processCacheCompletion();
|
void processCacheCompletion();
|
||||||
|
|
||||||
virtual void serialize();
|
virtual void serialize(std::ostream &os);
|
||||||
virtual void unserialize(IniFile &db, const std::string &category,
|
virtual void unserialize(IniFile &db, const std::string §ion);
|
||||||
ConfigNode *node);
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
Fault read(Addr addr, T& data, unsigned flags);
|
Fault read(Addr addr, T& data, unsigned flags);
|
||||||
|
|
|
@ -41,6 +41,11 @@ typedef uint64 UINT64;
|
||||||
#else
|
#else
|
||||||
typedef uint32_t UINT32;
|
typedef uint32_t UINT32;
|
||||||
typedef uint64_t UINT64;
|
typedef uint64_t UINT64;
|
||||||
|
|
||||||
|
#include <ostream>
|
||||||
|
#include <string>
|
||||||
|
class IniFile;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// This structure hacked up from simos
|
// This structure hacked up from simos
|
||||||
|
@ -74,6 +79,11 @@ struct AlphaAccess
|
||||||
UINT64 bootStrapImpure; // 70:
|
UINT64 bootStrapImpure; // 70:
|
||||||
UINT32 bootStrapCPU; // 78:
|
UINT32 bootStrapCPU; // 78:
|
||||||
UINT32 align2; // 7C: Dummy placeholder for alignment
|
UINT32 align2; // 7C: Dummy placeholder for alignment
|
||||||
|
|
||||||
|
#ifndef CONSOLE
|
||||||
|
void serialize(std::ostream &os);
|
||||||
|
void unserialize(IniFile &db, const std::string §ion);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __ALPHA_ACCESS_H__
|
#endif // __ALPHA_ACCESS_H__
|
||||||
|
|
|
@ -166,70 +166,59 @@ AlphaConsole::write(MemReqPtr req, const uint8_t *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AlphaConsole::serialize()
|
AlphaAccess::serialize(ostream &os)
|
||||||
{
|
{
|
||||||
nameOut();
|
SERIALIZE_MEMBER(last_offset);
|
||||||
// assumes full AlphaAccess size
|
SERIALIZE_MEMBER(version);
|
||||||
// might have unnecessary fields here
|
SERIALIZE_MEMBER(numCPUs);
|
||||||
paramOut("last_offset",alphaAccess->last_offset);
|
SERIALIZE_MEMBER(mem_size);
|
||||||
paramOut("version",alphaAccess->version);
|
SERIALIZE_MEMBER(cpuClock);
|
||||||
paramOut("numCPUs",alphaAccess->numCPUs);
|
SERIALIZE_MEMBER(intrClockFrequency);
|
||||||
paramOut("mem_size",alphaAccess->mem_size);
|
SERIALIZE_MEMBER(kernStart);
|
||||||
paramOut("cpuClock",alphaAccess->cpuClock);
|
SERIALIZE_MEMBER(kernEnd);
|
||||||
paramOut("intrClockFrequency",alphaAccess->intrClockFrequency);
|
SERIALIZE_MEMBER(entryPoint);
|
||||||
paramOut("kernStart",alphaAccess->kernStart);
|
SERIALIZE_MEMBER(diskUnit);
|
||||||
paramOut("kernEnd",alphaAccess->kernEnd);
|
SERIALIZE_MEMBER(diskCount);
|
||||||
paramOut("entryPoint",alphaAccess->entryPoint);
|
SERIALIZE_MEMBER(diskPAddr);
|
||||||
paramOut("diskUnit",alphaAccess->diskUnit);
|
SERIALIZE_MEMBER(diskBlock);
|
||||||
paramOut("diskCount",alphaAccess->diskCount);
|
SERIALIZE_MEMBER(diskOperation);
|
||||||
paramOut("diskPAddr",alphaAccess->diskPAddr);
|
SERIALIZE_MEMBER(outputChar);
|
||||||
paramOut("diskBlock",alphaAccess->diskBlock);
|
SERIALIZE_MEMBER(bootStrapImpure);
|
||||||
paramOut("diskOperation",alphaAccess->diskOperation);
|
SERIALIZE_MEMBER(bootStrapCPU);
|
||||||
paramOut("outputChar",alphaAccess->outputChar);
|
|
||||||
paramOut("bootStrapImpure",alphaAccess->bootStrapImpure);
|
|
||||||
paramOut("bootStrapCPU",alphaAccess->bootStrapCPU);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AlphaConsole::unserialize(IniFile &db, const std::string &category,
|
AlphaAccess::unserialize(IniFile &db, const std::string §ion)
|
||||||
ConfigNode *node)
|
|
||||||
{
|
{
|
||||||
string data;
|
UNSERIALIZE_MEMBER(last_offset);
|
||||||
db.findDefault(category,"last_offset",data);
|
UNSERIALIZE_MEMBER(version);
|
||||||
to_number(data,alphaAccess->last_offset);
|
UNSERIALIZE_MEMBER(numCPUs);
|
||||||
db.findDefault(category,"version",data);
|
UNSERIALIZE_MEMBER(mem_size);
|
||||||
to_number(data,alphaAccess->version);
|
UNSERIALIZE_MEMBER(cpuClock);
|
||||||
db.findDefault(category,"numCPUs",data);
|
UNSERIALIZE_MEMBER(intrClockFrequency);
|
||||||
to_number(data,alphaAccess->numCPUs);
|
UNSERIALIZE_MEMBER(kernStart);
|
||||||
db.findDefault(category,"mem_size",data);
|
UNSERIALIZE_MEMBER(kernEnd);
|
||||||
to_number(data,alphaAccess->mem_size);
|
UNSERIALIZE_MEMBER(entryPoint);
|
||||||
db.findDefault(category,"cpuClock",data);
|
UNSERIALIZE_MEMBER(diskUnit);
|
||||||
to_number(data,alphaAccess->cpuClock);
|
UNSERIALIZE_MEMBER(diskCount);
|
||||||
db.findDefault(category,"intrClockFrequency",data);
|
UNSERIALIZE_MEMBER(diskPAddr);
|
||||||
to_number(data,alphaAccess->intrClockFrequency);
|
UNSERIALIZE_MEMBER(diskBlock);
|
||||||
db.findDefault(category,"kernStart",data);
|
UNSERIALIZE_MEMBER(diskOperation);
|
||||||
to_number(data,alphaAccess->kernStart);
|
UNSERIALIZE_MEMBER(outputChar);
|
||||||
db.findDefault(category,"kernEnd",data);
|
UNSERIALIZE_MEMBER(bootStrapImpure);
|
||||||
to_number(data,alphaAccess->kernEnd);
|
UNSERIALIZE_MEMBER(bootStrapCPU);
|
||||||
db.findDefault(category,"entryPoint",data);
|
}
|
||||||
to_number(data,alphaAccess->entryPoint);
|
|
||||||
db.findDefault(category,"diskUnit",data);
|
|
||||||
to_number(data,alphaAccess->diskUnit);
|
|
||||||
db.findDefault(category,"diskCount",data);
|
|
||||||
to_number(data,alphaAccess->diskCount);
|
|
||||||
db.findDefault(category,"diskPAddr",data);
|
|
||||||
to_number(data,alphaAccess->diskPAddr);
|
|
||||||
db.findDefault(category,"diskBlock",data);
|
|
||||||
to_number(data,alphaAccess->diskBlock);
|
|
||||||
db.findDefault(category,"diskOperation",data);
|
|
||||||
to_number(data,alphaAccess->diskOperation);
|
|
||||||
db.findDefault(category,"outputChar",data);
|
|
||||||
to_number(data,alphaAccess->outputChar);
|
|
||||||
db.findDefault(category,"bootStrapImpure",data);
|
|
||||||
to_number(data,alphaAccess->bootStrapImpure);
|
|
||||||
db.findDefault(category,"bootStrapCPU",data);
|
|
||||||
to_number(data,alphaAccess->bootStrapCPU);
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AlphaConsole::serialize(ostream &os)
|
||||||
|
{
|
||||||
|
alphaAccess->serialize(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AlphaConsole::unserialize(IniFile &db, const std::string §ion)
|
||||||
|
{
|
||||||
|
alphaAccess->unserialize(db, section);
|
||||||
}
|
}
|
||||||
|
|
||||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)
|
BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)
|
||||||
|
|
|
@ -100,9 +100,8 @@ class AlphaConsole : public MmapDevice
|
||||||
/**
|
/**
|
||||||
* standard serialization routines for checkpointing
|
* standard serialization routines for checkpointing
|
||||||
*/
|
*/
|
||||||
virtual void serialize();
|
virtual void serialize(std::ostream &os);
|
||||||
virtual void unserialize(IniFile &db, const std::string &category,
|
virtual void unserialize(IniFile &db, const std::string §ion);
|
||||||
ConfigNode *node);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __ALPHA_CONSOLE_HH__
|
#endif // __ALPHA_CONSOLE_HH__
|
||||||
|
|
|
@ -314,14 +314,13 @@ SimConsole::setInt(int bits)
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SimConsole::serialize()
|
SimConsole::serialize(ostream &os)
|
||||||
{
|
{
|
||||||
panic("Unimplemented");
|
panic("Unimplemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SimConsole::unserialize(IniFile &db, const std::string &category,
|
SimConsole::unserialize(IniFile &db, const std::string §ion)
|
||||||
ConfigNode *node)
|
|
||||||
{
|
{
|
||||||
panic("Unimplemented");
|
panic("Unimplemented");
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,9 +128,8 @@ class SimConsole : public SimObject
|
||||||
void initInt(IntrControl *i);
|
void initInt(IntrControl *i);
|
||||||
void setInt(int bits);
|
void setInt(int bits);
|
||||||
|
|
||||||
virtual void serialize();
|
virtual void serialize(std::ostream &os);
|
||||||
virtual void unserialize(IniFile &db, const std::string &category,
|
virtual void unserialize(IniFile &db, const std::string §ion);
|
||||||
ConfigNode *node);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConsoleListener : public SimObject
|
class ConsoleListener : public SimObject
|
||||||
|
|
|
@ -134,7 +134,7 @@ EventQueue::nameChildren()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
EventQueue::serialize()
|
EventQueue::serialize(ostream &os)
|
||||||
{
|
{
|
||||||
string objects = "";
|
string objects = "";
|
||||||
|
|
||||||
|
@ -142,12 +142,12 @@ EventQueue::serialize()
|
||||||
while (event) {
|
while (event) {
|
||||||
objects += event->name();
|
objects += event->name();
|
||||||
objects += " ";
|
objects += " ";
|
||||||
event->serialize();
|
event->serialize(os);
|
||||||
|
|
||||||
event = event->next;
|
event = event->next;
|
||||||
}
|
}
|
||||||
nameOut("Serialized");
|
nameOut(os, "Serialized");
|
||||||
paramOut("objects",objects);
|
SERIALIZE_MEMBER(objects);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -246,7 +246,7 @@ class EventQueue : public Serializeable
|
||||||
Tick nextEventTime() { return empty() ? curTick : head->when(); }
|
Tick nextEventTime() { return empty() ? curTick : head->when(); }
|
||||||
|
|
||||||
virtual void nameChildren();
|
virtual void nameChildren();
|
||||||
virtual void serialize();
|
virtual void serialize(std::ostream &os);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
138
sim/serialize.cc
138
sim/serialize.cc
|
@ -34,6 +34,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "base/misc.hh"
|
#include "base/misc.hh"
|
||||||
|
#include "base/str.hh"
|
||||||
|
|
||||||
#include "sim/eventq.hh"
|
#include "sim/eventq.hh"
|
||||||
#include "sim/param.hh"
|
#include "sim/param.hh"
|
||||||
|
@ -48,7 +49,7 @@ using namespace std;
|
||||||
Serializer *Serializeable::serializer = NULL;
|
Serializer *Serializeable::serializer = NULL;
|
||||||
|
|
||||||
Serializeable::Serializeable(const string &n)
|
Serializeable::Serializeable(const string &n)
|
||||||
: proxy(this), objName(n), serialized(false)
|
: objName(n), serialized(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Serializeable::~Serializeable()
|
Serializeable::~Serializeable()
|
||||||
|
@ -63,30 +64,131 @@ Serializeable::mark()
|
||||||
serialized = true;
|
serialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ostream &
|
void
|
||||||
Serializeable::out() const
|
Serializeable::nameOut(ostream &os)
|
||||||
{
|
{
|
||||||
return serializer->out();
|
os << "\n[" << name() << "]\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Serializeable::nameOut()
|
Serializeable::nameOut(ostream &os, const string &_name)
|
||||||
{
|
{
|
||||||
out() << "\n[" << name() << "]\n";
|
os << "\n[" << _name << "]\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T> bool parseParam(const std::string &str, T &data);
|
||||||
|
template <class T> void showParam(const std::ostream &os, T &data);
|
||||||
|
|
||||||
|
template <class T>
|
||||||
void
|
void
|
||||||
Serializeable::nameOut(const string &_name)
|
paramOut(ostream &os, const std::string &name, const T& param)
|
||||||
{
|
{
|
||||||
out() << "\n[" << _name << "]\n";
|
os << name << "=";
|
||||||
|
showParam(os, param);
|
||||||
|
os << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> void
|
|
||||||
Serializeable::paramOut(const string &name, const uint64_t& param)
|
template <class T>
|
||||||
|
void
|
||||||
|
paramIn(IniFile &db, const std::string §ion,
|
||||||
|
const std::string &name, T& param)
|
||||||
{
|
{
|
||||||
out() << name << "=0x" << hex << param << dec << "\n";
|
std::string str;
|
||||||
|
if (!db.find(section, name, str) || !parseParam(str, param)) {
|
||||||
|
fatal("Can't unserialize '%s:%s'\n", section, name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void
|
||||||
|
arrayParamOut(ostream &os, const std::string &name,
|
||||||
|
const T *param, int size)
|
||||||
|
{
|
||||||
|
os << name << "=";
|
||||||
|
if (size > 0)
|
||||||
|
showParam(os, param[0]);
|
||||||
|
for (int i = 1; i < size; ++i) {
|
||||||
|
os << " ";
|
||||||
|
showParam(os, param[i]);
|
||||||
|
}
|
||||||
|
os << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void
|
||||||
|
arrayParamIn(IniFile &db, const std::string §ion,
|
||||||
|
const std::string &name, T *param, int size)
|
||||||
|
{
|
||||||
|
std::string str;
|
||||||
|
if (!db.find(section, name, str)) {
|
||||||
|
fatal("Can't unserialize '%s:%s'\n", section, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// code below stolen from VectorParam<T>::parse().
|
||||||
|
// it would be nice to unify these somehow...
|
||||||
|
|
||||||
|
vector<string> tokens;
|
||||||
|
|
||||||
|
tokenize(tokens, str, ' ');
|
||||||
|
|
||||||
|
// Need this if we were doing a vector
|
||||||
|
// value.resize(tokens.size());
|
||||||
|
|
||||||
|
if (tokens.size() != size) {
|
||||||
|
fatal("Array size mismatch on %s:%s'\n", section, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < tokens.size(); i++) {
|
||||||
|
// need to parse into local variable to handle vector<bool>,
|
||||||
|
// for which operator[] returns a special reference class
|
||||||
|
// that's not the same as 'bool&', (since it's a packed
|
||||||
|
// vector)
|
||||||
|
T scalar_value;
|
||||||
|
if (!parseParam(tokens[i], scalar_value)) {
|
||||||
|
string err("could not parse \"");
|
||||||
|
|
||||||
|
err += str;
|
||||||
|
err += "\"";
|
||||||
|
|
||||||
|
fatal(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
// assign parsed value to vector
|
||||||
|
param[i] = scalar_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define INSTANTIATE_PARAM_TEMPLATES(type) \
|
||||||
|
template void \
|
||||||
|
paramOut(ostream &os, const std::string &name, const type ¶m); \
|
||||||
|
template void \
|
||||||
|
paramIn(IniFile &db, const std::string §ion, \
|
||||||
|
const std::string &name, type & param); \
|
||||||
|
template void \
|
||||||
|
arrayParamOut(ostream &os, const std::string &name, \
|
||||||
|
const type *param, int size); \
|
||||||
|
template void \
|
||||||
|
arrayParamIn(IniFile &db, const std::string §ion, \
|
||||||
|
const std::string &name, type *param, int size);
|
||||||
|
|
||||||
|
|
||||||
|
INSTANTIATE_PARAM_TEMPLATES(int8_t)
|
||||||
|
INSTANTIATE_PARAM_TEMPLATES(uint8_t)
|
||||||
|
INSTANTIATE_PARAM_TEMPLATES(int16_t)
|
||||||
|
INSTANTIATE_PARAM_TEMPLATES(uint16_t)
|
||||||
|
INSTANTIATE_PARAM_TEMPLATES(int32_t)
|
||||||
|
INSTANTIATE_PARAM_TEMPLATES(uint32_t)
|
||||||
|
INSTANTIATE_PARAM_TEMPLATES(int64_t)
|
||||||
|
INSTANTIATE_PARAM_TEMPLATES(uint64_t)
|
||||||
|
INSTANTIATE_PARAM_TEMPLATES(string)
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// unneeded?
|
||||||
void
|
void
|
||||||
Serializeable::childOut(const string &name, Serializeable *child)
|
Serializeable::childOut(const string &name, Serializeable *child)
|
||||||
{
|
{
|
||||||
|
@ -96,6 +198,7 @@ Serializeable::childOut(const string &name, Serializeable *child)
|
||||||
|
|
||||||
out() << name << "=" << child->name() << "\n";
|
out() << name << "=" << child->name() << "\n";
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
Serializeable::setName(const string &name)
|
Serializeable::setName(const string &name)
|
||||||
|
@ -174,11 +277,12 @@ Serializer::serialize(const string &f)
|
||||||
|
|
||||||
add_objects();
|
add_objects();
|
||||||
while (!objects.empty()) {
|
while (!objects.empty()) {
|
||||||
Serializeable *serial = objects.front();
|
Serializeable *obj = objects.front();
|
||||||
DPRINTF(Serialize, "Serializing %s\n", serial->name());
|
DPRINTF(Serialize, "Serializing %s\n", obj->name());
|
||||||
serial->serialize();
|
obj->nameOut(out());
|
||||||
|
obj->serialize(out());
|
||||||
objects.pop_front();
|
objects.pop_front();
|
||||||
list.push_back(serial);
|
list.push_back(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!list.empty()) {
|
while (!list.empty()) {
|
||||||
|
@ -203,7 +307,7 @@ class SerializeEvent : public Event
|
||||||
~SerializeEvent();
|
~SerializeEvent();
|
||||||
|
|
||||||
virtual void process();
|
virtual void process();
|
||||||
virtual void serialize();
|
virtual void serialize(std::ostream &os);
|
||||||
};
|
};
|
||||||
|
|
||||||
SerializeEvent::SerializeEvent(EventQueue *q, Tick when, const string &f)
|
SerializeEvent::SerializeEvent(EventQueue *q, Tick when, const string &f)
|
||||||
|
@ -226,7 +330,7 @@ SerializeEvent::process()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SerializeEvent::serialize()
|
SerializeEvent::serialize(ostream &os)
|
||||||
{
|
{
|
||||||
panic("Cannot serialize the SerializeEvent");
|
panic("Cannot serialize the SerializeEvent");
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,44 +36,52 @@
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "sim/host.hh"
|
#include "sim/host.hh"
|
||||||
#include "sim/configfile.hh"
|
#include "sim/configfile.hh"
|
||||||
|
|
||||||
class IniFile;
|
class IniFile;
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void paramOut(std::ostream &os, const std::string &name, const T& param);
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void paramIn(IniFile &db, const std::string §ion,
|
||||||
|
const std::string &name, T& param);
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void arrayParamOut(std::ostream &os, const std::string &name,
|
||||||
|
const T *param, int size);
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void arrayParamIn(IniFile &db, const std::string §ion,
|
||||||
|
const std::string &name, T *param, int size);
|
||||||
|
|
||||||
|
//
|
||||||
|
// These macros are streamlined to use in serialize/unserialize
|
||||||
|
// functions. It's assumed that serialize() has a parameter 'os' for
|
||||||
|
// the ostream, and unserialize() has parameters 'db' and 'section'.
|
||||||
|
#define SERIALIZE_MEMBER(member) paramOut(os, #member, member)
|
||||||
|
|
||||||
|
#define UNSERIALIZE_MEMBER(member) paramIn(db, section, #member, member)
|
||||||
|
|
||||||
|
#define SERIALIZE_ARRAY(member, size) \
|
||||||
|
arrayParamOut(os, #member, member, size)
|
||||||
|
|
||||||
|
#define UNSERIALIZE_ARRAY(member, size) \
|
||||||
|
arrayParamIn(db, section, #member, member, size)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Basic support for object serialization.
|
* Basic support for object serialization.
|
||||||
*/
|
*/
|
||||||
class Serializeable
|
class Serializeable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// To allow other classes to do some of the serialization work.
|
|
||||||
class Proxy {
|
|
||||||
private:
|
|
||||||
Serializeable *obj;
|
|
||||||
|
|
||||||
// Make it so only Serializables can construct one of these.
|
|
||||||
Proxy(Serializeable *o) : obj(o) {};
|
|
||||||
|
|
||||||
friend class Serializeable;
|
|
||||||
|
|
||||||
public:
|
|
||||||
template <class T>
|
|
||||||
void paramOut(const std::string &name, const T& param) const {
|
|
||||||
obj->paramOut(name, param);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
friend class Serializer;
|
friend class Serializer;
|
||||||
friend class Proxy;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Proxy proxy;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const Proxy &getProxy() { return(proxy); };
|
|
||||||
|
|
||||||
// object name: should be unique
|
// object name: should be unique
|
||||||
std::string objName;
|
std::string objName;
|
||||||
|
|
||||||
|
@ -81,13 +89,8 @@ class Serializeable
|
||||||
static Serializer *serializer;
|
static Serializer *serializer;
|
||||||
|
|
||||||
void mark();
|
void mark();
|
||||||
void nameOut();
|
void nameOut(std::ostream& os);
|
||||||
void nameOut(const std::string &_name);
|
void nameOut(std::ostream& os, const std::string &_name);
|
||||||
void childOut(const std::string &name, Serializeable *child);
|
|
||||||
template <class T>
|
|
||||||
void paramOut(const std::string &name, const T& param);
|
|
||||||
|
|
||||||
std::ostream &out() const;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Serializeable(const std::string &n);
|
Serializeable(const std::string &n);
|
||||||
|
@ -99,12 +102,8 @@ class Serializeable
|
||||||
const std::string &name() const { return objName; }
|
const std::string &name() const { return objName; }
|
||||||
|
|
||||||
virtual void nameChildren() {}
|
virtual void nameChildren() {}
|
||||||
virtual void serialize() {}
|
virtual void serialize(std::ostream& os) {}
|
||||||
virtual void unserialize(IniFile &db, const std::string &category,
|
virtual void unserialize(IniFile &db, const std::string §ion) {}
|
||||||
ConfigNode *node = NULL)
|
|
||||||
{
|
|
||||||
std::cout << name() << " is being unserialized" << std::endl;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Serializer
|
class Serializer
|
||||||
|
@ -131,17 +130,6 @@ class Serializer
|
||||||
const std::string &filename() const { return file; }
|
const std::string &filename() const { return file; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline void
|
|
||||||
Serializeable::paramOut(const std::string &name, const T& param)
|
|
||||||
{
|
|
||||||
out() << name << "=" << param << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
template <> void
|
|
||||||
Serializeable::paramOut(const std::string &name, const uint64_t& param);
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// A SerializeableBuilder serves as an evaluation context for a set of
|
// A SerializeableBuilder serves as an evaluation context for a set of
|
||||||
// parameters that describe a specific instance of a Serializeable. This
|
// parameters that describe a specific instance of a Serializeable. This
|
||||||
|
|
Loading…
Reference in a new issue