diff options
Diffstat (limited to 'src/sim')
-rw-r--r-- | src/sim/clock_domain.cc | 8 | ||||
-rw-r--r-- | src/sim/clock_domain.hh | 5 | ||||
-rw-r--r-- | src/sim/cxx_manager.cc | 2 | ||||
-rw-r--r-- | src/sim/cxx_manager.hh | 4 | ||||
-rw-r--r-- | src/sim/dvfs_handler.cc | 23 | ||||
-rw-r--r-- | src/sim/dvfs_handler.hh | 4 | ||||
-rw-r--r-- | src/sim/eventq.cc | 21 | ||||
-rw-r--r-- | src/sim/eventq.hh | 11 | ||||
-rw-r--r-- | src/sim/process.cc | 25 | ||||
-rw-r--r-- | src/sim/process.hh | 12 | ||||
-rw-r--r-- | src/sim/root.cc | 6 | ||||
-rw-r--r-- | src/sim/root.hh | 7 | ||||
-rw-r--r-- | src/sim/serialize.cc | 270 | ||||
-rw-r--r-- | src/sim/serialize.hh | 257 | ||||
-rw-r--r-- | src/sim/sim_events.cc | 17 | ||||
-rw-r--r-- | src/sim/sim_events.hh | 10 | ||||
-rw-r--r-- | src/sim/sim_object.cc | 15 | ||||
-rw-r--r-- | src/sim/sim_object.hh | 8 | ||||
-rw-r--r-- | src/sim/system.cc | 17 | ||||
-rw-r--r-- | src/sim/system.hh | 9 | ||||
-rw-r--r-- | src/sim/ticked_object.cc | 20 | ||||
-rw-r--r-- | src/sim/ticked_object.hh | 10 | ||||
-rw-r--r-- | src/sim/voltage_domain.cc | 6 | ||||
-rw-r--r-- | src/sim/voltage_domain.hh | 5 |
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 §ion) +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 §ion); + + 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 §ion) +DVFSHandler::unserialize(CheckpointIn &cp) { bool temp = enableHandler; @@ -213,9 +212,9 @@ DVFSHandler::unserialize(Checkpoint *cp, const std::string §ion) 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 §ion); + 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 §ion) +Event::unserialize(CheckpointIn &cp) { } void -Event::unserialize(Checkpoint *cp, const string §ion, EventQueue *eventq) +Event::unserializeEvent(CheckpointIn &cp, EventQueue *eventq) { if (scheduled()) eventq->deschedule(this); @@ -290,7 +290,7 @@ Event::unserialize(Checkpoint *cp, const string §ion, 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 §ion) +EventQueue::unserialize(CheckpointIn &cp) { int numEvents; UNSERIALIZE_SCALAR(numEvents); @@ -329,7 +326,7 @@ EventQueue::unserialize(Checkpoint *cp, const std::string §ion) 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 §ion); + 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 §ion, - 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 §ion); + 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 §ion) +Process::FdMap::unserialize(CheckpointIn &cp) { UNSERIALIZE_SCALAR(fd); UNSERIALIZE_SCALAR(isPipe); @@ -510,7 +517,7 @@ Process::FdMap::unserialize(Checkpoint *cp, const std::string §ion) } 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 §ion) +Process::unserialize(CheckpointIn &cp) { UNSERIALIZE_SCALAR(brk_point); UNSERIALIZE_SCALAR(stack_base); @@ -543,9 +548,9 @@ Process::unserialize(Checkpoint *cp, const std::string §ion) 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 §ion); + 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 §ion); + 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 §ion) +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 §ion); - + 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 ¶m) +paramOut(CheckpointOut &os, const string &name, const T ¶m) { os << name << "="; showParam(os, param); @@ -175,7 +178,7 @@ paramOut(ostream &os, const string &name, const T ¶m) template <class T> void -arrayParamOut(ostream &os, const string &name, const vector<T> ¶m) +arrayParamOut(CheckpointOut &os, const string &name, const vector<T> ¶m) { typename vector<T>::size_type size = param.size(); os << name << "="; @@ -190,7 +193,7 @@ arrayParamOut(ostream &os, const string &name, const vector<T> ¶m) template <class T> void -arrayParamOut(ostream &os, const string &name, const list<T> ¶m) +arrayParamOut(CheckpointOut &os, const string &name, const list<T> ¶m) { typename list<T>::const_iterator it = param.begin(); @@ -208,20 +211,22 @@ arrayParamOut(ostream &os, const string &name, const list<T> ¶m) template <class T> void -paramIn(Checkpoint *cp, const string §ion, const string &name, T ¶m) +paramIn(CheckpointIn &cp, const string &name, T ¶m) { + const string §ion(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 §ion, const string &name, T ¶m) +optParamIn(CheckpointIn &cp, const string &name, T ¶m) { + const string §ion(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 §ion, const string &name, T ¶m) 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 §ion, const string &name, - T *param, unsigned size) +arrayParamIn(CheckpointIn &cp, const string &name, T *param, unsigned size) { + const string §ion(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 §ion, 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 §ion, const string &name, template <class T> void -arrayParamIn(Checkpoint *cp, const string §ion, - const string &name, vector<T> ¶m) +arrayParamIn(CheckpointIn &cp, const string &name, vector<T> ¶m) { + const string §ion(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 §ion, // 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 §ion, template <class T> void -arrayParamIn(Checkpoint *cp, const string §ion, - const string &name, list<T> ¶m) +arrayParamIn(CheckpointIn &cp, const string &name, list<T> ¶m) { + const string §ion(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 §ion, 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 §ion, void -objParamIn(Checkpoint *cp, const string §ion, - const string &name, SimObject * ¶m) +objParamIn(CheckpointIn &cp, const string &name, SimObject * ¶m) { - if (!cp->findObj(section, name, param)) { + const string §ion(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 ¶m); \ -template void \ -paramIn(Checkpoint *cp, const string §ion, \ - const string &name, type & param); \ -template bool \ -optParamIn(Checkpoint *cp, const string §ion, \ - 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 §ion, \ - const string &name, type *param, unsigned size); \ -template void \ -arrayParamOut(ostream &os, const string &name, \ - const vector<type> ¶m); \ -template void \ -arrayParamIn(Checkpoint *cp, const string §ion, \ - const string &name, vector<type> ¶m); \ -template void \ -arrayParamOut(ostream &os, const string &name, \ - const list<type> ¶m); \ -template void \ -arrayParamIn(Checkpoint *cp, const string §ion, \ - const string &name, list<type> ¶m); + template void \ + paramOut(CheckpointOut &os, const string &name, type const ¶m); \ + 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> ¶m); \ + template void \ + arrayParamIn(CheckpointIn &cp, const string &name, \ + vector<type> ¶m); \ + template void \ + arrayParamOut(CheckpointOut &os, const string &name, \ + const list<type> ¶m); \ + template void \ + arrayParamIn(CheckpointIn &cp, const string &name, \ + list<type> ¶m); 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 §ion); + 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 §ion) +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 §ion) +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 §ion) +SerializableClass::createObject(CheckpointIn &cp, const string §ion) { 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 §ion) return object; } +const std::string & +Serializable::currentSection() +{ + assert(!path.empty()); + + return path.top(); +} Serializable * -Serializable::create(Checkpoint *cp, const string §ion) +Serializable::create(CheckpointIn &cp, const string §ion) { 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 §ion, const string &entry, string &value) +CheckpointIn::find(const string §ion, const string &entry, string &value) { return db->find(section, entry, value); } bool -Checkpoint::findObj(const string §ion, const string &entry, +CheckpointIn::findObj(const string §ion, const string &entry, SimObject *&value) { string path; @@ -634,7 +676,7 @@ Checkpoint::findObj(const string §ion, const string &entry, bool -Checkpoint::sectionExists(const string §ion) +CheckpointIn::sectionExists(const string §ion) { 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 ¶m); +void paramOut(CheckpointOut &cp, const std::string &name, const T ¶m); 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 §ion, - const std::string &name, T ¶m); +void paramIn(CheckpointIn &cp, const std::string &name, T ¶m); template <typename DataType, typename BitUnion> -void paramIn(Checkpoint *cp, const std::string §ion, - 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 §ion, - const std::string &name, T ¶m); +bool optParamIn(CheckpointIn &cp, const std::string &name, T ¶m); template <typename DataType, typename BitUnion> -bool optParamIn(Checkpoint *cp, const std::string §ion, - 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> ¶m); template <class T> -void arrayParamOut(std::ostream &os, const std::string &name, +void arrayParamOut(CheckpointOut &cp, const std::string &name, const std::list<T> ¶m); template <class T> -void arrayParamIn(Checkpoint *cp, const std::string §ion, - 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 §ion, - const std::string &name, std::vector<T> ¶m); +void arrayParamIn(CheckpointIn &cp, const std::string &name, + std::vector<T> ¶m); template <class T> -void arrayParamIn(Checkpoint *cp, const std::string §ion, - const std::string &name, std::list<T> ¶m); +void arrayParamIn(CheckpointIn &cp, const std::string &name, + std::list<T> ¶m); void -objParamIn(Checkpoint *cp, const std::string §ion, - const std::string &name, SimObject * ¶m); +objParamIn(CheckpointIn &cp, const std::string &name, SimObject * ¶m); 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 §ion); - - static Serializable *create(Checkpoint *cp, const std::string §ion); + /** + * 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 ¤tSection(); + + static Serializable *create(CheckpointIn &cp, const std::string §ion); 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 §ion); 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 §ion); }; @@ -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 §ion) +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 §ion) } void -LocalSimLoopExitEvent::unserialize(Checkpoint *cp, const string §ion, - 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 §ion, } Serializable * -LocalSimLoopExitEvent::createForUnserialize(Checkpoint *cp, +LocalSimLoopExitEvent::createForUnserialize(CheckpointIn &cp, const string §ion) { 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 §ion); - virtual void unserialize(Checkpoint *cp, const std::string §ion, - 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 §ion); }; 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 §ion) +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 §ion); + 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 §ion) {} + 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 §ion) +Ticked::unserialize(CheckpointIn &cp) { uint64_t lastStoppedUint = 0; @@ -90,7 +90,7 @@ Ticked::unserialize(Checkpoint *cp, const std::string §ion) * 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 §ion) +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 §ion); + 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 §ion); + 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 §ion) { +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 §ion); + void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE; + void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE; + private: typedef std::vector<double> Voltages; /** |