serialize.hh revision 13415
12SN/A/*
213107Sgiacomo.travaglini@arm.com * Copyright (c) 2015, 2018 ARM Limited
310905Sandreas.sandberg@arm.com * All rights reserved
410905Sandreas.sandberg@arm.com *
510905Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall
610905Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual
710905Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating
810905Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software
910905Sandreas.sandberg@arm.com * licensed hereunder.  You may use the software subject to the license
1010905Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated
1110905Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software,
1210905Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form.
1310905Sandreas.sandberg@arm.com *
141762SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
152SN/A * All rights reserved.
162SN/A *
172SN/A * Redistribution and use in source and binary forms, with or without
182SN/A * modification, are permitted provided that the following conditions are
192SN/A * met: redistributions of source code must retain the above copyright
202SN/A * notice, this list of conditions and the following disclaimer;
212SN/A * redistributions in binary form must reproduce the above copyright
222SN/A * notice, this list of conditions and the following disclaimer in the
232SN/A * documentation and/or other materials provided with the distribution;
242SN/A * neither the name of the copyright holders nor the names of its
252SN/A * contributors may be used to endorse or promote products derived from
262SN/A * this software without specific prior written permission.
272SN/A *
282SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
292SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
302SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
312SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
322SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
332SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
342SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
352SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
362SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
372SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
382SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392665Ssaidi@eecs.umich.edu *
402760Sbinkertn@umich.edu * Authors: Nathan Binkert
412760Sbinkertn@umich.edu *          Erik Hallnor
422665Ssaidi@eecs.umich.edu *          Steve Reinhardt
4310905Sandreas.sandberg@arm.com *          Andreas Sandberg
442SN/A */
452SN/A
462SN/A/* @file
472SN/A * Serialization Interface Declarations
482SN/A */
492SN/A
502SN/A#ifndef __SERIALIZE_HH__
512SN/A#define __SERIALIZE_HH__
522SN/A
532SN/A
5413107Sgiacomo.travaglini@arm.com#include <algorithm>
558229Snate@binkert.org#include <iostream>
562SN/A#include <list>
578229Snate@binkert.org#include <map>
5810905Sandreas.sandberg@arm.com#include <stack>
5911076SCurtis.Dunham@arm.com#include <set>
604841Ssaidi@eecs.umich.edu#include <vector>
612SN/A
6210459SAndreas.Sandberg@ARM.com#include "base/bitunion.hh"
6313414Sgiacomo.travaglini@arm.com#include "base/logging.hh"
6413414Sgiacomo.travaglini@arm.com#include "base/str.hh"
652SN/A
662738Sstever@eecs.umich.educlass IniFile;
674000Ssaidi@eecs.umich.educlass SimObject;
6811067Sandreas.sandberg@arm.comclass SimObjectResolver;
692SN/A
7010905Sandreas.sandberg@arm.comtypedef std::ostream CheckpointOut;
7110905Sandreas.sandberg@arm.com
7213414Sgiacomo.travaglini@arm.comclass CheckpointIn
7313414Sgiacomo.travaglini@arm.com{
7413414Sgiacomo.travaglini@arm.com  private:
7510905Sandreas.sandberg@arm.com
7613414Sgiacomo.travaglini@arm.com    IniFile *db;
77217SN/A
7813414Sgiacomo.travaglini@arm.com    SimObjectResolver &objNameResolver;
7910459SAndreas.Sandberg@ARM.com
8013414Sgiacomo.travaglini@arm.com  public:
8113414Sgiacomo.travaglini@arm.com    CheckpointIn(const std::string &cpt_dir, SimObjectResolver &resolver);
8213414Sgiacomo.travaglini@arm.com    ~CheckpointIn();
83217SN/A
8413414Sgiacomo.travaglini@arm.com    const std::string cptDir;
8510459SAndreas.Sandberg@ARM.com
8613414Sgiacomo.travaglini@arm.com    bool find(const std::string &section, const std::string &entry,
8713414Sgiacomo.travaglini@arm.com              std::string &value);
886820SLisa.Hsu@amd.com
8913414Sgiacomo.travaglini@arm.com    bool findObj(const std::string &section, const std::string &entry,
9013414Sgiacomo.travaglini@arm.com                 SimObject *&value);
9110459SAndreas.Sandberg@ARM.com
92217SN/A
9313414Sgiacomo.travaglini@arm.com    bool entryExists(const std::string &section, const std::string &entry);
9413414Sgiacomo.travaglini@arm.com    bool sectionExists(const std::string &section);
954841Ssaidi@eecs.umich.edu
9613414Sgiacomo.travaglini@arm.com    // The following static functions have to do with checkpoint
9713414Sgiacomo.travaglini@arm.com    // creation rather than restoration.  This class makes a handy
9813414Sgiacomo.travaglini@arm.com    // namespace for them though.  Currently no Checkpoint object is
9913414Sgiacomo.travaglini@arm.com    // created on serialization (only unserialization) so we track the
10013414Sgiacomo.travaglini@arm.com    // directory name as a global.  It would be nice to change this
10113414Sgiacomo.travaglini@arm.com    // someday
1027948SAli.Saidi@ARM.com
10313414Sgiacomo.travaglini@arm.com  private:
10413414Sgiacomo.travaglini@arm.com    // current directory we're serializing into.
10513414Sgiacomo.travaglini@arm.com    static std::string currentDirectory;
10611076SCurtis.Dunham@arm.com
10713414Sgiacomo.travaglini@arm.com  public:
10813414Sgiacomo.travaglini@arm.com    // Set the current directory.  This function takes care of
10913414Sgiacomo.travaglini@arm.com    // inserting curTick() if there's a '%d' in the argument, and
11013414Sgiacomo.travaglini@arm.com    // appends a '/' if necessary.  The final name is returned.
11113414Sgiacomo.travaglini@arm.com    static std::string setDir(const std::string &base_name);
112217SN/A
11313414Sgiacomo.travaglini@arm.com    // Export current checkpoint directory name so other objects can
11413414Sgiacomo.travaglini@arm.com    // derive filenames from it (e.g., memory).  The return value is
11513414Sgiacomo.travaglini@arm.com    // guaranteed to end in '/' so filenames can be directly appended.
11613414Sgiacomo.travaglini@arm.com    // This function is only valid while a checkpoint is being created.
11713414Sgiacomo.travaglini@arm.com    static std::string dir();
1184841Ssaidi@eecs.umich.edu
11913414Sgiacomo.travaglini@arm.com    // Filename for base checkpoint file within directory.
12013414Sgiacomo.travaglini@arm.com    static const char *baseFilename;
12113414Sgiacomo.travaglini@arm.com};
122217SN/A
1239342SAndreas.Sandberg@arm.com/**
1242SN/A * Basic support for object serialization.
1259342SAndreas.Sandberg@arm.com *
12610905Sandreas.sandberg@arm.com * Objects that support serialization should derive from this
12710905Sandreas.sandberg@arm.com * class. Such objects can largely be divided into two categories: 1)
12810905Sandreas.sandberg@arm.com * True SimObjects (deriving from SimObject), and 2) child objects
12910905Sandreas.sandberg@arm.com * (non-SimObjects).
13010905Sandreas.sandberg@arm.com *
13110905Sandreas.sandberg@arm.com * SimObjects are serialized automatically into their own sections
13210905Sandreas.sandberg@arm.com * automatically by the SimObject base class (see
13310905Sandreas.sandberg@arm.com * SimObject::serializeAll().
13410905Sandreas.sandberg@arm.com *
13510905Sandreas.sandberg@arm.com * SimObjects can contain other serializable objects that are not
13610905Sandreas.sandberg@arm.com * SimObjects. Much like normal serialized members are not serialized
13710905Sandreas.sandberg@arm.com * automatically, these objects will not be serialized automatically
13810905Sandreas.sandberg@arm.com * and it is expected that the objects owning such serializable
13910905Sandreas.sandberg@arm.com * objects call the required serialization/unserialization methods on
14010905Sandreas.sandberg@arm.com * child objects. The preferred method to serialize a child object is
14110905Sandreas.sandberg@arm.com * to call serializeSection() on the child, which serializes the
14210905Sandreas.sandberg@arm.com * object into a new subsection in the current section. Another option
14310905Sandreas.sandberg@arm.com * is to call serialize() directly, which serializes the object into
14410905Sandreas.sandberg@arm.com * the current section. The latter is not recommended as it can lead
14510905Sandreas.sandberg@arm.com * to naming clashes between objects.
14610905Sandreas.sandberg@arm.com *
1479342SAndreas.Sandberg@arm.com * @note Many objects that support serialization need to be put in a
1489342SAndreas.Sandberg@arm.com * consistent state when serialization takes place. We refer to the
1499342SAndreas.Sandberg@arm.com * action of forcing an object into a consistent state as
1509342SAndreas.Sandberg@arm.com * 'draining'. Objects that need draining inherit from Drainable. See
1519342SAndreas.Sandberg@arm.com * Drainable for more information.
1522SN/A */
153395SN/Aclass Serializable
1542SN/A{
1552SN/A  protected:
15610905Sandreas.sandberg@arm.com    /**
15710905Sandreas.sandberg@arm.com     * Scoped checkpoint section helper class
15810905Sandreas.sandberg@arm.com     *
15910905Sandreas.sandberg@arm.com     * This helper class creates a section within a checkpoint without
16010905Sandreas.sandberg@arm.com     * the need for a separate serializeable object. It is mainly used
16110905Sandreas.sandberg@arm.com     * within the Serializable class when serializing or unserializing
16210905Sandreas.sandberg@arm.com     * section (see serializeSection() and unserializeSection()). It
16310905Sandreas.sandberg@arm.com     * can also be used to maintain backwards compatibility in
16410905Sandreas.sandberg@arm.com     * existing code that serializes structs that are not inheriting
16510905Sandreas.sandberg@arm.com     * from Serializable into subsections.
16610905Sandreas.sandberg@arm.com     *
16710905Sandreas.sandberg@arm.com     * When the class is instantiated, it appends a name to the active
16810905Sandreas.sandberg@arm.com     * path in a checkpoint. The old path is later restored when the
16910905Sandreas.sandberg@arm.com     * instance is destroyed. For example, serializeSection() could be
17010905Sandreas.sandberg@arm.com     * implemented by instantiating a ScopedCheckpointSection and then
17110905Sandreas.sandberg@arm.com     * calling serialize() on an object.
17210905Sandreas.sandberg@arm.com     */
17310905Sandreas.sandberg@arm.com    class ScopedCheckpointSection {
17410905Sandreas.sandberg@arm.com      public:
17510905Sandreas.sandberg@arm.com        template<class CP>
17610905Sandreas.sandberg@arm.com        ScopedCheckpointSection(CP &cp, const char *name) {
17710905Sandreas.sandberg@arm.com            pushName(name);
17810905Sandreas.sandberg@arm.com            nameOut(cp);
17910905Sandreas.sandberg@arm.com        }
18010905Sandreas.sandberg@arm.com
18110905Sandreas.sandberg@arm.com        template<class CP>
18210905Sandreas.sandberg@arm.com        ScopedCheckpointSection(CP &cp, const std::string &name) {
18310905Sandreas.sandberg@arm.com            pushName(name.c_str());
18410905Sandreas.sandberg@arm.com            nameOut(cp);
18510905Sandreas.sandberg@arm.com        }
18610905Sandreas.sandberg@arm.com
18710905Sandreas.sandberg@arm.com        ~ScopedCheckpointSection();
18810905Sandreas.sandberg@arm.com
18910905Sandreas.sandberg@arm.com        ScopedCheckpointSection() = delete;
19010905Sandreas.sandberg@arm.com        ScopedCheckpointSection(const ScopedCheckpointSection &) = delete;
19110905Sandreas.sandberg@arm.com        ScopedCheckpointSection &operator=(
19210905Sandreas.sandberg@arm.com            const ScopedCheckpointSection &) = delete;
19310905Sandreas.sandberg@arm.com        ScopedCheckpointSection &operator=(
19410905Sandreas.sandberg@arm.com            ScopedCheckpointSection &&) = delete;
19510905Sandreas.sandberg@arm.com
19610905Sandreas.sandberg@arm.com      private:
19710905Sandreas.sandberg@arm.com        void pushName(const char *name);
19810905Sandreas.sandberg@arm.com        void nameOut(CheckpointOut &cp);
19910905Sandreas.sandberg@arm.com        void nameOut(CheckpointIn &cp) {};
20010905Sandreas.sandberg@arm.com    };
2012SN/A
2022SN/A  public:
2035739Snate@binkert.org    Serializable();
2045739Snate@binkert.org    virtual ~Serializable();
2052SN/A
20610905Sandreas.sandberg@arm.com    /**
20710905Sandreas.sandberg@arm.com     * Serialize an object
20810905Sandreas.sandberg@arm.com     *
20910905Sandreas.sandberg@arm.com     * Output an object's state into the current checkpoint section.
21010905Sandreas.sandberg@arm.com     *
21110905Sandreas.sandberg@arm.com     * @param cp Checkpoint state
21210905Sandreas.sandberg@arm.com     */
21310905Sandreas.sandberg@arm.com    virtual void serialize(CheckpointOut &cp) const = 0;
2142SN/A
21510905Sandreas.sandberg@arm.com    /**
21610905Sandreas.sandberg@arm.com     * Unserialize an object
21710905Sandreas.sandberg@arm.com     *
21810905Sandreas.sandberg@arm.com     * Read an object's state from the current checkpoint section.
21910905Sandreas.sandberg@arm.com     *
22010905Sandreas.sandberg@arm.com     * @param cp Checkpoint state
22110905Sandreas.sandberg@arm.com     */
22210905Sandreas.sandberg@arm.com    virtual void unserialize(CheckpointIn &cp) = 0;
223237SN/A
22410905Sandreas.sandberg@arm.com    /**
22510905Sandreas.sandberg@arm.com     * Serialize an object into a new section
22610905Sandreas.sandberg@arm.com     *
22710905Sandreas.sandberg@arm.com     * This method creates a new section in a checkpoint and calls
22810905Sandreas.sandberg@arm.com     * serialize() to serialize the current object into that
22910905Sandreas.sandberg@arm.com     * section. The name of the section is appended to the current
23010905Sandreas.sandberg@arm.com     * checkpoint path.
23110905Sandreas.sandberg@arm.com     *
23210905Sandreas.sandberg@arm.com     * @param cp Checkpoint state
23310905Sandreas.sandberg@arm.com     * @param name Name to append to the active path
23410905Sandreas.sandberg@arm.com     */
23510905Sandreas.sandberg@arm.com    void serializeSection(CheckpointOut &cp, const char *name) const;
23610905Sandreas.sandberg@arm.com
23710905Sandreas.sandberg@arm.com    void serializeSection(CheckpointOut &cp, const std::string &name) const {
23810905Sandreas.sandberg@arm.com        serializeSection(cp, name.c_str());
23910905Sandreas.sandberg@arm.com    }
24010905Sandreas.sandberg@arm.com
24110905Sandreas.sandberg@arm.com    /**
24210905Sandreas.sandberg@arm.com     * Unserialize an a child object
24310905Sandreas.sandberg@arm.com     *
24410905Sandreas.sandberg@arm.com     * This method loads a child object from a checkpoint. The object
24510905Sandreas.sandberg@arm.com     * name is appended to the active path to form a fully qualified
24610905Sandreas.sandberg@arm.com     * section name and unserialize() is called.
24710905Sandreas.sandberg@arm.com     *
24810905Sandreas.sandberg@arm.com     * @param cp Checkpoint state
24910905Sandreas.sandberg@arm.com     * @param name Name to append to the active path
25010905Sandreas.sandberg@arm.com     */
25110905Sandreas.sandberg@arm.com    void unserializeSection(CheckpointIn &cp, const char *name);
25210905Sandreas.sandberg@arm.com
25310905Sandreas.sandberg@arm.com    void unserializeSection(CheckpointIn &cp, const std::string &name) {
25410905Sandreas.sandberg@arm.com        unserializeSection(cp, name.c_str());
25510905Sandreas.sandberg@arm.com    }
25610905Sandreas.sandberg@arm.com
25710905Sandreas.sandberg@arm.com    /** Get the fully-qualified name of the active section */
25810905Sandreas.sandberg@arm.com    static const std::string &currentSection();
25910905Sandreas.sandberg@arm.com
2602287SN/A    static int ckptCount;
2612287SN/A    static int ckptMaxCount;
2622287SN/A    static int ckptPrevCount;
2632868Sktlim@umich.edu    static void serializeAll(const std::string &cpt_dir);
26410905Sandreas.sandberg@arm.com    static void unserializeGlobals(CheckpointIn &cp);
26510905Sandreas.sandberg@arm.com
26610905Sandreas.sandberg@arm.com  private:
26710905Sandreas.sandberg@arm.com    static std::stack<std::string> path;
2682SN/A};
2692SN/A
27013414Sgiacomo.travaglini@arm.com//
27113414Sgiacomo.travaglini@arm.com// The base implementations use to_number for parsing and '<<' for
27213414Sgiacomo.travaglini@arm.com// displaying, suitable for integer types.
27313414Sgiacomo.travaglini@arm.com//
27413414Sgiacomo.travaglini@arm.comtemplate <class T>
27513414Sgiacomo.travaglini@arm.combool
27613414Sgiacomo.travaglini@arm.comparseParam(const std::string &s, T &value)
27713414Sgiacomo.travaglini@arm.com{
27813414Sgiacomo.travaglini@arm.com    return to_number(s, value);
27913414Sgiacomo.travaglini@arm.com}
2809554Sandreas.hansson@arm.com
28113414Sgiacomo.travaglini@arm.comtemplate <class T>
28213414Sgiacomo.travaglini@arm.comvoid
28313414Sgiacomo.travaglini@arm.comshowParam(CheckpointOut &os, const T &value)
28413414Sgiacomo.travaglini@arm.com{
28513414Sgiacomo.travaglini@arm.com    os << value;
28613414Sgiacomo.travaglini@arm.com}
28710453SAndrew.Bardsley@arm.com
28813415Sgiacomo.travaglini@arm.comtemplate <class T>
28913415Sgiacomo.travaglini@arm.combool
29013415Sgiacomo.travaglini@arm.comparseParam(const std::string &s, BitUnionType<T> &value)
29113415Sgiacomo.travaglini@arm.com{
29213415Sgiacomo.travaglini@arm.com    auto storage = static_cast<BitUnionBaseType<T>>(value);
29313415Sgiacomo.travaglini@arm.com    auto res = to_number(s, storage);
29413415Sgiacomo.travaglini@arm.com    value = storage;
29513415Sgiacomo.travaglini@arm.com    return res;
29613415Sgiacomo.travaglini@arm.com}
29713415Sgiacomo.travaglini@arm.com
29813415Sgiacomo.travaglini@arm.comtemplate <class T>
29913415Sgiacomo.travaglini@arm.comvoid
30013415Sgiacomo.travaglini@arm.comshowParam(CheckpointOut &os, const BitUnionType<T> &value)
30113415Sgiacomo.travaglini@arm.com{
30213415Sgiacomo.travaglini@arm.com    auto storage = static_cast<BitUnionBaseType<T>>(value);
30313415Sgiacomo.travaglini@arm.com
30413415Sgiacomo.travaglini@arm.com    // For a BitUnion8, the storage type is an unsigned char.
30513415Sgiacomo.travaglini@arm.com    // Since we want to serialize a number we need to cast to
30613415Sgiacomo.travaglini@arm.com    // unsigned int
30713415Sgiacomo.travaglini@arm.com    os << ((sizeof(storage) == 1) ?
30813415Sgiacomo.travaglini@arm.com        static_cast<unsigned int>(storage) : storage);
30913415Sgiacomo.travaglini@arm.com}
31013415Sgiacomo.travaglini@arm.com
31113414Sgiacomo.travaglini@arm.com// Treat 8-bit ints (chars) as ints on output, not as chars
31213414Sgiacomo.travaglini@arm.comtemplate <>
31313414Sgiacomo.travaglini@arm.cominline void
31413414Sgiacomo.travaglini@arm.comshowParam(CheckpointOut &os, const char &value)
315237SN/A{
31613414Sgiacomo.travaglini@arm.com    os << (int)value;
31713414Sgiacomo.travaglini@arm.com}
318237SN/A
31913414Sgiacomo.travaglini@arm.comtemplate <>
32013414Sgiacomo.travaglini@arm.cominline void
32113414Sgiacomo.travaglini@arm.comshowParam(CheckpointOut &os, const signed char &value)
32213414Sgiacomo.travaglini@arm.com{
32313414Sgiacomo.travaglini@arm.com    os << (int)value;
32413414Sgiacomo.travaglini@arm.com}
325237SN/A
32613414Sgiacomo.travaglini@arm.comtemplate <>
32713414Sgiacomo.travaglini@arm.cominline void
32813414Sgiacomo.travaglini@arm.comshowParam(CheckpointOut &os, const unsigned char &value)
32913414Sgiacomo.travaglini@arm.com{
33013414Sgiacomo.travaglini@arm.com    os << (unsigned int)value;
33113414Sgiacomo.travaglini@arm.com}
33210453SAndrew.Bardsley@arm.com
33313414Sgiacomo.travaglini@arm.comtemplate <>
33413414Sgiacomo.travaglini@arm.cominline bool
33513414Sgiacomo.travaglini@arm.comparseParam(const std::string &s, float &value)
33613414Sgiacomo.travaglini@arm.com{
33713414Sgiacomo.travaglini@arm.com    return to_number(s, value);
33813414Sgiacomo.travaglini@arm.com}
339237SN/A
34013414Sgiacomo.travaglini@arm.comtemplate <>
34113414Sgiacomo.travaglini@arm.cominline bool
34213414Sgiacomo.travaglini@arm.comparseParam(const std::string &s, double &value)
34313414Sgiacomo.travaglini@arm.com{
34413414Sgiacomo.travaglini@arm.com    return to_number(s, value);
34513414Sgiacomo.travaglini@arm.com}
346937SN/A
34713414Sgiacomo.travaglini@arm.comtemplate <>
34813414Sgiacomo.travaglini@arm.cominline bool
34913414Sgiacomo.travaglini@arm.comparseParam(const std::string &s, bool &value)
35013414Sgiacomo.travaglini@arm.com{
35113414Sgiacomo.travaglini@arm.com    return to_bool(s, value);
35213414Sgiacomo.travaglini@arm.com}
353237SN/A
35413414Sgiacomo.travaglini@arm.com// Display bools as strings
35513414Sgiacomo.travaglini@arm.comtemplate <>
35613414Sgiacomo.travaglini@arm.cominline void
35713414Sgiacomo.travaglini@arm.comshowParam(CheckpointOut &os, const bool &value)
35813414Sgiacomo.travaglini@arm.com{
35913414Sgiacomo.travaglini@arm.com    os << (value ? "true" : "false");
36013414Sgiacomo.travaglini@arm.com}
361304SN/A
36213414Sgiacomo.travaglini@arm.com// String requires no processing to speak of
36313414Sgiacomo.travaglini@arm.comtemplate <>
36413414Sgiacomo.travaglini@arm.cominline bool
36513414Sgiacomo.travaglini@arm.comparseParam(const std::string &s, std::string &value)
36613414Sgiacomo.travaglini@arm.com{
36713414Sgiacomo.travaglini@arm.com    value = s;
36813414Sgiacomo.travaglini@arm.com    return true;
36913414Sgiacomo.travaglini@arm.com}
37011655Sandreas.sandberg@arm.com
37113414Sgiacomo.travaglini@arm.comtemplate <class T>
37213414Sgiacomo.travaglini@arm.comvoid
37313414Sgiacomo.travaglini@arm.comparamOut(CheckpointOut &os, const std::string &name, const T &param)
37413414Sgiacomo.travaglini@arm.com{
37513414Sgiacomo.travaglini@arm.com    os << name << "=";
37613414Sgiacomo.travaglini@arm.com    showParam(os, param);
37713414Sgiacomo.travaglini@arm.com    os << "\n";
37813414Sgiacomo.travaglini@arm.com}
379449SN/A
38013414Sgiacomo.travaglini@arm.comtemplate <class T>
38113414Sgiacomo.travaglini@arm.comvoid
38213414Sgiacomo.travaglini@arm.comparamIn(CheckpointIn &cp, const std::string &name, T &param)
38313414Sgiacomo.travaglini@arm.com{
38413414Sgiacomo.travaglini@arm.com    const std::string &section(Serializable::currentSection());
38513414Sgiacomo.travaglini@arm.com    std::string str;
38613414Sgiacomo.travaglini@arm.com    if (!cp.find(section, name, str) || !parseParam(str, param)) {
38713414Sgiacomo.travaglini@arm.com        fatal("Can't unserialize '%s:%s'\n", section, name);
38813414Sgiacomo.travaglini@arm.com    }
38913414Sgiacomo.travaglini@arm.com}
3907491Ssteve.reinhardt@amd.com
39113414Sgiacomo.travaglini@arm.comtemplate <class T>
39213414Sgiacomo.travaglini@arm.combool
39313414Sgiacomo.travaglini@arm.comoptParamIn(CheckpointIn &cp, const std::string &name,
39413414Sgiacomo.travaglini@arm.com           T &param, bool warn = true)
39513414Sgiacomo.travaglini@arm.com{
39613414Sgiacomo.travaglini@arm.com    const std::string &section(Serializable::currentSection());
39713414Sgiacomo.travaglini@arm.com    std::string str;
39813414Sgiacomo.travaglini@arm.com    if (!cp.find(section, name, str) || !parseParam(str, param)) {
39913414Sgiacomo.travaglini@arm.com        if (warn)
40013414Sgiacomo.travaglini@arm.com            warn("optional parameter %s:%s not present\n", section, name);
40113414Sgiacomo.travaglini@arm.com        return false;
40213414Sgiacomo.travaglini@arm.com    } else {
40313414Sgiacomo.travaglini@arm.com        return true;
40413414Sgiacomo.travaglini@arm.com    }
40513414Sgiacomo.travaglini@arm.com}
406449SN/A
40713414Sgiacomo.travaglini@arm.comtemplate <class T>
40813414Sgiacomo.travaglini@arm.comvoid
40913414Sgiacomo.travaglini@arm.comarrayParamOut(CheckpointOut &os, const std::string &name,
41013414Sgiacomo.travaglini@arm.com              const std::vector<T> &param)
41113414Sgiacomo.travaglini@arm.com{
41213414Sgiacomo.travaglini@arm.com    typename std::vector<T>::size_type size = param.size();
41313414Sgiacomo.travaglini@arm.com    os << name << "=";
41413414Sgiacomo.travaglini@arm.com    if (size > 0)
41513414Sgiacomo.travaglini@arm.com        showParam(os, param[0]);
41613414Sgiacomo.travaglini@arm.com    for (typename std::vector<T>::size_type i = 1; i < size; ++i) {
41713414Sgiacomo.travaglini@arm.com        os << " ";
41813414Sgiacomo.travaglini@arm.com        showParam(os, param[i]);
41913414Sgiacomo.travaglini@arm.com    }
42013414Sgiacomo.travaglini@arm.com    os << "\n";
42113414Sgiacomo.travaglini@arm.com}
42213414Sgiacomo.travaglini@arm.com
42313414Sgiacomo.travaglini@arm.comtemplate <class T>
42413414Sgiacomo.travaglini@arm.comvoid
42513414Sgiacomo.travaglini@arm.comarrayParamOut(CheckpointOut &os, const std::string &name,
42613414Sgiacomo.travaglini@arm.com              const std::list<T> &param)
42713414Sgiacomo.travaglini@arm.com{
42813414Sgiacomo.travaglini@arm.com    typename std::list<T>::const_iterator it = param.begin();
42913414Sgiacomo.travaglini@arm.com
43013414Sgiacomo.travaglini@arm.com    os << name << "=";
43113414Sgiacomo.travaglini@arm.com    if (param.size() > 0)
43213414Sgiacomo.travaglini@arm.com        showParam(os, *it);
43313414Sgiacomo.travaglini@arm.com    it++;
43413414Sgiacomo.travaglini@arm.com    while (it != param.end()) {
43513414Sgiacomo.travaglini@arm.com        os << " ";
43613414Sgiacomo.travaglini@arm.com        showParam(os, *it);
43713414Sgiacomo.travaglini@arm.com        it++;
43813414Sgiacomo.travaglini@arm.com    }
43913414Sgiacomo.travaglini@arm.com    os << "\n";
44013414Sgiacomo.travaglini@arm.com}
44113414Sgiacomo.travaglini@arm.com
44213414Sgiacomo.travaglini@arm.comtemplate <class T>
44313414Sgiacomo.travaglini@arm.comvoid
44413414Sgiacomo.travaglini@arm.comarrayParamOut(CheckpointOut &os, const std::string &name,
44513414Sgiacomo.travaglini@arm.com              const std::set<T> &param)
44613414Sgiacomo.travaglini@arm.com{
44713414Sgiacomo.travaglini@arm.com    typename std::set<T>::const_iterator it = param.begin();
44813414Sgiacomo.travaglini@arm.com
44913414Sgiacomo.travaglini@arm.com    os << name << "=";
45013414Sgiacomo.travaglini@arm.com    if (param.size() > 0)
45113414Sgiacomo.travaglini@arm.com        showParam(os, *it);
45213414Sgiacomo.travaglini@arm.com    it++;
45313414Sgiacomo.travaglini@arm.com    while (it != param.end()) {
45413414Sgiacomo.travaglini@arm.com        os << " ";
45513414Sgiacomo.travaglini@arm.com        showParam(os, *it);
45613414Sgiacomo.travaglini@arm.com        it++;
45713414Sgiacomo.travaglini@arm.com    }
45813414Sgiacomo.travaglini@arm.com    os << "\n";
45913414Sgiacomo.travaglini@arm.com}
46013414Sgiacomo.travaglini@arm.com
46113414Sgiacomo.travaglini@arm.comtemplate <class T>
46213414Sgiacomo.travaglini@arm.comvoid
46313414Sgiacomo.travaglini@arm.comarrayParamOut(CheckpointOut &os, const std::string &name,
46413414Sgiacomo.travaglini@arm.com              const T *param, unsigned size)
46513414Sgiacomo.travaglini@arm.com{
46613414Sgiacomo.travaglini@arm.com    os << name << "=";
46713414Sgiacomo.travaglini@arm.com    if (size > 0)
46813414Sgiacomo.travaglini@arm.com        showParam(os, param[0]);
46913414Sgiacomo.travaglini@arm.com    for (unsigned i = 1; i < size; ++i) {
47013414Sgiacomo.travaglini@arm.com        os << " ";
47113414Sgiacomo.travaglini@arm.com        showParam(os, param[i]);
47213414Sgiacomo.travaglini@arm.com    }
47313414Sgiacomo.travaglini@arm.com    os << "\n";
47413414Sgiacomo.travaglini@arm.com}
47513414Sgiacomo.travaglini@arm.com
47613414Sgiacomo.travaglini@arm.com
47713414Sgiacomo.travaglini@arm.comtemplate <class T>
47813414Sgiacomo.travaglini@arm.comvoid
47913414Sgiacomo.travaglini@arm.comarrayParamIn(CheckpointIn &cp, const std::string &name,
48013414Sgiacomo.travaglini@arm.com             T *param, unsigned size)
48113414Sgiacomo.travaglini@arm.com{
48213414Sgiacomo.travaglini@arm.com    const std::string &section(Serializable::currentSection());
48313414Sgiacomo.travaglini@arm.com    std::string str;
48413414Sgiacomo.travaglini@arm.com    if (!cp.find(section, name, str)) {
48513414Sgiacomo.travaglini@arm.com        fatal("Can't unserialize '%s:%s'\n", section, name);
48613414Sgiacomo.travaglini@arm.com    }
48713414Sgiacomo.travaglini@arm.com
48813414Sgiacomo.travaglini@arm.com    // code below stolen from VectorParam<T>::parse().
48913414Sgiacomo.travaglini@arm.com    // it would be nice to unify these somehow...
49013414Sgiacomo.travaglini@arm.com
49113414Sgiacomo.travaglini@arm.com    std::vector<std::string> tokens;
49213414Sgiacomo.travaglini@arm.com
49313414Sgiacomo.travaglini@arm.com    tokenize(tokens, str, ' ');
49413414Sgiacomo.travaglini@arm.com
49513414Sgiacomo.travaglini@arm.com    // Need this if we were doing a vector
49613414Sgiacomo.travaglini@arm.com    // value.resize(tokens.size());
49713414Sgiacomo.travaglini@arm.com
49813414Sgiacomo.travaglini@arm.com    if (tokens.size() != size) {
49913414Sgiacomo.travaglini@arm.com        fatal("Array size mismatch on %s:%s'\n", section, name);
50013414Sgiacomo.travaglini@arm.com    }
50113414Sgiacomo.travaglini@arm.com
50213414Sgiacomo.travaglini@arm.com    for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) {
50313414Sgiacomo.travaglini@arm.com        // need to parse into local variable to handle vector<bool>,
50413414Sgiacomo.travaglini@arm.com        // for which operator[] returns a special reference class
50513414Sgiacomo.travaglini@arm.com        // that's not the same as 'bool&', (since it's a packed
50613414Sgiacomo.travaglini@arm.com        // vector)
50713414Sgiacomo.travaglini@arm.com        T scalar_value;
50813414Sgiacomo.travaglini@arm.com        if (!parseParam(tokens[i], scalar_value)) {
50913414Sgiacomo.travaglini@arm.com            std::string err("could not parse \"");
51013414Sgiacomo.travaglini@arm.com
51113414Sgiacomo.travaglini@arm.com            err += str;
51213414Sgiacomo.travaglini@arm.com            err += "\"";
51313414Sgiacomo.travaglini@arm.com
51413414Sgiacomo.travaglini@arm.com            fatal(err);
51513414Sgiacomo.travaglini@arm.com        }
51613414Sgiacomo.travaglini@arm.com
51713414Sgiacomo.travaglini@arm.com        // assign parsed value to vector
51813414Sgiacomo.travaglini@arm.com        param[i] = scalar_value;
51913414Sgiacomo.travaglini@arm.com    }
52013414Sgiacomo.travaglini@arm.com}
52113414Sgiacomo.travaglini@arm.com
52213414Sgiacomo.travaglini@arm.comtemplate <class T>
52313414Sgiacomo.travaglini@arm.comvoid
52413414Sgiacomo.travaglini@arm.comarrayParamIn(CheckpointIn &cp, const std::string &name, std::vector<T> &param)
52513414Sgiacomo.travaglini@arm.com{
52613414Sgiacomo.travaglini@arm.com    const std::string &section(Serializable::currentSection());
52713414Sgiacomo.travaglini@arm.com    std::string str;
52813414Sgiacomo.travaglini@arm.com    if (!cp.find(section, name, str)) {
52913414Sgiacomo.travaglini@arm.com        fatal("Can't unserialize '%s:%s'\n", section, name);
53013414Sgiacomo.travaglini@arm.com    }
53113414Sgiacomo.travaglini@arm.com
53213414Sgiacomo.travaglini@arm.com    // code below stolen from VectorParam<T>::parse().
53313414Sgiacomo.travaglini@arm.com    // it would be nice to unify these somehow...
53413414Sgiacomo.travaglini@arm.com
53513414Sgiacomo.travaglini@arm.com    std::vector<std::string> tokens;
53613414Sgiacomo.travaglini@arm.com
53713414Sgiacomo.travaglini@arm.com    tokenize(tokens, str, ' ');
53813414Sgiacomo.travaglini@arm.com
53913414Sgiacomo.travaglini@arm.com    // Need this if we were doing a vector
54013414Sgiacomo.travaglini@arm.com    // value.resize(tokens.size());
54113414Sgiacomo.travaglini@arm.com
54213414Sgiacomo.travaglini@arm.com    param.resize(tokens.size());
54313414Sgiacomo.travaglini@arm.com
54413414Sgiacomo.travaglini@arm.com    for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) {
54513414Sgiacomo.travaglini@arm.com        // need to parse into local variable to handle vector<bool>,
54613414Sgiacomo.travaglini@arm.com        // for which operator[] returns a special reference class
54713414Sgiacomo.travaglini@arm.com        // that's not the same as 'bool&', (since it's a packed
54813414Sgiacomo.travaglini@arm.com        // vector)
54913414Sgiacomo.travaglini@arm.com        T scalar_value;
55013414Sgiacomo.travaglini@arm.com        if (!parseParam(tokens[i], scalar_value)) {
55113414Sgiacomo.travaglini@arm.com            std::string err("could not parse \"");
55213414Sgiacomo.travaglini@arm.com
55313414Sgiacomo.travaglini@arm.com            err += str;
55413414Sgiacomo.travaglini@arm.com            err += "\"";
55513414Sgiacomo.travaglini@arm.com
55613414Sgiacomo.travaglini@arm.com            fatal(err);
55713414Sgiacomo.travaglini@arm.com        }
55813414Sgiacomo.travaglini@arm.com
55913414Sgiacomo.travaglini@arm.com        // assign parsed value to vector
56013414Sgiacomo.travaglini@arm.com        param[i] = scalar_value;
56113414Sgiacomo.travaglini@arm.com    }
56213414Sgiacomo.travaglini@arm.com}
56313414Sgiacomo.travaglini@arm.com
56413414Sgiacomo.travaglini@arm.comtemplate <class T>
56513414Sgiacomo.travaglini@arm.comvoid
56613414Sgiacomo.travaglini@arm.comarrayParamIn(CheckpointIn &cp, const std::string &name, std::list<T> &param)
56713414Sgiacomo.travaglini@arm.com{
56813414Sgiacomo.travaglini@arm.com    const std::string &section(Serializable::currentSection());
56913414Sgiacomo.travaglini@arm.com    std::string str;
57013414Sgiacomo.travaglini@arm.com    if (!cp.find(section, name, str)) {
57113414Sgiacomo.travaglini@arm.com        fatal("Can't unserialize '%s:%s'\n", section, name);
57213414Sgiacomo.travaglini@arm.com    }
57313414Sgiacomo.travaglini@arm.com    param.clear();
57413414Sgiacomo.travaglini@arm.com
57513414Sgiacomo.travaglini@arm.com    std::vector<std::string> tokens;
57613414Sgiacomo.travaglini@arm.com    tokenize(tokens, str, ' ');
57713414Sgiacomo.travaglini@arm.com
57813414Sgiacomo.travaglini@arm.com    for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) {
57913414Sgiacomo.travaglini@arm.com        T scalar_value;
58013414Sgiacomo.travaglini@arm.com        if (!parseParam(tokens[i], scalar_value)) {
58113414Sgiacomo.travaglini@arm.com            std::string err("could not parse \"");
58213414Sgiacomo.travaglini@arm.com
58313414Sgiacomo.travaglini@arm.com            err += str;
58413414Sgiacomo.travaglini@arm.com            err += "\"";
58513414Sgiacomo.travaglini@arm.com
58613414Sgiacomo.travaglini@arm.com            fatal(err);
58713414Sgiacomo.travaglini@arm.com        }
58813414Sgiacomo.travaglini@arm.com
58913414Sgiacomo.travaglini@arm.com        // assign parsed value to vector
59013414Sgiacomo.travaglini@arm.com        param.push_back(scalar_value);
59113414Sgiacomo.travaglini@arm.com    }
59213414Sgiacomo.travaglini@arm.com}
59313414Sgiacomo.travaglini@arm.com
59413414Sgiacomo.travaglini@arm.comtemplate <class T>
59513414Sgiacomo.travaglini@arm.comvoid
59613414Sgiacomo.travaglini@arm.comarrayParamIn(CheckpointIn &cp, const std::string &name, std::set<T> &param)
59713414Sgiacomo.travaglini@arm.com{
59813414Sgiacomo.travaglini@arm.com    const std::string &section(Serializable::currentSection());
59913414Sgiacomo.travaglini@arm.com    std::string str;
60013414Sgiacomo.travaglini@arm.com    if (!cp.find(section, name, str)) {
60113414Sgiacomo.travaglini@arm.com        fatal("Can't unserialize '%s:%s'\n", section, name);
60213414Sgiacomo.travaglini@arm.com    }
60313414Sgiacomo.travaglini@arm.com    param.clear();
60413414Sgiacomo.travaglini@arm.com
60513414Sgiacomo.travaglini@arm.com    std::vector<std::string> tokens;
60613414Sgiacomo.travaglini@arm.com    tokenize(tokens, str, ' ');
60713414Sgiacomo.travaglini@arm.com
60813414Sgiacomo.travaglini@arm.com    for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) {
60913414Sgiacomo.travaglini@arm.com        T scalar_value;
61013414Sgiacomo.travaglini@arm.com        if (!parseParam(tokens[i], scalar_value)) {
61113414Sgiacomo.travaglini@arm.com            std::string err("could not parse \"");
61213414Sgiacomo.travaglini@arm.com
61313414Sgiacomo.travaglini@arm.com            err += str;
61413414Sgiacomo.travaglini@arm.com            err += "\"";
61513414Sgiacomo.travaglini@arm.com
61613414Sgiacomo.travaglini@arm.com            fatal(err);
61713414Sgiacomo.travaglini@arm.com        }
61813414Sgiacomo.travaglini@arm.com
61913414Sgiacomo.travaglini@arm.com        // assign parsed value to vector
62013414Sgiacomo.travaglini@arm.com        param.insert(scalar_value);
62113414Sgiacomo.travaglini@arm.com    }
62213414Sgiacomo.travaglini@arm.com}
62313414Sgiacomo.travaglini@arm.com
62413414Sgiacomo.travaglini@arm.comvoid
62513414Sgiacomo.travaglini@arm.comdebug_serialize(const std::string &cpt_dir);
62613414Sgiacomo.travaglini@arm.com
62713414Sgiacomo.travaglini@arm.comvoid
62813414Sgiacomo.travaglini@arm.comobjParamIn(CheckpointIn &cp, const std::string &name, SimObject * &param);
62913414Sgiacomo.travaglini@arm.com
63013414Sgiacomo.travaglini@arm.com//
63113414Sgiacomo.travaglini@arm.com// These macros are streamlined to use in serialize/unserialize
63213414Sgiacomo.travaglini@arm.com// functions.  It's assumed that serialize() has a parameter 'os' for
63313414Sgiacomo.travaglini@arm.com// the ostream, and unserialize() has parameters 'cp' and 'section'.
63413414Sgiacomo.travaglini@arm.com#define SERIALIZE_SCALAR(scalar)        paramOut(cp, #scalar, scalar)
63513414Sgiacomo.travaglini@arm.com
63613414Sgiacomo.travaglini@arm.com#define UNSERIALIZE_SCALAR(scalar)      paramIn(cp, #scalar, scalar)
63713414Sgiacomo.travaglini@arm.com#define UNSERIALIZE_OPT_SCALAR(scalar)      optParamIn(cp, #scalar, scalar)
63813414Sgiacomo.travaglini@arm.com
63913414Sgiacomo.travaglini@arm.com// ENUMs are like SCALARs, but we cast them to ints on the way out
64013414Sgiacomo.travaglini@arm.com#define SERIALIZE_ENUM(scalar)          paramOut(cp, #scalar, (int)scalar)
64113414Sgiacomo.travaglini@arm.com
64213414Sgiacomo.travaglini@arm.com#define UNSERIALIZE_ENUM(scalar)                        \
64313414Sgiacomo.travaglini@arm.com    do {                                                \
64413414Sgiacomo.travaglini@arm.com        int tmp;                                        \
64513414Sgiacomo.travaglini@arm.com        paramIn(cp, #scalar, tmp);                      \
64613414Sgiacomo.travaglini@arm.com        scalar = static_cast<decltype(scalar)>(tmp);    \
64713414Sgiacomo.travaglini@arm.com    } while (0)
64813414Sgiacomo.travaglini@arm.com
64913414Sgiacomo.travaglini@arm.com#define SERIALIZE_ARRAY(member, size)           \
65013414Sgiacomo.travaglini@arm.com        arrayParamOut(cp, #member, member, size)
65113414Sgiacomo.travaglini@arm.com
65213414Sgiacomo.travaglini@arm.com#define UNSERIALIZE_ARRAY(member, size)         \
65313414Sgiacomo.travaglini@arm.com        arrayParamIn(cp, #member, member, size)
65413414Sgiacomo.travaglini@arm.com
65513414Sgiacomo.travaglini@arm.com#define SERIALIZE_CONTAINER(member)             \
65613414Sgiacomo.travaglini@arm.com        arrayParamOut(cp, #member, member)
65713414Sgiacomo.travaglini@arm.com
65813414Sgiacomo.travaglini@arm.com#define UNSERIALIZE_CONTAINER(member)           \
65913414Sgiacomo.travaglini@arm.com        arrayParamIn(cp, #member, member)
66013414Sgiacomo.travaglini@arm.com
66113414Sgiacomo.travaglini@arm.com#define SERIALIZE_EVENT(event) event.serializeSection(cp, #event);
66213414Sgiacomo.travaglini@arm.com
66313414Sgiacomo.travaglini@arm.com#define UNSERIALIZE_EVENT(event)                        \
66413414Sgiacomo.travaglini@arm.com    do {                                                \
66513414Sgiacomo.travaglini@arm.com        event.unserializeSection(cp, #event);           \
66613414Sgiacomo.travaglini@arm.com        eventQueue()->checkpointReschedule(&event);     \
66713414Sgiacomo.travaglini@arm.com    } while (0)
66813414Sgiacomo.travaglini@arm.com
66913414Sgiacomo.travaglini@arm.com#define SERIALIZE_OBJ(obj) obj.serializeSection(cp, #obj)
67013414Sgiacomo.travaglini@arm.com#define UNSERIALIZE_OBJ(obj) obj.unserializeSection(cp, #obj)
67113414Sgiacomo.travaglini@arm.com
67213414Sgiacomo.travaglini@arm.com#define SERIALIZE_OBJPTR(objptr)        paramOut(cp, #objptr, (objptr)->name())
67313414Sgiacomo.travaglini@arm.com
67413414Sgiacomo.travaglini@arm.com#define UNSERIALIZE_OBJPTR(objptr)                      \
67513414Sgiacomo.travaglini@arm.com    do {                                                \
67613414Sgiacomo.travaglini@arm.com        SimObject *sptr;                                \
67713414Sgiacomo.travaglini@arm.com        objParamIn(cp, #objptr, sptr);                  \
67813414Sgiacomo.travaglini@arm.com        objptr = dynamic_cast<decltype(objptr)>(sptr);  \
67913414Sgiacomo.travaglini@arm.com    } while (0)
6802SN/A
6812SN/A#endif // __SERIALIZE_HH__
682