From 1ad5b772291220d44b355d8d939d625db7dffc1a Mon Sep 17 00:00:00 2001 From: Curtis Dunham Date: Wed, 2 Sep 2015 15:19:43 -0500 Subject: sim: make warning for absent optional parameters optional This is in support of tag-based checkpoint versioning. It should be possible to examine an optional parameter in a checkpoint during unserialization and not have it throw a warning. --- src/sim/serialize.cc | 8 +++++--- src/sim/serialize.hh | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'src/sim') diff --git a/src/sim/serialize.cc b/src/sim/serialize.cc index 3127d9a04..0ecf45b6d 100644 --- a/src/sim/serialize.cc +++ b/src/sim/serialize.cc @@ -223,12 +223,13 @@ paramIn(CheckpointIn &cp, const string &name, T ¶m) template bool -optParamIn(CheckpointIn &cp, const string &name, T ¶m) +optParamIn(CheckpointIn &cp, const string &name, T ¶m, bool warn) { const string §ion(Serializable::currentSection()); string str; if (!cp.find(section, name, str) || !parseParam(str, param)) { - warn("optional parameter %s:%s not present\n", section, name); + if (warn) + warn("optional parameter %s:%s not present\n", section, name); return false; } else { return true; @@ -384,7 +385,8 @@ objParamIn(CheckpointIn &cp, const string &name, SimObject * ¶m) template void \ paramIn(CheckpointIn &cp, const string &name, type & param); \ template bool \ - optParamIn(CheckpointIn &cp, const string &name, type & param); \ + optParamIn(CheckpointIn &cp, const string &name, type & param, \ + bool warn); \ template void \ arrayParamOut(CheckpointOut &os, const string &name, \ type const *param, unsigned size); \ diff --git a/src/sim/serialize.hh b/src/sim/serialize.hh index 561cd5508..e3b761f10 100644 --- a/src/sim/serialize.hh +++ b/src/sim/serialize.hh @@ -100,13 +100,15 @@ void paramIn(CheckpointIn &cp, const std::string &name, } template -bool optParamIn(CheckpointIn &cp, const std::string &name, T ¶m); +bool optParamIn(CheckpointIn &cp, const std::string &name, T ¶m, + bool warn = true); template bool optParamIn(CheckpointIn &cp, const std::string &name, - BitfieldBackend::BitUnionOperators &p) + BitfieldBackend::BitUnionOperators &p, + bool warn = true) { - return optParamIn(cp, name, p.__data); + return optParamIn(cp, name, p.__data, warn); } template -- cgit v1.2.3 From 62e0344aefd56cb1878cdbc27dbed11d6cc73ba4 Mon Sep 17 00:00:00 2001 From: Curtis Dunham Date: Wed, 2 Sep 2015 15:19:44 -0500 Subject: sim: support checkpointing std::set's This is in support of tag-based checkpoint versioning; the version tags are stored in string sets. This commit adds such support. --- src/sim/serialize.cc | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/sim/serialize.hh | 9 +++++++++ 2 files changed, 62 insertions(+) (limited to 'src/sim') diff --git a/src/sim/serialize.cc b/src/sim/serialize.cc index 0ecf45b6d..0904b1375 100644 --- a/src/sim/serialize.cc +++ b/src/sim/serialize.cc @@ -210,6 +210,24 @@ arrayParamOut(CheckpointOut &os, const string &name, const list ¶m) os << "\n"; } +template +void +arrayParamOut(CheckpointOut &os, const string &name, const set ¶m) +{ + typename set::const_iterator it = param.begin(); + + os << name << "="; + if (param.size() > 0) + showParam(os, *it); + it++; + while (it != param.end()) { + os << " "; + showParam(os, *it); + it++; + } + os << "\n"; +} + template void paramIn(CheckpointIn &cp, const string &name, T ¶m) @@ -368,6 +386,36 @@ arrayParamIn(CheckpointIn &cp, const string &name, list ¶m) } } +template +void +arrayParamIn(CheckpointIn &cp, const string &name, set ¶m) +{ + const string §ion(Serializable::currentSection()); + string str; + if (!cp.find(section, name, str)) { + fatal("Can't unserialize '%s:%s'\n", section, name); + } + param.clear(); + + vector tokens; + tokenize(tokens, str, ' '); + + for (vector::size_type i = 0; i < tokens.size(); i++) { + T scalar_value; + if (!parseParam(tokens[i], scalar_value)) { + string err("could not parse \""); + + err += str; + err += "\""; + + fatal(err); + } + + // assign parsed value to vector + param.insert(scalar_value); + } +} + void objParamIn(CheckpointIn &cp, const string &name, SimObject * ¶m) @@ -423,6 +471,11 @@ INSTANTIATE_PARAM_TEMPLATES(double) INSTANTIATE_PARAM_TEMPLATES(string) INSTANTIATE_PARAM_TEMPLATES(Pixel) +// set is only used with strings and furthermore doesn't agree with Pixel +template void +arrayParamOut(CheckpointOut &, const string &, const set &); +template void +arrayParamIn(CheckpointIn &, const string &, set &); ///////////////////////////// diff --git a/src/sim/serialize.hh b/src/sim/serialize.hh index e3b761f10..4a2cc04e9 100644 --- a/src/sim/serialize.hh +++ b/src/sim/serialize.hh @@ -55,6 +55,7 @@ #include #include #include +#include #include #include "base/bitunion.hh" @@ -123,6 +124,10 @@ template void arrayParamOut(CheckpointOut &cp, const std::string &name, const std::list ¶m); +template +void arrayParamOut(CheckpointOut &cp, const std::string &name, + const std::set ¶m); + template void arrayParamIn(CheckpointIn &cp, const std::string &name, T *param, unsigned size); @@ -135,6 +140,10 @@ template void arrayParamIn(CheckpointIn &cp, const std::string &name, std::list ¶m); +template +void arrayParamIn(CheckpointIn &cp, const std::string &name, + std::set ¶m); + void objParamIn(CheckpointIn &cp, const std::string &name, SimObject * ¶m); -- cgit v1.2.3 From 87b9da2df4d4dc0028566a7803ee55159343d735 Mon Sep 17 00:00:00 2001 From: Curtis Dunham Date: Wed, 2 Sep 2015 15:23:30 -0500 Subject: sim: tag-based checkpoint versioning This commit addresses gem5 checkpoints' linear versioning bottleneck. Since development is distributed across many private trees, there exists a sort of 'race' for checkpoint version numbers: internally a checkpoint version may be used but then resynchronizing with the external tree causes a conflict on that version. This change replaces the linear version number with a set of unique strings called tags. Now the only conflicts that can arise are of tag names, where collisions are much easier to avoid. The checkpoint upgrader (util/cpt_upgrader.py) upgrades the version representation, as one would expect. Each tag version implements its upgrader code in a python file in the util/cpt_upgraders directory rather than adding a function to the upgrader script itself. The version tags are stored in the 'Globals' section rather than 'root' (as the version was previously) because 'Globals' gets unserialized first and can provide a warning before any other unserialization errors can occur. --- src/sim/SConscript | 1 + src/sim/root.cc | 24 +--------------------- src/sim/serialize.cc | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/sim/serialize.hh | 9 --------- 4 files changed, 59 insertions(+), 32 deletions(-) (limited to 'src/sim') diff --git a/src/sim/SConscript b/src/sim/SConscript index 0b3a35915..204bfca3b 100644 --- a/src/sim/SConscript +++ b/src/sim/SConscript @@ -42,6 +42,7 @@ SimObject('SubSystem.py') Source('arguments.cc') Source('async.cc') Source('core.cc') +Source('tags.cc') Source('cxx_config.cc') Source('cxx_manager.cc') Source('cxx_config_ini.cc') diff --git a/src/sim/root.cc b/src/sim/root.cc index 1d58c3bbe..7647ca5b7 100644 --- a/src/sim/root.cc +++ b/src/sim/root.cc @@ -132,8 +132,6 @@ Root::loadState(CheckpointIn &cp) void Root::serialize(CheckpointOut &cp) const { - uint64_t cpt_ver = gem5CheckpointVersion; - SERIALIZE_SCALAR(cpt_ver); SERIALIZE_SCALAR(FullSystem); std::string isa = THE_ISA_STR; SERIALIZE_SCALAR(isa); @@ -141,27 +139,7 @@ Root::serialize(CheckpointOut &cp) const void Root::unserialize(CheckpointIn &cp) -{ - uint64_t cpt_ver = 0; - UNSERIALIZE_OPT_SCALAR(cpt_ver); - if (cpt_ver < gem5CheckpointVersion) { - warn("**********************************************************\n"); - warn("!!!! Checkpoint ver %#x is older than current ver %#x !!!!\n", - cpt_ver, gem5CheckpointVersion); - warn("You might experience some issues when restoring and should run " - "the checkpoint upgrader (util/cpt_upgrader.py) on your " - "checkpoint\n"); - warn("**********************************************************\n"); - } else if (cpt_ver > gem5CheckpointVersion) { - warn("**********************************************************\n"); - warn("!!!! Checkpoint ver %#x is newer than current ver %#x !!!!\n", - cpt_ver, gem5CheckpointVersion); - warn("Running a new checkpoint with an older version of gem5 is not " - "supported. While it might work, you may experience incorrect " - "behavior or crashes.\n"); - warn("**********************************************************\n"); - } -} +{} bool FullSystem; diff --git a/src/sim/serialize.cc b/src/sim/serialize.cc index 0904b1375..f9a945b95 100644 --- a/src/sim/serialize.cc +++ b/src/sim/serialize.cc @@ -496,16 +496,73 @@ class Globals : public Serializable /// The one and only instance of the Globals class. Globals globals; +/// The version tags for this build of the simulator, to be stored in the +/// Globals section during serialization and compared upon unserialization. +extern std::set version_tags; + void Globals::serialize(CheckpointOut &cp) const { paramOut(cp, "curTick", curTick()); + SERIALIZE_CONTAINER(version_tags); } void Globals::unserialize(CheckpointIn &cp) { paramIn(cp, "curTick", unserializedCurTick); + + const std::string §ion(Serializable::currentSection()); + std::string str; + if (!cp.find(section, "version_tags", str)) { + warn("**********************************************************\n"); + warn("!!!! Checkpoint uses an old versioning scheme. !!!!\n"); + warn("Run the checkpoint upgrader (util/cpt_upgrader.py) on your " + "checkpoint\n"); + warn("**********************************************************\n"); + return; + } + + std::set cpt_tags; + arrayParamIn(cp, "version_tags", cpt_tags); // UNSERIALIZE_CONTAINER + + bool err = false; + for (const auto& t : version_tags) { + if (cpt_tags.find(t) == cpt_tags.end()) { + // checkpoint is missing tag that this binary has + if (!err) { + warn("*****************************************************\n"); + warn("!!!! Checkpoint is missing the following version tags:\n"); + err = true; + } + warn(" %s\n", t); + } + } + if (err) { + warn("You might experience some issues when restoring and should run " + "the checkpoint upgrader (util/cpt_upgrader.py) on your " + "checkpoint\n"); + warn("**********************************************************\n"); + } + + err = false; + for (const auto& t : cpt_tags) { + if (version_tags.find(t) == version_tags.end()) { + // gem5 binary is missing tag that this checkpoint has + if (!err) { + warn("*****************************************************\n"); + warn("!!!! gem5 is missing the following version tags:\n"); + err = true; + } + warn(" %s\n", t); + } + } + if (err) { + warn("Running a checkpoint with incompatible version tags is not " + "supported. While it might work, you may experience incorrect " + "behavior or crashes.\n"); + warn("**********************************************************\n"); + } } Serializable::Serializable() diff --git a/src/sim/serialize.hh b/src/sim/serialize.hh index 4a2cc04e9..9a1170a9e 100644 --- a/src/sim/serialize.hh +++ b/src/sim/serialize.hh @@ -71,15 +71,6 @@ 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 - * the current version until the checkpoint format is updated. Adding a new - * SimObject shouldn't cause the version number to increase, only changes to - * existing objects such as serializing/unserializing more state, changing sizes - * of serialized arrays, etc. */ -static const uint64_t gem5CheckpointVersion = 0x000000000000000f; - template void paramOut(CheckpointOut &cp, const std::string &name, const T ¶m); -- cgit v1.2.3