X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fsim%2Fserialize.hh;h=1f31dd2033a41a69bbdcca0be5bb2701e6b165f1;hb=968fb5cdee848a18a6cef064fd740ad33cec018c;hp=677a3fd92ec898041dd09916ba1a4e340b42d43e;hpb=345dfd1b41729162ff31da010cce0659ce810897;p=gem5.git diff --git a/src/sim/serialize.hh b/src/sim/serialize.hh index 677a3fd92..1f31dd203 100644 --- a/src/sim/serialize.hh +++ b/src/sim/serialize.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2015, 2018 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. * @@ -24,10 +36,6 @@ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Nathan Binkert - * Erik Hallnor - * Steve Reinhardt */ /* @file @@ -38,231 +46,838 @@ #define __SERIALIZE_HH__ -#include -#include +#include #include +#include #include +#include +#include +#include -#include "base/types.hh" +#include "base/bitunion.hh" +#include "base/logging.hh" +#include "base/str.hh" class IniFile; -class Serializable; -class Checkpoint; class SimObject; +class SimObjectResolver; -template -void paramOut(std::ostream &os, const std::string &name, const T ¶m); +typedef std::ostream CheckpointOut; -template -void paramIn(Checkpoint *cp, const std::string §ion, - const std::string &name, T ¶m); +class CheckpointIn +{ + private: -template -bool optParamIn(Checkpoint *cp, const std::string §ion, - const std::string &name, T ¶m); + IniFile *db; -template -void arrayParamOut(std::ostream &os, const std::string &name, - const T *param, unsigned size); + SimObjectResolver &objNameResolver; -template -void arrayParamOut(std::ostream &os, const std::string &name, - const std::vector ¶m); + const std::string _cptDir; -template -void arrayParamIn(Checkpoint *cp, const std::string §ion, - const std::string &name, T *param, unsigned size); - -template -void arrayParamIn(Checkpoint *cp, const std::string §ion, - const std::string &name, std::vector ¶m); + public: + CheckpointIn(const std::string &cpt_dir, SimObjectResolver &resolver); + ~CheckpointIn(); -void -objParamIn(Checkpoint *cp, const std::string §ion, - const std::string &name, SimObject * ¶m); + /** + * @ingroup api_serialize + * @{ + */ + const std::string getCptDir() { return _cptDir; } + bool find(const std::string §ion, const std::string &entry, + std::string &value); -// -// 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) + bool findObj(const std::string §ion, const std::string &entry, + SimObject *&value); -#define UNSERIALIZE_SCALAR(scalar) paramIn(cp, section, #scalar, scalar) -#define UNSERIALIZE_OPT_SCALAR(scalar) optParamIn(cp, section, #scalar, scalar) + bool entryExists(const std::string §ion, const std::string &entry); + bool sectionExists(const std::string §ion); + /** @}*/ //end of api_checkout group -// ENUMs are like SCALARs, but we cast them to ints on the way out -#define SERIALIZE_ENUM(scalar) paramOut(os, #scalar, (int)scalar) + // The following static functions have to do with checkpoint + // creation rather than restoration. This class makes a handy + // namespace for them though. Currently no Checkpoint object is + // created on serialization (only unserialization) so we track the + // directory name as a global. It would be nice to change this + // someday -#define UNSERIALIZE_ENUM(scalar) \ - do { \ - int tmp; \ - paramIn(cp, section, #scalar, tmp); \ - scalar = (typeof(scalar))tmp; \ - } while (0) + private: + // current directory we're serializing into. + static std::string currentDirectory; -#define SERIALIZE_ARRAY(member, size) \ - arrayParamOut(os, #member, member, size) -#define UNSERIALIZE_ARRAY(member, size) \ - arrayParamIn(cp, section, #member, member, size) + public: + /** + * Set the current directory + * + * This function takes care of inserting curTick() if there's a '%d' in the + * argument, and appends a '/' if necessary. The final name is returned. + * + * @ingroup api_serialize + */ + static std::string setDir(const std::string &base_name); -#define SERIALIZE_OBJPTR(objptr) paramOut(os, #objptr, (objptr)->name()) + /** + * Get the current checkout directory name + * + * This function exports the current checkout point directory name so other + * objects can derive filenames from it (e.g., memory). The return value is + * guaranteed to end in '/' so filenames can be directly appended. This + * function is only valid while a checkpoint is being created. + * + * @ingroup api_serialize + */ + static std::string dir(); -#define UNSERIALIZE_OBJPTR(objptr) \ - do { \ - SimObject *sptr; \ - objParamIn(cp, section, #objptr, sptr); \ - objptr = dynamic_cast(sptr); \ - } while (0) + // Filename for base checkpoint file within directory. + static const char *baseFilename; +}; -/* +/** * 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 + * 'draining'. Objects that need draining inherit from Drainable. See + * Drainable for more information. */ 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: + /** + * @ingroup api_serialize + * @{ + */ + template + ScopedCheckpointSection(CP &cp, const char *name) { + pushName(name); + nameOut(cp); + } + + template + ScopedCheckpointSection(CP &cp, const std::string &name) { + pushName(name.c_str()); + nameOut(cp); + } + /** @}*/ //end of api_serialize group + + ~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: + /** + * @ingroup api_serialize + */ 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); + /** + * Serialize an object + * + * Output an object's state into the current checkpoint section. + * + * @param cp Checkpoint state + * + * @ingroup api_serialize + */ + virtual void serialize(CheckpointOut &cp) const = 0; + + /** + * Unserialize an object + * + * Read an object's state from the current checkpoint section. + * + * @param cp Checkpoint state + * + * @ingroup api_serialize + */ + 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 + * + * @ingroup api_serialize + */ + void serializeSection(CheckpointOut &cp, const char *name) const; + + /** + * @ingroup api_serialize + */ + 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 + * + * @ingroup api_serialize + */ + void unserializeSection(CheckpointIn &cp, const char *name); + + /** + * @ingroup api_serialize + */ + void unserializeSection(CheckpointIn &cp, const std::string &name) { + unserializeSection(cp, name.c_str()); + } + + /** + * Gets the fully-qualified name of the active section + * + * @ingroup api_serialize + */ + static const std::string ¤tSection(); + + /** + * @ingroup api_serialize + */ + static void serializeAll(const std::string &cpt_dir); - static Serializable *create(Checkpoint *cp, const std::string §ion); + /** + * @ingroup api_serialize + */ + static void unserializeGlobals(CheckpointIn &cp); - static int ckptCount; - static int ckptMaxCount; - static int ckptPrevCount; - static void serializeAll(const std::string &cpt_dir); - static void unserializeAll(const std::string &cpt_dir); - static void unserializeGlobals(Checkpoint *cp); + private: + static std::stack path; }; -// -// A SerializableBuilder serves as an evaluation context for a set of -// parameters that describe a specific instance of a Serializable. This -// evaluation context corresponds to a section in the .ini file (as -// with the base ParamContext) plus an optional node in the -// configuration hierarchy (the configNode member) for resolving -// Serializable references. SerializableBuilder is an abstract superclass; -// derived classes specialize the class for particular subclasses of -// Serializable (e.g., BaseCache). -// -// For typical usage, see the definition of -// SerializableClass::createObject(). -// -class SerializableBuilder +/** + * @ingroup api_serialize + */ +template +bool +parseParam(const std::string &s, T &value) { - public: + // The base implementations use to_number for parsing and '<<' for + // displaying, suitable for integer types. + return to_number(s, value); +} - SerializableBuilder() {} +/** + * @ingroup api_serialize + */ +template +void +showParam(CheckpointOut &os, const T &value) +{ + os << value; +} - virtual ~SerializableBuilder() {} +/** + * @ingroup api_serialize + */ +template +bool +parseParam(const std::string &s, BitUnionType &value) +{ + // Zero initialize storage to avoid leaking an uninitialized value + BitUnionBaseType storage = BitUnionBaseType(); + auto res = to_number(s, storage); + value = storage; + return res; +} + +/** + * @ingroup api_serialize + */ +template +void +showParam(CheckpointOut &os, const BitUnionType &value) +{ + auto storage = static_cast>(value); - // Create the actual Serializable corresponding to the parameter - // values in this context. This function is overridden in derived - // classes to call a specific constructor for a particular - // subclass of Serializable. - virtual Serializable *create() = 0; -}; + // For a BitUnion8, the storage type is an unsigned char. + // Since we want to serialize a number we need to cast to + // unsigned int + os << ((sizeof(storage) == 1) ? + static_cast(storage) : storage); +} -// -// An instance of SerializableClass corresponds to a class derived from -// Serializable. The SerializableClass instance serves to bind the string -// name (found in the config file) to a function that creates an -// instance of the appropriate derived class. -// -// This would be much cleaner in Smalltalk or Objective-C, where types -// are first-class objects themselves. -// -class SerializableClass +/** + * @ingroup api_serialize + */ +template <> +inline void +showParam(CheckpointOut &os, const char &value) { - public: + // Treat 8-bit ints (chars) as ints on output, not as chars + os << (int)value; +} - // Type CreateFunc is a pointer to a function that creates a new - // simulation object builder based on a .ini-file parameter - // section (specified by the first string argument), a unique name - // 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, - const std::string §ion); - - static std::map *classMap; - - // Constructor. For example: - // - // SerializableClass baseCacheSerializableClass("BaseCacheSerializable", - // newBaseCacheSerializableBuilder); - // - SerializableClass(const std::string &className, CreateFunc createFunc); - - // create Serializable given name of class and pointer to - // configuration hierarchy node - static Serializable *createObject(Checkpoint *cp, - const std::string §ion); -}; +/** + * @ingroup api_serialize + */ +template <> +inline void +showParam(CheckpointOut &os, const signed char &value) +{ + os << (int)value; +} -// -// Macros to encapsulate the magic of declaring & defining -// SerializableBuilder and SerializableClass objects -// +/** + * @ingroup api_serialize + */ +template <> +inline void +showParam(CheckpointOut &os, const unsigned char &value) +{ + os << (unsigned int)value; +} -#define REGISTER_SERIALIZEABLE(CLASS_NAME, OBJ_CLASS) \ -SerializableClass the##OBJ_CLASS##Class(CLASS_NAME, \ - OBJ_CLASS::createForUnserialize); +/** + * @ingroup api_serialize + */ +template <> +inline bool +parseParam(const std::string &s, float &value) +{ + return to_number(s, value); +} -class Checkpoint +/** + * @ingroup api_serialize + */ +template <> +inline bool +parseParam(const std::string &s, double &value) { - private: + return to_number(s, value); +} - IniFile *db; +/** + * @ingroup api_serialize + */ +template <> +inline bool +parseParam(const std::string &s, bool &value) +{ + return to_bool(s, value); +} - public: - Checkpoint(const std::string &cpt_dir); +/** + * @ingroup api_serialize + */ +template <> +inline void +showParam(CheckpointOut &os, const bool &value) +{ + // Display bools as strings + os << (value ? "true" : "false"); +} - const std::string cptDir; +/** + * @ingroup api_serialize + */ +template <> +inline bool +parseParam(const std::string &s, std::string &value) +{ + // String requires no processing to speak of + value = s; + return true; +} - bool find(const std::string §ion, const std::string &entry, - std::string &value); +/** + * @ingroup api_serialize + */ +template +void +paramOut(CheckpointOut &os, const std::string &name, const T ¶m) +{ + os << name << "="; + showParam(os, param); + os << "\n"; +} - bool findObj(const std::string §ion, const std::string &entry, - SimObject *&value); +/** + * @ingroup api_serialize + */ +template +void +paramIn(CheckpointIn &cp, const std::string &name, T ¶m) +{ + const std::string §ion(Serializable::currentSection()); + std::string str; + if (!cp.find(section, name, str) || !parseParam(str, param)) { + fatal("Can't unserialize '%s:%s'\n", section, name); + } +} + +/** + * @ingroup api_serialize + */ +template +bool +optParamIn(CheckpointIn &cp, const std::string &name, + T ¶m, bool warn = true) +{ + const std::string §ion(Serializable::currentSection()); + std::string str; + if (!cp.find(section, name, str) || !parseParam(str, param)) { + if (warn) + warn("optional parameter %s:%s not present\n", section, name); + return false; + } else { + return true; + } +} + +/** + * @ingroup api_serialize + */ +template +void +arrayParamOut(CheckpointOut &os, const std::string &name, + const std::vector ¶m) +{ + typename std::vector::size_type size = param.size(); + os << name << "="; + if (size > 0) + showParam(os, param[0]); + for (typename std::vector::size_type i = 1; i < size; ++i) { + os << " "; + showParam(os, param[i]); + } + os << "\n"; +} + +/** + * @ingroup api_serialize + */ +template +void +arrayParamOut(CheckpointOut &os, const std::string &name, + const std::list ¶m) +{ + typename std::list::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"; +} + +/** + * @ingroup api_serialize + */ +template +void +arrayParamOut(CheckpointOut &os, const std::string &name, + const std::set ¶m) +{ + typename std::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"; +} + +/** + * @ingroup api_serialize + */ +template +void +arrayParamOut(CheckpointOut &os, const std::string &name, + const T *param, unsigned size) +{ + os << name << "="; + if (size > 0) + showParam(os, param[0]); + for (unsigned i = 1; i < size; ++i) { + os << " "; + showParam(os, param[i]); + } + os << "\n"; +} + +/** + * Extract values stored in the checkpoint, and assign them to the provided + * array container. + * + * @param cp The checkpoint to be parsed. + * @param name Name of the container. + * @param param The array container. + * @param size The expected number of entries to be extracted. + * + * @ingroup api_serialize + */ +template +void +arrayParamIn(CheckpointIn &cp, const std::string &name, + T *param, unsigned size) +{ + const std::string §ion(Serializable::currentSection()); + std::string str; + if (!cp.find(section, name, str)) { + fatal("Can't unserialize '%s:%s'\n", section, name); + } - bool sectionExists(const std::string §ion); + // code below stolen from VectorParam::parse(). + // it would be nice to unify these somehow... - // The following static functions have to do with checkpoint - // creation rather than restoration. This class makes a handy - // namespace for them though. Currently no Checkpoint object is - // created on serialization (only unserialization) so we track the - // directory name as a global. It would be nice to change this - // someday + std::vector tokens; - private: - // current directory we're serializing into. - static std::string currentDirectory; + tokenize(tokens, str, ' '); - public: - // Set the current directory. This function takes care of - // inserting curTick if there's a '%d' in the argument, and - // appends a '/' if necessary. The final name is returned. - static std::string setDir(const std::string &base_name); + // Need this if we were doing a vector + // value.resize(tokens.size()); - // Export current checkpoint directory name so other objects can - // derive filenames from it (e.g., memory). The return value is - // guaranteed to end in '/' so filenames can be directly appended. - // This function is only valid while a checkpoint is being created. - static std::string dir(); + fatal_if(tokens.size() != size, + "Array size mismatch on %s:%s (Got %u, expected %u)'\n", + section, name, tokens.size(), size); - // Filename for base checkpoint file within directory. - static const char *baseFilename; -}; + for (std::vector::size_type i = 0; i < tokens.size(); i++) { + // need to parse into local variable to handle vector, + // for which operator[] returns a special reference class + // that's not the same as 'bool&', (since it's a packed + // vector) + T scalar_value; + if (!parseParam(tokens[i], scalar_value)) { + std::string err("could not parse \""); + + err += str; + err += "\""; + + fatal(err); + } + + // assign parsed value to vector + param[i] = scalar_value; + } +} + +/** + * @ingroup api_serialize + */ +template +void +arrayParamIn(CheckpointIn &cp, const std::string &name, std::vector ¶m) +{ + const std::string §ion(Serializable::currentSection()); + std::string str; + if (!cp.find(section, name, str)) { + fatal("Can't unserialize '%s:%s'\n", section, name); + } + + // code below stolen from VectorParam::parse(). + // it would be nice to unify these somehow... + + std::vector tokens; + + tokenize(tokens, str, ' '); + + // Need this if we were doing a vector + // value.resize(tokens.size()); + + param.resize(tokens.size()); + + for (std::vector::size_type i = 0; i < tokens.size(); i++) { + // need to parse into local variable to handle vector, + // for which operator[] returns a special reference class + // that's not the same as 'bool&', (since it's a packed + // vector) + T scalar_value; + if (!parseParam(tokens[i], scalar_value)) { + std::string err("could not parse \""); + + err += str; + err += "\""; + + fatal(err); + } + + // assign parsed value to vector + param[i] = scalar_value; + } +} + +/** + * @ingroup api_serialize + */ +template +void +arrayParamIn(CheckpointIn &cp, const std::string &name, std::list ¶m) +{ + const std::string §ion(Serializable::currentSection()); + std::string str; + if (!cp.find(section, name, str)) { + fatal("Can't unserialize '%s:%s'\n", section, name); + } + param.clear(); + + std::vector tokens; + tokenize(tokens, str, ' '); + + for (std::vector::size_type i = 0; i < tokens.size(); i++) { + T scalar_value; + if (!parseParam(tokens[i], scalar_value)) { + std::string err("could not parse \""); + + err += str; + err += "\""; + + fatal(err); + } + + // assign parsed value to vector + param.push_back(scalar_value); + } +} + +/** + * @ingroup api_serialize + */ +template +void +arrayParamIn(CheckpointIn &cp, const std::string &name, std::set ¶m) +{ + const std::string §ion(Serializable::currentSection()); + std::string str; + if (!cp.find(section, name, str)) { + fatal("Can't unserialize '%s:%s'\n", section, name); + } + param.clear(); + + std::vector tokens; + tokenize(tokens, str, ' '); + + for (std::vector::size_type i = 0; i < tokens.size(); i++) { + T scalar_value; + if (!parseParam(tokens[i], scalar_value)) { + std::string err("could not parse \""); + + err += str; + err += "\""; + + fatal(err); + } + + // assign parsed value to vector + param.insert(scalar_value); + } +} + +void +debug_serialize(const std::string &cpt_dir); + + +/** + * @ingroup api_serialize + */ +void +objParamIn(CheckpointIn &cp, const std::string &name, SimObject * ¶m); + +// +// 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'. + + +/** + * \def SERIALIZE_SCALER(scaler) + * + * @ingroup api_serialize + */ +#define SERIALIZE_SCALAR(scalar) paramOut(cp, #scalar, scalar) + +/** + * \def UNSERIALIZE_SCALER(scalar) + * + * @ingroup api_serialize + */ +#define UNSERIALIZE_SCALAR(scalar) paramIn(cp, #scalar, scalar) + +/** + * \def UNSERIALIZE_OPT_SCALAR(scalar) + * + * @ingroup api_serialize + */ +#define UNSERIALIZE_OPT_SCALAR(scalar) optParamIn(cp, #scalar, scalar) + +// ENUMs are like SCALARs, but we cast them to ints on the way out + +/** + * \def SERIALIZE_ENUM(scalar) + * + * @ingroup api_serialize + */ +#define SERIALIZE_ENUM(scalar) paramOut(cp, #scalar, (int)scalar) + +/** + * \def UNSERIALIZE_ENUM(scaler) + * + * @ingroup api_serialize + */ +#define UNSERIALIZE_ENUM(scalar) \ + do { \ + int tmp; \ + paramIn(cp, #scalar, tmp); \ + scalar = static_cast(tmp); \ + } while (0) + +/** + * \def SERIALIZE_ARRAY(member, size) + * + * @ingroup api_serialize + */ +#define SERIALIZE_ARRAY(member, size) \ + arrayParamOut(cp, #member, member, size) + +/** + * \def UNSERIALIZE_ARRAY(member, size) + * + * @ingroup api_serialize + */ +#define UNSERIALIZE_ARRAY(member, size) \ + arrayParamIn(cp, #member, member, size) + +/** + * \def SERIALIZE_CONTAINER(member) + * + * @ingroup api_serialize + */ +#define SERIALIZE_CONTAINER(member) \ + arrayParamOut(cp, #member, member) + +/** + * \def UNSERIALIZE_CONTAINER(member) + * + * @ingroup api_serialize + */ +#define UNSERIALIZE_CONTAINER(member) \ + arrayParamIn(cp, #member, member) + +/** + * \def SERIALIZE_EVENT(event) + * + * @ingroup api_serialize + */ +#define SERIALIZE_EVENT(event) event.serializeSection(cp, #event); + +/** + * \def UNSERIALIZE_EVENT(event) + * + * @ingroup api_serialize + */ +#define UNSERIALIZE_EVENT(event) \ + do { \ + event.unserializeSection(cp, #event); \ + eventQueue()->checkpointReschedule(&event); \ + } while (0) + +/** + * \def SERIALIZE_OBJ(obj) + * + * @ingroup api_serialize + */ +#define SERIALIZE_OBJ(obj) obj.serializeSection(cp, #obj) + +/** + * \def UNSERIALIZE_OBJ(obj) + * + * @ingroup api_serialize + */ +#define UNSERIALIZE_OBJ(obj) obj.unserializeSection(cp, #obj) + +/** + * \def SERIALIZE_OBJPTR(objptr) + * + * @ingroup api_serialize + */ +#define SERIALIZE_OBJPTR(objptr) paramOut(cp, #objptr, (objptr)->name()) + +/** + * \def UNSERIALIZE_OBJPTR(objptr) + * + * @ingroup api_serialize + */ +#define UNSERIALIZE_OBJPTR(objptr) \ + do { \ + SimObject *sptr; \ + objParamIn(cp, #objptr, sptr); \ + objptr = dynamic_cast(sptr); \ + } while (0) #endif // __SERIALIZE_HH__