summaryrefslogtreecommitdiff
path: root/src/sim
diff options
context:
space:
mode:
Diffstat (limited to 'src/sim')
-rw-r--r--src/sim/clock_domain.cc8
-rw-r--r--src/sim/clock_domain.hh5
-rw-r--r--src/sim/cxx_manager.cc2
-rw-r--r--src/sim/cxx_manager.hh4
-rw-r--r--src/sim/dvfs_handler.cc23
-rw-r--r--src/sim/dvfs_handler.hh4
-rw-r--r--src/sim/eventq.cc21
-rw-r--r--src/sim/eventq.hh11
-rw-r--r--src/sim/process.cc25
-rw-r--r--src/sim/process.hh12
-rw-r--r--src/sim/root.cc6
-rw-r--r--src/sim/root.hh7
-rw-r--r--src/sim/serialize.cc270
-rw-r--r--src/sim/serialize.hh257
-rw-r--r--src/sim/sim_events.cc17
-rw-r--r--src/sim/sim_events.hh10
-rw-r--r--src/sim/sim_object.cc15
-rw-r--r--src/sim/sim_object.hh8
-rw-r--r--src/sim/system.cc17
-rw-r--r--src/sim/system.hh9
-rw-r--r--src/sim/ticked_object.cc20
-rw-r--r--src/sim/ticked_object.hh10
-rw-r--r--src/sim/voltage_domain.cc6
-rw-r--r--src/sim/voltage_domain.hh5
24 files changed, 488 insertions, 284 deletions
diff --git a/src/sim/clock_domain.cc b/src/sim/clock_domain.cc
index 8f45bba09..60c688b1a 100644
--- a/src/sim/clock_domain.cc
+++ b/src/sim/clock_domain.cc
@@ -156,16 +156,16 @@ SrcClockDomain::perfLevel(PerfLevel perf_level)
}
void
-SrcClockDomain::serialize(std::ostream &os)
+SrcClockDomain::serialize(CheckpointOut &cp) const
{
SERIALIZE_SCALAR(_perfLevel);
- ClockDomain::serialize(os);
+ ClockDomain::serialize(cp);
}
void
-SrcClockDomain::unserialize(Checkpoint *cp, const std::string &section)
+SrcClockDomain::unserialize(CheckpointIn &cp)
{
- ClockDomain::unserialize(cp, section);
+ ClockDomain::unserialize(cp);
UNSERIALIZE_SCALAR(_perfLevel);
}
diff --git a/src/sim/clock_domain.hh b/src/sim/clock_domain.hh
index edf2340ad..c4242af55 100644
--- a/src/sim/clock_domain.hh
+++ b/src/sim/clock_domain.hh
@@ -238,8 +238,9 @@ class SrcClockDomain : public ClockDomain
}
void startup();
- void serialize(std::ostream &os);
- void unserialize(Checkpoint *cp, const std::string &section);
+
+ void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
+ void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
private:
/**
diff --git a/src/sim/cxx_manager.cc b/src/sim/cxx_manager.cc
index 7f6a03398..6d4565dbc 100644
--- a/src/sim/cxx_manager.cc
+++ b/src/sim/cxx_manager.cc
@@ -671,7 +671,7 @@ CxxConfigManager::serialize(std::ostream &os)
}
void
-CxxConfigManager::loadState(Checkpoint *checkpoint)
+CxxConfigManager::loadState(CheckpointIn &checkpoint)
{
for (auto i = objectsInOrder.begin(); i != objectsInOrder.end(); ++ i)
(*i)->loadState(checkpoint);
diff --git a/src/sim/cxx_manager.hh b/src/sim/cxx_manager.hh
index caa115f03..b2ba31214 100644
--- a/src/sim/cxx_manager.hh
+++ b/src/sim/cxx_manager.hh
@@ -61,7 +61,7 @@
#include "base/cprintf.hh"
#include "sim/cxx_config.hh"
-class Checkpoint;
+class CheckpointIn;
/** This class allows a config file to be read into gem5 (generating the
* appropriate SimObjects) from C++ */
@@ -292,7 +292,7 @@ class CxxConfigManager
void serialize(std::ostream &os);
/** Load all objects' state from the given Checkpoint */
- void loadState(Checkpoint *checkpoint);
+ void loadState(CheckpointIn &checkpoint);
/** Delete all objects and clear objectsByName and objectsByOrder */
void deleteObjects();
diff --git a/src/sim/dvfs_handler.cc b/src/sim/dvfs_handler.cc
index f4fe760a2..f507897b3 100644
--- a/src/sim/dvfs_handler.cc
+++ b/src/sim/dvfs_handler.cc
@@ -170,7 +170,7 @@ DVFSHandler::UpdateEvent::updatePerfLevel()
}
void
-DVFSHandler::serialize(std::ostream &os)
+DVFSHandler::serialize(CheckpointOut &cp) const
{
//This is to ensure that the handler status is maintained during the
//entire simulation run and not changed from command line during checkpoint
@@ -182,23 +182,22 @@ DVFSHandler::serialize(std::ostream &os)
std::vector<DomainID> domain_ids;
std::vector<PerfLevel> perf_levels;
std::vector<Tick> whens;
- for (auto it = updatePerfLevelEvents.begin();
- it != updatePerfLevelEvents.end(); ++it) {
- DomainID id = it->first;
- UpdateEvent *event = &it->second;
+ for (const auto &ev_pair : updatePerfLevelEvents) {
+ DomainID id = ev_pair.first;
+ const UpdateEvent *event = &ev_pair.second;
assert(id == event->domainIDToSet);
domain_ids.push_back(id);
perf_levels.push_back(event->perfLevelToSet);
whens.push_back(event->scheduled() ? event->when() : 0);
}
- arrayParamOut(os, "domain_ids", domain_ids);
- arrayParamOut(os, "perf_levels", perf_levels);
- arrayParamOut(os, "whens", whens);
+ SERIALIZE_CONTAINER(domain_ids);
+ SERIALIZE_CONTAINER(perf_levels);
+ SERIALIZE_CONTAINER(whens);
}
void
-DVFSHandler::unserialize(Checkpoint *cp, const std::string &section)
+DVFSHandler::unserialize(CheckpointIn &cp)
{
bool temp = enableHandler;
@@ -213,9 +212,9 @@ DVFSHandler::unserialize(Checkpoint *cp, const std::string &section)
std::vector<DomainID> domain_ids;
std::vector<PerfLevel> perf_levels;
std::vector<Tick> whens;
- arrayParamIn(cp, section, "domain_ids", domain_ids);
- arrayParamIn(cp, section, "perf_levels", perf_levels);
- arrayParamIn(cp, section, "whens", whens);
+ UNSERIALIZE_CONTAINER(domain_ids);
+ UNSERIALIZE_CONTAINER(perf_levels);
+ UNSERIALIZE_CONTAINER(whens);
for (size_t i = 0; i < domain_ids.size(); ++i) {;
UpdateEvent *event = &updatePerfLevelEvents[domain_ids[i]];
diff --git a/src/sim/dvfs_handler.hh b/src/sim/dvfs_handler.hh
index a8b78d08b..6e495fff5 100644
--- a/src/sim/dvfs_handler.hh
+++ b/src/sim/dvfs_handler.hh
@@ -198,8 +198,8 @@ class DVFSHandler : public SimObject
*/
bool isEnabled() const { return enableHandler; }
- void serialize(std::ostream &os);
- void unserialize(Checkpoint *cp, const std::string &section);
+ void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
+ void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
private:
typedef std::map<DomainID, SrcClockDomain*> Domains;
diff --git a/src/sim/eventq.cc b/src/sim/eventq.cc
index 4fde79656..f75ada47c 100644
--- a/src/sim/eventq.cc
+++ b/src/sim/eventq.cc
@@ -242,7 +242,7 @@ EventQueue::serviceOne()
}
void
-Event::serialize(std::ostream &os)
+Event::serialize(CheckpointOut &cp) const
{
SERIALIZE_SCALAR(_when);
SERIALIZE_SCALAR(_priority);
@@ -251,12 +251,12 @@ Event::serialize(std::ostream &os)
}
void
-Event::unserialize(Checkpoint *cp, const string &section)
+Event::unserialize(CheckpointIn &cp)
{
}
void
-Event::unserialize(Checkpoint *cp, const string &section, EventQueue *eventq)
+Event::unserializeEvent(CheckpointIn &cp, EventQueue *eventq)
{
if (scheduled())
eventq->deschedule(this);
@@ -290,7 +290,7 @@ Event::unserialize(Checkpoint *cp, const string &section, EventQueue *eventq)
}
void
-EventQueue::serialize(ostream &os)
+EventQueue::serialize(CheckpointOut &cp) const
{
std::list<Event *> eventPtrs;
@@ -302,7 +302,7 @@ EventQueue::serialize(ostream &os)
while (nextInBin) {
if (nextInBin->flags.isSet(Event::AutoSerialize)) {
eventPtrs.push_back(nextInBin);
- paramOut(os, csprintf("event%d", numEvents++),
+ paramOut(cp, csprintf("event%d", numEvents++),
nextInBin->name());
}
nextInBin = nextInBin->nextInBin;
@@ -313,15 +313,12 @@ EventQueue::serialize(ostream &os)
SERIALIZE_SCALAR(numEvents);
- for (std::list<Event *>::iterator it = eventPtrs.begin();
- it != eventPtrs.end(); ++it) {
- (*it)->nameOut(os);
- (*it)->serialize(os);
- }
+ for (Event *ev : eventPtrs)
+ ev->serializeSection(cp, ev->name());
}
void
-EventQueue::unserialize(Checkpoint *cp, const std::string &section)
+EventQueue::unserialize(CheckpointIn &cp)
{
int numEvents;
UNSERIALIZE_SCALAR(numEvents);
@@ -329,7 +326,7 @@ EventQueue::unserialize(Checkpoint *cp, const std::string &section)
std::string eventName;
for (int i = 0; i < numEvents; i++) {
// get the pointer value associated with the event
- paramIn(cp, section, csprintf("event%d", i), eventName);
+ paramIn(cp, csprintf("event%d", i), eventName);
// create the event based on its pointer value
Serializable::create(cp, eventName);
diff --git a/src/sim/eventq.hh b/src/sim/eventq.hh
index f726a6dbd..b90e5d382 100644
--- a/src/sim/eventq.hh
+++ b/src/sim/eventq.hh
@@ -350,15 +350,14 @@ class Event : public EventBase, public Serializable
virtual BaseGlobalEvent *globalEvent() { return NULL; }
#ifndef SWIG
- virtual void serialize(std::ostream &os);
- virtual void unserialize(Checkpoint *cp, const std::string &section);
+ void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
+ void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
//! This function is required to support restoring from checkpoints
//! when running with multiple queues. Since we still have not thrashed
//! out all the details on checkpointing, this function is most likely
//! to be revisited in future.
- virtual void unserialize(Checkpoint *cp, const std::string &section,
- EventQueue *eventq);
+ virtual void unserializeEvent(CheckpointIn &cp, EventQueue *eventq);
#endif
};
@@ -647,8 +646,8 @@ class EventQueue : public Serializable
/**@}*/
#ifndef SWIG
- virtual void serialize(std::ostream &os);
- virtual void unserialize(Checkpoint *cp, const std::string &section);
+ void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
+ void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
#endif
virtual ~EventQueue() { }
diff --git a/src/sim/process.cc b/src/sim/process.cc
index 35f981d1e..a820b0632 100644
--- a/src/sim/process.cc
+++ b/src/sim/process.cc
@@ -259,6 +259,13 @@ Process::initState()
pTable->initState(tc);
}
+unsigned int
+Process::drain(DrainManager *dm)
+{
+ find_file_offsets();
+ return 0;
+}
+
// map simulator fd sim_fd to target fd tgt_fd
void
Process::dup_fd(int sim_fd, int tgt_fd)
@@ -488,7 +495,7 @@ Process::setReadPipeSource(int read_pipe_fd, int source_fd)
}
void
-Process::FdMap::serialize(std::ostream &os)
+Process::FdMap::serialize(CheckpointOut &cp) const
{
SERIALIZE_SCALAR(fd);
SERIALIZE_SCALAR(isPipe);
@@ -499,7 +506,7 @@ Process::FdMap::serialize(std::ostream &os)
}
void
-Process::FdMap::unserialize(Checkpoint *cp, const std::string &section)
+Process::FdMap::unserialize(CheckpointIn &cp)
{
UNSERIALIZE_SCALAR(fd);
UNSERIALIZE_SCALAR(isPipe);
@@ -510,7 +517,7 @@ Process::FdMap::unserialize(Checkpoint *cp, const std::string &section)
}
void
-Process::serialize(std::ostream &os)
+Process::serialize(CheckpointOut &cp) const
{
SERIALIZE_SCALAR(brk_point);
SERIALIZE_SCALAR(stack_base);
@@ -521,18 +528,16 @@ Process::serialize(std::ostream &os)
SERIALIZE_SCALAR(mmap_end);
SERIALIZE_SCALAR(nxm_start);
SERIALIZE_SCALAR(nxm_end);
- find_file_offsets();
- pTable->serialize(os);
+ pTable->serialize(cp);
for (int x = 0; x <= MAX_FD; x++) {
- nameOut(os, csprintf("%s.FdMap%d", name(), x));
- fd_map[x].serialize(os);
+ fd_map[x].serializeSection(cp, csprintf("FdMap%d", x));
}
SERIALIZE_SCALAR(M5_pid);
}
void
-Process::unserialize(Checkpoint *cp, const std::string &section)
+Process::unserialize(CheckpointIn &cp)
{
UNSERIALIZE_SCALAR(brk_point);
UNSERIALIZE_SCALAR(stack_base);
@@ -543,9 +548,9 @@ Process::unserialize(Checkpoint *cp, const std::string &section)
UNSERIALIZE_SCALAR(mmap_end);
UNSERIALIZE_SCALAR(nxm_start);
UNSERIALIZE_SCALAR(nxm_end);
- pTable->unserialize(cp, section);
+ pTable->unserialize(cp);
for (int x = 0; x <= MAX_FD; x++) {
- fd_map[x].unserialize(cp, csprintf("%s.FdMap%d", section, x));
+ fd_map[x].unserializeSection(cp, csprintf("FdMap%d", x));
}
fix_file_offsets();
UNSERIALIZE_OPT_SCALAR(M5_pid);
diff --git a/src/sim/process.hh b/src/sim/process.hh
index 04ce00f67..c1499ccf7 100644
--- a/src/sim/process.hh
+++ b/src/sim/process.hh
@@ -120,6 +120,8 @@ class Process : public SimObject
virtual void initState();
+ unsigned int drain(DrainManager *dm) M5_ATTR_OVERRIDE;
+
public:
//This id is assigned by m5 and is used to keep process' tlb entries
@@ -133,7 +135,7 @@ class Process : public SimObject
PageTableBase* pTable;
- class FdMap
+ class FdMap : public Serializable
{
public:
int fd;
@@ -150,8 +152,8 @@ class Process : public SimObject
isPipe(false), readPipeSource(0), fileOffset(0), driver(NULL)
{ }
- void serialize(std::ostream &os);
- void unserialize(Checkpoint *cp, const std::string &section);
+ void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
+ void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
};
protected:
@@ -233,8 +235,8 @@ class Process : public SimObject
*/
bool map(Addr vaddr, Addr paddr, int size, bool cacheable = true);
- void serialize(std::ostream &os);
- void unserialize(Checkpoint *cp, const std::string &section);
+ void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
+ void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
};
//
diff --git a/src/sim/root.cc b/src/sim/root.cc
index 9bb8b4f05..1d58c3bbe 100644
--- a/src/sim/root.cc
+++ b/src/sim/root.cc
@@ -123,14 +123,14 @@ Root::initState()
}
void
-Root::loadState(Checkpoint *cp)
+Root::loadState(CheckpointIn &cp)
{
SimObject::loadState(cp);
timeSyncEnable(params()->time_sync_enable);
}
void
-Root::serialize(std::ostream &os)
+Root::serialize(CheckpointOut &cp) const
{
uint64_t cpt_ver = gem5CheckpointVersion;
SERIALIZE_SCALAR(cpt_ver);
@@ -140,7 +140,7 @@ Root::serialize(std::ostream &os)
}
void
-Root::unserialize(Checkpoint *cp, const std::string &section)
+Root::unserialize(CheckpointIn &cp)
{
uint64_t cpt_ver = 0;
UNSERIALIZE_OPT_SCALAR(cpt_ver);
diff --git a/src/sim/root.hh b/src/sim/root.hh
index 6a7b5dc93..1c330e2c4 100644
--- a/src/sim/root.hh
+++ b/src/sim/root.hh
@@ -106,15 +106,14 @@ class Root : public SimObject
/** Schedule the timesync event at loadState() so that curTick is correct
*/
- void loadState(Checkpoint *cp);
+ void loadState(CheckpointIn &cp) M5_ATTR_OVERRIDE;
/** Schedule the timesync event at initState() when not unserializing
*/
void initState();
- virtual void serialize(std::ostream &os);
- virtual void unserialize(Checkpoint *cp, const std::string &section);
-
+ void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
+ void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
};
#endif // __SIM_ROOT_HH__
diff --git a/src/sim/serialize.cc b/src/sim/serialize.cc
index 99426b5a6..a7c1834cf 100644
--- a/src/sim/serialize.cc
+++ b/src/sim/serialize.cc
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2015 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* Copyright (c) 2013 Advanced Micro Devices, Inc.
* Copyright (c) 2013 Mark D. Hill and David A. Wood
@@ -30,6 +42,7 @@
* Authors: Nathan Binkert
* Erik Hallnor
* Steve Reinhardt
+ * Andreas Sandberg
*/
#include <sys/stat.h>
@@ -47,6 +60,7 @@
#include "base/output.hh"
#include "base/str.hh"
#include "base/trace.hh"
+#include "debug/Checkpoint.hh"
#include "sim/eventq.hh"
#include "sim/serialize.hh"
#include "sim/sim_events.hh"
@@ -71,7 +85,7 @@ parseParam(const string &s, T &value)
template <class T>
void
-showParam(ostream &os, const T &value)
+showParam(CheckpointOut &os, const T &value)
{
os << value;
}
@@ -87,7 +101,7 @@ showParam(ostream &os, const T &value)
// Treat 8-bit ints (chars) as ints on output, not as chars
template <>
void
-showParam(ostream &os, const char &value)
+showParam(CheckpointOut &os, const char &value)
{
os << (int)value;
}
@@ -95,7 +109,7 @@ showParam(ostream &os, const char &value)
template <>
void
-showParam(ostream &os, const signed char &value)
+showParam(CheckpointOut &os, const signed char &value)
{
os << (int)value;
}
@@ -103,7 +117,7 @@ showParam(ostream &os, const signed char &value)
template <>
void
-showParam(ostream &os, const unsigned char &value)
+showParam(CheckpointOut &os, const unsigned char &value)
{
os << (unsigned int)value;
}
@@ -133,7 +147,7 @@ parseParam(const string &s, bool &value)
// Display bools as strings
template <>
void
-showParam(ostream &os, const bool &value)
+showParam(CheckpointOut &os, const bool &value)
{
os << (value ? "true" : "false");
}
@@ -151,22 +165,11 @@ parseParam(const string &s, string &value)
int Serializable::ckptMaxCount = 0;
int Serializable::ckptCount = 0;
int Serializable::ckptPrevCount = -1;
-
-void
-Serializable::nameOut(ostream &os)
-{
- os << "\n[" << name() << "]\n";
-}
-
-void
-Serializable::nameOut(ostream &os, const string &_name)
-{
- os << "\n[" << _name << "]\n";
-}
+std::stack<std::string> Serializable::path;
template <class T>
void
-paramOut(ostream &os, const string &name, const T &param)
+paramOut(CheckpointOut &os, const string &name, const T &param)
{
os << name << "=";
showParam(os, param);
@@ -175,7 +178,7 @@ paramOut(ostream &os, const string &name, const T &param)
template <class T>
void
-arrayParamOut(ostream &os, const string &name, const vector<T> &param)
+arrayParamOut(CheckpointOut &os, const string &name, const vector<T> &param)
{
typename vector<T>::size_type size = param.size();
os << name << "=";
@@ -190,7 +193,7 @@ arrayParamOut(ostream &os, const string &name, const vector<T> &param)
template <class T>
void
-arrayParamOut(ostream &os, const string &name, const list<T> &param)
+arrayParamOut(CheckpointOut &os, const string &name, const list<T> &param)
{
typename list<T>::const_iterator it = param.begin();
@@ -208,20 +211,22 @@ arrayParamOut(ostream &os, const string &name, const list<T> &param)
template <class T>
void
-paramIn(Checkpoint *cp, const string &section, const string &name, T &param)
+paramIn(CheckpointIn &cp, const string &name, T &param)
{
+ const string &section(Serializable::currentSection());
string str;
- if (!cp->find(section, name, str) || !parseParam(str, param)) {
+ if (!cp.find(section, name, str) || !parseParam(str, param)) {
fatal("Can't unserialize '%s:%s'\n", section, name);
}
}
template <class T>
bool
-optParamIn(Checkpoint *cp, const string &section, const string &name, T &param)
+optParamIn(CheckpointIn &cp, const string &name, T &param)
{
+ const string &section(Serializable::currentSection());
string str;
- if (!cp->find(section, name, str) || !parseParam(str, param)) {
+ if (!cp.find(section, name, str) || !parseParam(str, param)) {
warn("optional parameter %s:%s not present\n", section, name);
return false;
} else {
@@ -231,7 +236,8 @@ optParamIn(Checkpoint *cp, const string &section, const string &name, T &param)
template <class T>
void
-arrayParamOut(ostream &os, const string &name, const T *param, unsigned size)
+arrayParamOut(CheckpointOut &os, const string &name,
+ const T *param, unsigned size)
{
os << name << "=";
if (size > 0)
@@ -246,11 +252,11 @@ arrayParamOut(ostream &os, const string &name, const T *param, unsigned size)
template <class T>
void
-arrayParamIn(Checkpoint *cp, const string &section, const string &name,
- T *param, unsigned size)
+arrayParamIn(CheckpointIn &cp, const string &name, T *param, unsigned size)
{
+ const string &section(Serializable::currentSection());
string str;
- if (!cp->find(section, name, str)) {
+ if (!cp.find(section, name, str)) {
fatal("Can't unserialize '%s:%s'\n", section, name);
}
@@ -273,7 +279,7 @@ arrayParamIn(Checkpoint *cp, const string &section, const string &name,
// for which operator[] returns a special reference class
// that's not the same as 'bool&', (since it's a packed
// vector)
- T scalar_value = 0;
+ T scalar_value;
if (!parseParam(tokens[i], scalar_value)) {
string err("could not parse \"");
@@ -290,11 +296,11 @@ arrayParamIn(Checkpoint *cp, const string &section, const string &name,
template <class T>
void
-arrayParamIn(Checkpoint *cp, const string &section,
- const string &name, vector<T> &param)
+arrayParamIn(CheckpointIn &cp, const string &name, vector<T> &param)
{
+ const string &section(Serializable::currentSection());
string str;
- if (!cp->find(section, name, str)) {
+ if (!cp.find(section, name, str)) {
fatal("Can't unserialize '%s:%s'\n", section, name);
}
@@ -315,7 +321,7 @@ arrayParamIn(Checkpoint *cp, const string &section,
// for which operator[] returns a special reference class
// that's not the same as 'bool&', (since it's a packed
// vector)
- T scalar_value = 0;
+ T scalar_value;
if (!parseParam(tokens[i], scalar_value)) {
string err("could not parse \"");
@@ -332,11 +338,11 @@ arrayParamIn(Checkpoint *cp, const string &section,
template <class T>
void
-arrayParamIn(Checkpoint *cp, const string &section,
- const string &name, list<T> &param)
+arrayParamIn(CheckpointIn &cp, const string &name, list<T> &param)
{
+ const string &section(Serializable::currentSection());
string str;
- if (!cp->find(section, name, str)) {
+ if (!cp.find(section, name, str)) {
fatal("Can't unserialize '%s:%s'\n", section, name);
}
param.clear();
@@ -345,7 +351,7 @@ arrayParamIn(Checkpoint *cp, const string &section,
tokenize(tokens, str, ' ');
for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
- T scalar_value = 0;
+ T scalar_value;
if (!parseParam(tokens[i], scalar_value)) {
string err("could not parse \"");
@@ -362,42 +368,40 @@ arrayParamIn(Checkpoint *cp, const string &section,
void
-objParamIn(Checkpoint *cp, const string &section,
- const string &name, SimObject * &param)
+objParamIn(CheckpointIn &cp, const string &name, SimObject * &param)
{
- if (!cp->findObj(section, name, param)) {
+ const string &section(Serializable::currentSection());
+ if (!cp.findObj(section, name, param)) {
fatal("Can't unserialize '%s:%s'\n", section, name);
}
}
#define INSTANTIATE_PARAM_TEMPLATES(type) \
-template void \
-paramOut(ostream &os, const string &name, type const &param); \
-template void \
-paramIn(Checkpoint *cp, const string &section, \
- const string &name, type & param); \
-template bool \
-optParamIn(Checkpoint *cp, const string &section, \
- const string &name, type & param); \
-template void \
-arrayParamOut(ostream &os, const string &name, \
- type const *param, unsigned size); \
-template void \
-arrayParamIn(Checkpoint *cp, const string &section, \
- const string &name, type *param, unsigned size); \
-template void \
-arrayParamOut(ostream &os, const string &name, \
- const vector<type> &param); \
-template void \
-arrayParamIn(Checkpoint *cp, const string &section, \
- const string &name, vector<type> &param); \
-template void \
-arrayParamOut(ostream &os, const string &name, \
- const list<type> &param); \
-template void \
-arrayParamIn(Checkpoint *cp, const string &section, \
- const string &name, list<type> &param);
+ template void \
+ paramOut(CheckpointOut &os, const string &name, type const &param); \
+ template void \
+ paramIn(CheckpointIn &cp, const string &name, type & param); \
+ template bool \
+ optParamIn(CheckpointIn &cp, const string &name, type & param); \
+ template void \
+ arrayParamOut(CheckpointOut &os, const string &name, \
+ type const *param, unsigned size); \
+ template void \
+ arrayParamIn(CheckpointIn &cp, const string &name, \
+ type *param, unsigned size); \
+ template void \
+ arrayParamOut(CheckpointOut &os, const string &name, \
+ const vector<type> &param); \
+ template void \
+ arrayParamIn(CheckpointIn &cp, const string &name, \
+ vector<type> &param); \
+ template void \
+ arrayParamOut(CheckpointOut &os, const string &name, \
+ const list<type> &param); \
+ template void \
+ arrayParamIn(CheckpointIn &cp, const string &name, \
+ list<type> &param);
INSTANTIATE_PARAM_TEMPLATES(char)
INSTANTIATE_PARAM_TEMPLATES(signed char)
@@ -423,45 +427,31 @@ INSTANTIATE_PARAM_TEMPLATES(string)
class Globals : public Serializable
{
public:
- const string name() const;
- void serialize(ostream &os);
- void unserialize(Checkpoint *cp, const std::string &section);
+ Globals()
+ : unserializedCurTick(0) {}
+
+ void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
+ void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
+
+ Tick unserializedCurTick;
};
/// The one and only instance of the Globals class.
Globals globals;
-const string
-Globals::name() const
-{
- return "Globals";
-}
-
void
-Globals::serialize(ostream &os)
+Globals::serialize(CheckpointOut &cp) const
{
- nameOut(os);
- paramOut(os, "curTick", curTick());
+ paramOut(cp, "curTick", curTick());
+ paramOut(cp, "numMainEventQueues", numMainEventQueues);
- paramOut(os, "numMainEventQueues", numMainEventQueues);
-
- for (uint32_t i = 0; i < numMainEventQueues; ++i) {
- nameOut(os, "MainEventQueue");
- mainEventQueue[i]->serialize(os);
- }
}
void
-Globals::unserialize(Checkpoint *cp, const std::string &section)
+Globals::unserialize(CheckpointIn &cp)
{
- Tick tick;
- paramIn(cp, section, "curTick", tick);
- paramIn(cp, section, "numMainEventQueues", numMainEventQueues);
-
- for (uint32_t i = 0; i < numMainEventQueues; ++i) {
- mainEventQueue[i]->setCurTick(tick);
- mainEventQueue[i]->unserialize(cp, "MainEventQueue");
- }
+ paramIn(cp, "curTick", unserializedCurTick);
+ paramIn(cp, "numMainEventQueues", numMainEventQueues);
}
Serializable::Serializable()
@@ -473,37 +463,82 @@ Serializable::~Serializable()
}
void
-Serializable::serialize(ostream &os)
+Serializable::serializeSection(CheckpointOut &cp, const char *name) const
{
+ Serializable::ScopedCheckpointSection sec(cp, name);
+ serialize(cp);
}
void
-Serializable::unserialize(Checkpoint *cp, const string &section)
+Serializable::serializeSectionOld(CheckpointOut &cp, const char *name)
{
+ Serializable::ScopedCheckpointSection sec(cp, name);
+ serializeOld(cp);
+}
+
+void
+Serializable::unserializeSection(CheckpointIn &cp, const char *name)
+{
+ Serializable::ScopedCheckpointSection sec(cp, name);
+ unserialize(cp);
}
void
Serializable::serializeAll(const string &cpt_dir)
{
- string dir = Checkpoint::setDir(cpt_dir);
+ string dir = CheckpointIn::setDir(cpt_dir);
if (mkdir(dir.c_str(), 0775) == -1 && errno != EEXIST)
fatal("couldn't mkdir %s\n", dir);
- string cpt_file = dir + Checkpoint::baseFilename;
+ string cpt_file = dir + CheckpointIn::baseFilename;
ofstream outstream(cpt_file.c_str());
time_t t = time(NULL);
if (!outstream.is_open())
fatal("Unable to open file %s for writing\n", cpt_file.c_str());
outstream << "## checkpoint generated: " << ctime(&t);
- globals.serialize(outstream);
+ globals.serializeSection(outstream, "Globals");
+ for (uint32_t i = 0; i < numMainEventQueues; ++i)
+ mainEventQueue[i]->serializeSection(outstream, "MainEventQueue");
+
SimObject::serializeAll(outstream);
}
void
-Serializable::unserializeGlobals(Checkpoint *cp)
+Serializable::unserializeGlobals(CheckpointIn &cp)
+{
+ globals.unserializeSection(cp, "Globals");
+
+ for (uint32_t i = 0; i < numMainEventQueues; ++i) {
+ mainEventQueue[i]->setCurTick(globals.unserializedCurTick);
+ mainEventQueue[i]->unserializeSection(cp, "MainEventQueue");
+ }
+}
+
+Serializable::ScopedCheckpointSection::~ScopedCheckpointSection()
+{
+ assert(!path.empty());
+ DPRINTF(Checkpoint, "Popping: %s\n", path.top());
+ path.pop();
+}
+
+void
+Serializable::ScopedCheckpointSection::pushName(const char *obj_name)
{
- globals.unserialize(cp, globals.name());
+ if (path.empty()) {
+ path.push(obj_name);
+ } else {
+ path.push(csprintf("%s.%s", path.top(), obj_name));
+ }
+ DPRINTF(Checkpoint, "ScopedCheckpointSection::pushName: %s\n", obj_name);
+}
+
+void
+Serializable::ScopedCheckpointSection::nameOut(CheckpointOut &cp)
+{
+ DPRINTF(Checkpoint, "ScopedCheckpointSection::nameOut: %s\n",
+ Serializable::currentSection());
+ cp << "\n[" << Serializable::currentSection() << "]\n";
}
void
@@ -542,11 +577,11 @@ SerializableClass::SerializableClass(const string &className,
//
//
Serializable *
-SerializableClass::createObject(Checkpoint *cp, const string &section)
+SerializableClass::createObject(CheckpointIn &cp, const string &section)
{
string className;
- if (!cp->find(section, "type", className)) {
+ if (!cp.find(section, "type", className)) {
fatal("Serializable::create: no 'type' entry in section '%s'.\n",
section);
}
@@ -565,22 +600,29 @@ SerializableClass::createObject(Checkpoint *cp, const string &section)
return object;
}
+const std::string &
+Serializable::currentSection()
+{
+ assert(!path.empty());
+
+ return path.top();
+}
Serializable *
-Serializable::create(Checkpoint *cp, const string &section)
+Serializable::create(CheckpointIn &cp, const string &section)
{
Serializable *object = SerializableClass::createObject(cp, section);
- object->unserialize(cp, section);
+ object->unserializeSection(cp, section);
return object;
}
-const char *Checkpoint::baseFilename = "m5.cpt";
+const char *CheckpointIn::baseFilename = "m5.cpt";
-string Checkpoint::currentDirectory;
+string CheckpointIn::currentDirectory;
string
-Checkpoint::setDir(const string &name)
+CheckpointIn::setDir(const string &name)
{
// use csprintf to insert curTick() into directory name if it
// appears to have a format placeholder in it.
@@ -592,35 +634,35 @@ Checkpoint::setDir(const string &name)
}
string
-Checkpoint::dir()
+CheckpointIn::dir()
{
return currentDirectory;
}
-Checkpoint::Checkpoint(const string &cpt_dir, SimObjectResolver &resolver)
+CheckpointIn::CheckpointIn(const string &cpt_dir, SimObjectResolver &resolver)
: db(new IniFile), objNameResolver(resolver), cptDir(setDir(cpt_dir))
{
- string filename = cptDir + "/" + Checkpoint::baseFilename;
+ string filename = cptDir + "/" + CheckpointIn::baseFilename;
if (!db->load(filename)) {
fatal("Can't load checkpoint file '%s'\n", filename);
}
}
-Checkpoint::~Checkpoint()
+CheckpointIn::~CheckpointIn()
{
delete db;
}
bool
-Checkpoint::find(const string &section, const string &entry, string &value)
+CheckpointIn::find(const string &section, const string &entry, string &value)
{
return db->find(section, entry, value);
}
bool
-Checkpoint::findObj(const string &section, const string &entry,
+CheckpointIn::findObj(const string &section, const string &entry,
SimObject *&value)
{
string path;
@@ -634,7 +676,7 @@ Checkpoint::findObj(const string &section, const string &entry,
bool
-Checkpoint::sectionExists(const string &section)
+CheckpointIn::sectionExists(const string &section)
{
return db->sectionExists(section);
}
diff --git a/src/sim/serialize.hh b/src/sim/serialize.hh
index 2fb7cddd0..644ef4005 100644
--- a/src/sim/serialize.hh
+++ b/src/sim/serialize.hh
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2015 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* All rights reserved.
*
@@ -28,6 +40,7 @@
* Authors: Nathan Binkert
* Erik Hallnor
* Steve Reinhardt
+ * Andreas Sandberg
*/
/* @file
@@ -41,6 +54,7 @@
#include <iostream>
#include <list>
#include <map>
+#include <stack>
#include <vector>
#include "base/bitunion.hh"
@@ -48,10 +62,13 @@
class IniFile;
class Serializable;
-class Checkpoint;
+class CheckpointIn;
class SimObject;
class EventQueue;
+typedef std::ostream CheckpointOut;
+
+
/** The current version of the checkpoint format.
* This should be incremented by 1 and only 1 for every new version, where a new
* version is defined as a checkpoint created before this version won't work on
@@ -62,66 +79,61 @@ class EventQueue;
static const uint64_t gem5CheckpointVersion = 0x000000000000000e;
template <class T>
-void paramOut(std::ostream &os, const std::string &name, const T &param);
+void paramOut(CheckpointOut &cp, const std::string &name, const T &param);
template <typename DataType, typename BitUnion>
-void paramOut(std::ostream &os, const std::string &name,
+void paramOut(CheckpointOut &cp, const std::string &name,
const BitfieldBackend::BitUnionOperators<DataType, BitUnion> &p)
{
- paramOut(os, name, p.__data);
+ paramOut(cp, name, p.__data);
}
template <class T>
-void paramIn(Checkpoint *cp, const std::string &section,
- const std::string &name, T &param);
+void paramIn(CheckpointIn &cp, const std::string &name, T &param);
template <typename DataType, typename BitUnion>
-void paramIn(Checkpoint *cp, const std::string &section,
- const std::string &name,
+void paramIn(CheckpointIn &cp, const std::string &name,
BitfieldBackend::BitUnionOperators<DataType, BitUnion> &p)
{
- paramIn(cp, section, name, p.__data);
+ paramIn(cp, name, p.__data);
}
template <class T>
-bool optParamIn(Checkpoint *cp, const std::string &section,
- const std::string &name, T &param);
+bool optParamIn(CheckpointIn &cp, const std::string &name, T &param);
template <typename DataType, typename BitUnion>
-bool optParamIn(Checkpoint *cp, const std::string &section,
- const std::string &name,
+bool optParamIn(CheckpointIn &cp, const std::string &name,
BitfieldBackend::BitUnionOperators<DataType, BitUnion> &p)
{
- return optParamIn(cp, section, name, p.__data);
+ return optParamIn(cp, name, p.__data);
}
template <class T>
-void arrayParamOut(std::ostream &os, const std::string &name,
+void arrayParamOut(CheckpointOut &cp, const std::string &name,
const T *param, unsigned size);
template <class T>
-void arrayParamOut(std::ostream &os, const std::string &name,
+void arrayParamOut(CheckpointOut &cp, const std::string &name,
const std::vector<T> &param);
template <class T>
-void arrayParamOut(std::ostream &os, const std::string &name,
+void arrayParamOut(CheckpointOut &cp, const std::string &name,
const std::list<T> &param);
template <class T>
-void arrayParamIn(Checkpoint *cp, const std::string &section,
- const std::string &name, T *param, unsigned size);
+void arrayParamIn(CheckpointIn &cp, const std::string &name,
+ T *param, unsigned size);
template <class T>
-void arrayParamIn(Checkpoint *cp, const std::string &section,
- const std::string &name, std::vector<T> &param);
+void arrayParamIn(CheckpointIn &cp, const std::string &name,
+ std::vector<T> &param);
template <class T>
-void arrayParamIn(Checkpoint *cp, const std::string &section,
- const std::string &name, std::list<T> &param);
+void arrayParamIn(CheckpointIn &cp, const std::string &name,
+ std::list<T> &param);
void
-objParamIn(Checkpoint *cp, const std::string &section,
- const std::string &name, SimObject * &param);
+objParamIn(CheckpointIn &cp, const std::string &name, SimObject * &param);
template <typename T>
void fromInt(T &t, int i)
@@ -139,45 +151,66 @@ void fromSimObject(T &t, SimObject *s)
// 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 'cp' and 'section'.
-#define SERIALIZE_SCALAR(scalar) paramOut(os, #scalar, scalar)
+#define SERIALIZE_SCALAR(scalar) paramOut(cp, #scalar, scalar)
-#define UNSERIALIZE_SCALAR(scalar) paramIn(cp, section, #scalar, scalar)
-#define UNSERIALIZE_OPT_SCALAR(scalar) optParamIn(cp, section, #scalar, scalar)
+#define UNSERIALIZE_SCALAR(scalar) paramIn(cp, #scalar, scalar)
+#define UNSERIALIZE_OPT_SCALAR(scalar) optParamIn(cp, #scalar, scalar)
// ENUMs are like SCALARs, but we cast them to ints on the way out
-#define SERIALIZE_ENUM(scalar) paramOut(os, #scalar, (int)scalar)
+#define SERIALIZE_ENUM(scalar) paramOut(cp, #scalar, (int)scalar)
#define UNSERIALIZE_ENUM(scalar) \
do { \
int tmp; \
- paramIn(cp, section, #scalar, tmp); \
- fromInt(scalar, tmp); \
+ paramIn(cp, #scalar, tmp); \
+ fromInt(scalar, tmp); \
} while (0)
#define SERIALIZE_ARRAY(member, size) \
- arrayParamOut(os, #member, member, size)
+ arrayParamOut(cp, #member, member, size)
#define UNSERIALIZE_ARRAY(member, size) \
- arrayParamIn(cp, section, #member, member, size)
+ arrayParamIn(cp, #member, member, size)
#define SERIALIZE_CONTAINER(member) \
- arrayParamOut(os, #member, member)
+ arrayParamOut(cp, #member, member)
#define UNSERIALIZE_CONTAINER(member) \
- arrayParamIn(cp, section, #member, member)
+ arrayParamIn(cp, #member, member)
-#define SERIALIZE_OBJPTR(objptr) paramOut(os, #objptr, (objptr)->name())
+#define SERIALIZE_OBJPTR(objptr) paramOut(cp, #objptr, (objptr)->name())
#define UNSERIALIZE_OBJPTR(objptr) \
do { \
SimObject *sptr; \
- objParamIn(cp, section, #objptr, sptr); \
+ objParamIn(cp, #objptr, sptr); \
fromSimObject(objptr, sptr); \
} while (0)
/**
* Basic support for object serialization.
*
+ * Objects that support serialization should derive from this
+ * class. Such objects can largely be divided into two categories: 1)
+ * True SimObjects (deriving from SimObject), and 2) child objects
+ * (non-SimObjects).
+ *
+ * SimObjects are serialized automatically into their own sections
+ * automatically by the SimObject base class (see
+ * SimObject::serializeAll().
+ *
+ * SimObjects can contain other serializable objects that are not
+ * SimObjects. Much like normal serialized members are not serialized
+ * automatically, these objects will not be serialized automatically
+ * and it is expected that the objects owning such serializable
+ * objects call the required serialization/unserialization methods on
+ * child objects. The preferred method to serialize a child object is
+ * to call serializeSection() on the child, which serializes the
+ * object into a new subsection in the current section. Another option
+ * is to call serialize() directly, which serializes the object into
+ * the current section. The latter is not recommended as it can lead
+ * to naming clashes between objects.
+ *
* @note Many objects that support serialization need to be put in a
* consistent state when serialization takes place. We refer to the
* action of forcing an object into a consistent state as
@@ -187,26 +220,146 @@ void fromSimObject(T &t, SimObject *s)
class Serializable
{
protected:
- void nameOut(std::ostream &os);
- void nameOut(std::ostream &os, const std::string &_name);
+ /**
+ * Scoped checkpoint section helper class
+ *
+ * This helper class creates a section within a checkpoint without
+ * the need for a separate serializeable object. It is mainly used
+ * within the Serializable class when serializing or unserializing
+ * section (see serializeSection() and unserializeSection()). It
+ * can also be used to maintain backwards compatibility in
+ * existing code that serializes structs that are not inheriting
+ * from Serializable into subsections.
+ *
+ * When the class is instantiated, it appends a name to the active
+ * path in a checkpoint. The old path is later restored when the
+ * instance is destroyed. For example, serializeSection() could be
+ * implemented by instantiating a ScopedCheckpointSection and then
+ * calling serialize() on an object.
+ */
+ class ScopedCheckpointSection {
+ public:
+ template<class CP>
+ ScopedCheckpointSection(CP &cp, const char *name) {
+ pushName(name);
+ nameOut(cp);
+ }
+
+ template<class CP>
+ ScopedCheckpointSection(CP &cp, const std::string &name) {
+ pushName(name.c_str());
+ nameOut(cp);
+ }
+
+ ~ScopedCheckpointSection();
+
+ ScopedCheckpointSection() = delete;
+ ScopedCheckpointSection(const ScopedCheckpointSection &) = delete;
+ ScopedCheckpointSection &operator=(
+ const ScopedCheckpointSection &) = delete;
+ ScopedCheckpointSection &operator=(
+ ScopedCheckpointSection &&) = delete;
+
+ private:
+ void pushName(const char *name);
+ void nameOut(CheckpointOut &cp);
+ void nameOut(CheckpointIn &cp) {};
+ };
public:
Serializable();
virtual ~Serializable();
- // manditory virtual function, so objects must provide names
- virtual const std::string name() const = 0;
-
- virtual void serialize(std::ostream &os);
- virtual void unserialize(Checkpoint *cp, const std::string &section);
-
- static Serializable *create(Checkpoint *cp, const std::string &section);
+ /**
+ * Serialize an object
+ *
+ * Output an object's state into the current checkpoint section.
+ *
+ * @param cp Checkpoint state
+ */
+ virtual void serialize(CheckpointOut &cp) const = 0;
+
+ /**
+ * Unserialize an object
+ *
+ * Read an object's state from the current checkpoint section.
+ *
+ * @param cp Checkpoint state
+ */
+ virtual void unserialize(CheckpointIn &cp) = 0;
+
+ /**
+ * Serialize an object into a new section
+ *
+ * This method creates a new section in a checkpoint and calls
+ * serialize() to serialize the current object into that
+ * section. The name of the section is appended to the current
+ * checkpoint path.
+ *
+ * @param cp Checkpoint state
+ * @param name Name to append to the active path
+ */
+ void serializeSection(CheckpointOut &cp, const char *name) const;
+
+ void serializeSection(CheckpointOut &cp, const std::string &name) const {
+ serializeSection(cp, name.c_str());
+ }
+
+ /**
+ * Unserialize an a child object
+ *
+ * This method loads a child object from a checkpoint. The object
+ * name is appended to the active path to form a fully qualified
+ * section name and unserialize() is called.
+ *
+ * @param cp Checkpoint state
+ * @param name Name to append to the active path
+ */
+ void unserializeSection(CheckpointIn &cp, const char *name);
+
+ void unserializeSection(CheckpointIn &cp, const std::string &name) {
+ unserializeSection(cp, name.c_str());
+ }
+
+ /**
+ * @{
+ * @name Legacy interface
+ *
+ * Interface for objects that insist on changing their state when
+ * serializing. Such state change should be done in drain(),
+ * memWriteback(), or memInvalidate() and not in the serialization
+ * method. In general, if state changes occur in serialize, it
+ * complicates testing since it breaks assumptions about draining
+ * and serialization. It potentially also makes components more
+ * fragile since they there are no ordering guarantees when
+ * serializing SimObjects.
+ *
+ * @warn This interface is considered deprecated and should never
+ * be used.
+ */
+
+ virtual void serializeOld(CheckpointOut &cp) {
+ serialize(cp);
+ }
+ void serializeSectionOld(CheckpointOut &cp, const char *name);
+ void serializeSectionOld(CheckpointOut &cp, const std::string &name) {
+ serializeSectionOld(cp, name.c_str());
+ }
+ /** @} */
+
+ /** Get the fully-qualified name of the active section */
+ static const std::string &currentSection();
+
+ static Serializable *create(CheckpointIn &cp, const std::string &section);
static int ckptCount;
static int ckptMaxCount;
static int ckptPrevCount;
static void serializeAll(const std::string &cpt_dir);
- static void unserializeGlobals(Checkpoint *cp);
+ static void unserializeGlobals(CheckpointIn &cp);
+
+ private:
+ static std::stack<std::string> path;
};
void debug_serialize(const std::string &cpt_dir);
@@ -258,7 +411,7 @@ class SerializableClass
// for the object (specified by the second string argument), and
// an optional config hierarchy node (specified by the third
// argument). A pointer to the new SerializableBuilder is returned.
- typedef Serializable *(*CreateFunc)(Checkpoint *cp,
+ typedef Serializable *(*CreateFunc)(CheckpointIn &cp,
const std::string &section);
static std::map<std::string,CreateFunc> *classMap;
@@ -272,7 +425,7 @@ class SerializableClass
// create Serializable given name of class and pointer to
// configuration hierarchy node
- static Serializable *createObject(Checkpoint *cp,
+ static Serializable *createObject(CheckpointIn &cp,
const std::string &section);
};
@@ -297,7 +450,7 @@ class SimObjectResolver
virtual SimObject *resolveSimObject(const std::string &name) = 0;
};
-class Checkpoint
+class CheckpointIn
{
private:
@@ -306,8 +459,8 @@ class Checkpoint
SimObjectResolver &objNameResolver;
public:
- Checkpoint(const std::string &cpt_dir, SimObjectResolver &resolver);
- ~Checkpoint();
+ CheckpointIn(const std::string &cpt_dir, SimObjectResolver &resolver);
+ ~CheckpointIn();
const std::string cptDir;
diff --git a/src/sim/sim_events.cc b/src/sim/sim_events.cc
index 5e47adca1..719a732ab 100644
--- a/src/sim/sim_events.cc
+++ b/src/sim/sim_events.cc
@@ -117,10 +117,10 @@ LocalSimLoopExitEvent::description() const
}
void
-LocalSimLoopExitEvent::serialize(ostream &os)
+LocalSimLoopExitEvent::serialize(CheckpointOut &cp) const
{
- paramOut(os, "type", string("SimLoopExitEvent"));
- Event::serialize(os);
+ paramOut(cp, "type", string("SimLoopExitEvent"));
+ Event::serialize(cp);
SERIALIZE_SCALAR(cause);
SERIALIZE_SCALAR(code);
@@ -128,9 +128,9 @@ LocalSimLoopExitEvent::serialize(ostream &os)
}
void
-LocalSimLoopExitEvent::unserialize(Checkpoint *cp, const string &section)
+LocalSimLoopExitEvent::unserialize(CheckpointIn &cp)
{
- Event::unserialize(cp, section);
+ Event::unserialize(cp);
UNSERIALIZE_SCALAR(cause);
UNSERIALIZE_SCALAR(code);
@@ -138,10 +138,9 @@ LocalSimLoopExitEvent::unserialize(Checkpoint *cp, const string &section)
}
void
-LocalSimLoopExitEvent::unserialize(Checkpoint *cp, const string &section,
- EventQueue *eventq)
+LocalSimLoopExitEvent::unserializeEvent(CheckpointIn &cp, EventQueue *eventq)
{
- Event::unserialize(cp, section, eventq);
+ Event::unserializeEvent(cp, eventq);
UNSERIALIZE_SCALAR(cause);
UNSERIALIZE_SCALAR(code);
@@ -149,7 +148,7 @@ LocalSimLoopExitEvent::unserialize(Checkpoint *cp, const string &section,
}
Serializable *
-LocalSimLoopExitEvent::createForUnserialize(Checkpoint *cp,
+LocalSimLoopExitEvent::createForUnserialize(CheckpointIn &cp,
const string &section)
{
return new LocalSimLoopExitEvent();
diff --git a/src/sim/sim_events.hh b/src/sim/sim_events.hh
index 5be2609fd..8d5d5da7b 100644
--- a/src/sim/sim_events.hh
+++ b/src/sim/sim_events.hh
@@ -93,11 +93,11 @@ class LocalSimLoopExitEvent : public Event
virtual const char *description() const;
- virtual void serialize(std::ostream &os);
- virtual void unserialize(Checkpoint *cp, const std::string &section);
- virtual void unserialize(Checkpoint *cp, const std::string &section,
- EventQueue *eventq);
- static Serializable *createForUnserialize(Checkpoint *cp,
+ void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
+ void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
+ void unserializeEvent(CheckpointIn &cp,
+ EventQueue *eventq) M5_ATTR_OVERRIDE;
+ static Serializable *createForUnserialize(CheckpointIn &cp,
const std::string &section);
};
diff --git a/src/sim/sim_object.cc b/src/sim/sim_object.cc
index a7be4ebd2..2c4ba48f6 100644
--- a/src/sim/sim_object.cc
+++ b/src/sim/sim_object.cc
@@ -81,11 +81,13 @@ SimObject::init()
}
void
-SimObject::loadState(Checkpoint *cp)
+SimObject::loadState(CheckpointIn &cp)
{
- if (cp->sectionExists(name())) {
+ if (cp.sectionExists(name())) {
DPRINTF(Checkpoint, "unserializing\n");
- unserialize(cp, name());
+ // This works despite name() returning a fully qualified name
+ // since we are at the top level.
+ unserializeSection(cp, name());
} else {
DPRINTF(Checkpoint, "no checkpoint section found\n");
}
@@ -140,15 +142,16 @@ SimObject::getProbeManager()
// static function: serialize all SimObjects.
//
void
-SimObject::serializeAll(std::ostream &os)
+SimObject::serializeAll(CheckpointOut &cp)
{
SimObjectList::reverse_iterator ri = simObjectList.rbegin();
SimObjectList::reverse_iterator rend = simObjectList.rend();
for (; ri != rend; ++ri) {
SimObject *obj = *ri;
- obj->nameOut(os);
- obj->serialize(os);
+ // This works despite name() returning a fully qualified name
+ // since we are at the top level.
+ obj->serializeSectionOld(cp, obj->name());
}
}
diff --git a/src/sim/sim_object.hh b/src/sim/sim_object.hh
index 9bf95d07f..16237d051 100644
--- a/src/sim/sim_object.hh
+++ b/src/sim/sim_object.hh
@@ -126,7 +126,7 @@ class SimObject : public EventManager, public Serializable, public Drainable
*
* @param cp Checkpoint to restore the state from.
*/
- virtual void loadState(Checkpoint *cp);
+ virtual void loadState(CheckpointIn &cp);
/**
* initState() is called on each SimObject when *not* restoring
@@ -175,10 +175,14 @@ class SimObject : public EventManager, public Serializable, public Drainable
*/
unsigned int drain(DrainManager *drainManger);
+
+ void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE {};
+ void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE {};
+
/**
* Serialize all SimObjects in the system.
*/
- static void serializeAll(std::ostream &os);
+ static void serializeAll(CheckpointOut &cp);
#ifdef DEBUG
public:
diff --git a/src/sim/system.cc b/src/sim/system.cc
index 2f2427769..f781377f7 100644
--- a/src/sim/system.cc
+++ b/src/sim/system.cc
@@ -370,31 +370,30 @@ System::drainResume()
}
void
-System::serialize(ostream &os)
+System::serialize(CheckpointOut &cp) const
{
if (FullSystem)
- kernelSymtab->serialize("kernel_symtab", os);
+ kernelSymtab->serialize("kernel_symtab", cp);
SERIALIZE_SCALAR(pagePtr);
SERIALIZE_SCALAR(nextPID);
- serializeSymtab(os);
+ serializeSymtab(cp);
// also serialize the memories in the system
- nameOut(os, csprintf("%s.physmem", name()));
- physmem.serialize(os);
+ physmem.serializeSection(cp, "physmem");
}
void
-System::unserialize(Checkpoint *cp, const string &section)
+System::unserialize(CheckpointIn &cp)
{
if (FullSystem)
- kernelSymtab->unserialize("kernel_symtab", cp, section);
+ kernelSymtab->unserialize("kernel_symtab", cp);
UNSERIALIZE_SCALAR(pagePtr);
UNSERIALIZE_SCALAR(nextPID);
- unserializeSymtab(cp, section);
+ unserializeSymtab(cp);
// also unserialize the memories in the system
- physmem.unserialize(cp, csprintf("%s.physmem", name()));
+ physmem.unserializeSection(cp, "physmem");
}
void
diff --git a/src/sim/system.hh b/src/sim/system.hh
index 9ec349a47..b8114d0ca 100644
--- a/src/sim/system.hh
+++ b/src/sim/system.hh
@@ -517,8 +517,8 @@ class System : public MemObject
int registerThreadContext(ThreadContext *tc, int assigned=-1);
void replaceThreadContext(ThreadContext *tc, int context_id);
- void serialize(std::ostream &os);
- void unserialize(Checkpoint *cp, const std::string &section);
+ void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
+ void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
unsigned int drain(DrainManager *dm);
void drainResume();
@@ -552,7 +552,7 @@ class System : public MemObject
*
* @param os stream to serialize to
*/
- virtual void serializeSymtab(std::ostream &os) {}
+ virtual void serializeSymtab(CheckpointOut &os) const {}
/**
* If needed, unserialize additional symbol table entries for a
@@ -561,8 +561,7 @@ class System : public MemObject
* @param cp checkpoint to unserialize from
* @param section relevant section in the checkpoint
*/
- virtual void unserializeSymtab(Checkpoint *cp,
- const std::string &section) {}
+ virtual void unserializeSymtab(CheckpointIn &cp) {}
};
diff --git a/src/sim/ticked_object.cc b/src/sim/ticked_object.cc
index ef6ee1c20..ecdb87827 100644
--- a/src/sim/ticked_object.cc
+++ b/src/sim/ticked_object.cc
@@ -72,15 +72,15 @@ Ticked::regStats()
}
void
-Ticked::serialize(std::ostream &os)
+Ticked::serialize(CheckpointOut &cp) const
{
uint64_t lastStoppedUint = lastStopped;
- paramOut(os, "lastStopped", lastStoppedUint);
+ paramOut(cp, "lastStopped", lastStoppedUint);
}
void
-Ticked::unserialize(Checkpoint *cp, const std::string &section)
+Ticked::unserialize(CheckpointIn &cp)
{
uint64_t lastStoppedUint = 0;
@@ -90,7 +90,7 @@ Ticked::unserialize(Checkpoint *cp, const std::string &section)
* checkpointed object but not this one.
* An example would be a CPU model using Ticked restores from a
* simple CPU without without Ticked */
- optParamIn(cp, section, "lastStopped", lastStoppedUint);
+ optParamIn(cp, "lastStopped", lastStoppedUint);
lastStopped = Cycles(lastStoppedUint);
}
@@ -109,14 +109,14 @@ TickedObject::regStats()
}
void
-TickedObject::serialize(std::ostream &os)
+TickedObject::serialize(CheckpointOut &cp) const
{
- Ticked::serialize(os);
- ClockedObject::serialize(os);
+ Ticked::serialize(cp);
+ ClockedObject::serialize(cp);
}
void
-TickedObject::unserialize(Checkpoint *cp, const std::string &section)
+TickedObject::unserialize(CheckpointIn &cp)
{
- Ticked::unserialize(cp, section);
- ClockedObject::unserialize(cp, section);
+ Ticked::unserialize(cp);
+ ClockedObject::unserialize(cp);
}
diff --git a/src/sim/ticked_object.hh b/src/sim/ticked_object.hh
index ee143e0df..97750873f 100644
--- a/src/sim/ticked_object.hh
+++ b/src/sim/ticked_object.hh
@@ -56,7 +56,7 @@
*
* Ticked is not a ClockedObject but can be attached to one by
* inheritance and by calling regStats, serialize/unserialize */
-class Ticked
+class Ticked : public Serializable
{
protected:
/** An event to call process periodically */
@@ -164,8 +164,8 @@ class Ticked
}
/** Checkpoint lastStopped */
- void serialize(std::ostream &os);
- void unserialize(Checkpoint *cp, const std::string &section);
+ void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
+ void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
/** Action to call on the clock tick */
virtual void evaluate() = 0;
@@ -199,8 +199,8 @@ class TickedObject : public ClockedObject, public Ticked
/** Pass on regStats, serialize etc. onto Ticked */
void regStats();
- void serialize(std::ostream &os);
- void unserialize(Checkpoint *cp, const std::string &section);
+ void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
+ void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
};
#endif /* __SIM_TICKED_OBJECT_HH__ */
diff --git a/src/sim/voltage_domain.cc b/src/sim/voltage_domain.cc
index 2b16d04b9..b82efda33 100644
--- a/src/sim/voltage_domain.cc
+++ b/src/sim/voltage_domain.cc
@@ -142,12 +142,14 @@ VoltageDomainParams::create()
}
void
-VoltageDomain::serialize(std::ostream &os) {
+VoltageDomain::serialize(CheckpointOut &cp) const
+{
SERIALIZE_SCALAR(_perfLevel);
}
void
-VoltageDomain::unserialize(Checkpoint *cp, const std::string &section) {
+VoltageDomain::unserialize(CheckpointIn &cp)
+{
UNSERIALIZE_SCALAR(_perfLevel);
perfLevel(_perfLevel);
}
diff --git a/src/sim/voltage_domain.hh b/src/sim/voltage_domain.hh
index ab96abad8..596daba40 100644
--- a/src/sim/voltage_domain.hh
+++ b/src/sim/voltage_domain.hh
@@ -128,8 +128,9 @@ class VoltageDomain : public SimObject
void regStats();
- void serialize(std::ostream &os);
- void unserialize(Checkpoint *cp, const std::string &section);
+ void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
+ void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
+
private:
typedef std::vector<double> Voltages;
/**