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{
29213567Sodanrc@yahoo.com.br    // Zero initialize storage to avoid leaking an uninitialized value
29313567Sodanrc@yahoo.com.br    BitUnionBaseType<T> storage = BitUnionBaseType<T>();
29413415Sgiacomo.travaglini@arm.com    auto res = to_number(s, storage);
29513415Sgiacomo.travaglini@arm.com    value = storage;
29613415Sgiacomo.travaglini@arm.com    return res;
29713415Sgiacomo.travaglini@arm.com}
29813415Sgiacomo.travaglini@arm.com
29913415Sgiacomo.travaglini@arm.comtemplate <class T>
30013415Sgiacomo.travaglini@arm.comvoid
30113415Sgiacomo.travaglini@arm.comshowParam(CheckpointOut &os, const BitUnionType<T> &value)
30213415Sgiacomo.travaglini@arm.com{
30313415Sgiacomo.travaglini@arm.com    auto storage = static_cast<BitUnionBaseType<T>>(value);
30413415Sgiacomo.travaglini@arm.com
30513415Sgiacomo.travaglini@arm.com    // For a BitUnion8, the storage type is an unsigned char.
30613415Sgiacomo.travaglini@arm.com    // Since we want to serialize a number we need to cast to
30713415Sgiacomo.travaglini@arm.com    // unsigned int
30813415Sgiacomo.travaglini@arm.com    os << ((sizeof(storage) == 1) ?
30913415Sgiacomo.travaglini@arm.com        static_cast<unsigned int>(storage) : storage);
31013415Sgiacomo.travaglini@arm.com}
31113415Sgiacomo.travaglini@arm.com
31213414Sgiacomo.travaglini@arm.com// Treat 8-bit ints (chars) as ints on output, not as chars
31313414Sgiacomo.travaglini@arm.comtemplate <>
31413414Sgiacomo.travaglini@arm.cominline void
31513414Sgiacomo.travaglini@arm.comshowParam(CheckpointOut &os, const char &value)
316237SN/A{
31713414Sgiacomo.travaglini@arm.com    os << (int)value;
31813414Sgiacomo.travaglini@arm.com}
319237SN/A
32013414Sgiacomo.travaglini@arm.comtemplate <>
32113414Sgiacomo.travaglini@arm.cominline void
32213414Sgiacomo.travaglini@arm.comshowParam(CheckpointOut &os, const signed char &value)
32313414Sgiacomo.travaglini@arm.com{
32413414Sgiacomo.travaglini@arm.com    os << (int)value;
32513414Sgiacomo.travaglini@arm.com}
326237SN/A
32713414Sgiacomo.travaglini@arm.comtemplate <>
32813414Sgiacomo.travaglini@arm.cominline void
32913414Sgiacomo.travaglini@arm.comshowParam(CheckpointOut &os, const unsigned char &value)
33013414Sgiacomo.travaglini@arm.com{
33113414Sgiacomo.travaglini@arm.com    os << (unsigned int)value;
33213414Sgiacomo.travaglini@arm.com}
33310453SAndrew.Bardsley@arm.com
33413414Sgiacomo.travaglini@arm.comtemplate <>
33513414Sgiacomo.travaglini@arm.cominline bool
33613414Sgiacomo.travaglini@arm.comparseParam(const std::string &s, float &value)
33713414Sgiacomo.travaglini@arm.com{
33813414Sgiacomo.travaglini@arm.com    return to_number(s, value);
33913414Sgiacomo.travaglini@arm.com}
340237SN/A
34113414Sgiacomo.travaglini@arm.comtemplate <>
34213414Sgiacomo.travaglini@arm.cominline bool
34313414Sgiacomo.travaglini@arm.comparseParam(const std::string &s, double &value)
34413414Sgiacomo.travaglini@arm.com{
34513414Sgiacomo.travaglini@arm.com    return to_number(s, value);
34613414Sgiacomo.travaglini@arm.com}
347937SN/A
34813414Sgiacomo.travaglini@arm.comtemplate <>
34913414Sgiacomo.travaglini@arm.cominline bool
35013414Sgiacomo.travaglini@arm.comparseParam(const std::string &s, bool &value)
35113414Sgiacomo.travaglini@arm.com{
35213414Sgiacomo.travaglini@arm.com    return to_bool(s, value);
35313414Sgiacomo.travaglini@arm.com}
354237SN/A
35513414Sgiacomo.travaglini@arm.com// Display bools as strings
35613414Sgiacomo.travaglini@arm.comtemplate <>
35713414Sgiacomo.travaglini@arm.cominline void
35813414Sgiacomo.travaglini@arm.comshowParam(CheckpointOut &os, const bool &value)
35913414Sgiacomo.travaglini@arm.com{
36013414Sgiacomo.travaglini@arm.com    os << (value ? "true" : "false");
36113414Sgiacomo.travaglini@arm.com}
362304SN/A
36313414Sgiacomo.travaglini@arm.com// String requires no processing to speak of
36413414Sgiacomo.travaglini@arm.comtemplate <>
36513414Sgiacomo.travaglini@arm.cominline bool
36613414Sgiacomo.travaglini@arm.comparseParam(const std::string &s, std::string &value)
36713414Sgiacomo.travaglini@arm.com{
36813414Sgiacomo.travaglini@arm.com    value = s;
36913414Sgiacomo.travaglini@arm.com    return true;
37013414Sgiacomo.travaglini@arm.com}
37111655Sandreas.sandberg@arm.com
37213414Sgiacomo.travaglini@arm.comtemplate <class T>
37313414Sgiacomo.travaglini@arm.comvoid
37413414Sgiacomo.travaglini@arm.comparamOut(CheckpointOut &os, const std::string &name, const T &param)
37513414Sgiacomo.travaglini@arm.com{
37613414Sgiacomo.travaglini@arm.com    os << name << "=";
37713414Sgiacomo.travaglini@arm.com    showParam(os, param);
37813414Sgiacomo.travaglini@arm.com    os << "\n";
37913414Sgiacomo.travaglini@arm.com}
380449SN/A
38113414Sgiacomo.travaglini@arm.comtemplate <class T>
38213414Sgiacomo.travaglini@arm.comvoid
38313414Sgiacomo.travaglini@arm.comparamIn(CheckpointIn &cp, const std::string &name, T &param)
38413414Sgiacomo.travaglini@arm.com{
38513414Sgiacomo.travaglini@arm.com    const std::string &section(Serializable::currentSection());
38613414Sgiacomo.travaglini@arm.com    std::string str;
38713414Sgiacomo.travaglini@arm.com    if (!cp.find(section, name, str) || !parseParam(str, param)) {
38813414Sgiacomo.travaglini@arm.com        fatal("Can't unserialize '%s:%s'\n", section, name);
38913414Sgiacomo.travaglini@arm.com    }
39013414Sgiacomo.travaglini@arm.com}
3917491Ssteve.reinhardt@amd.com
39213414Sgiacomo.travaglini@arm.comtemplate <class T>
39313414Sgiacomo.travaglini@arm.combool
39413414Sgiacomo.travaglini@arm.comoptParamIn(CheckpointIn &cp, const std::string &name,
39513414Sgiacomo.travaglini@arm.com           T &param, bool warn = true)
39613414Sgiacomo.travaglini@arm.com{
39713414Sgiacomo.travaglini@arm.com    const std::string &section(Serializable::currentSection());
39813414Sgiacomo.travaglini@arm.com    std::string str;
39913414Sgiacomo.travaglini@arm.com    if (!cp.find(section, name, str) || !parseParam(str, param)) {
40013414Sgiacomo.travaglini@arm.com        if (warn)
40113414Sgiacomo.travaglini@arm.com            warn("optional parameter %s:%s not present\n", section, name);
40213414Sgiacomo.travaglini@arm.com        return false;
40313414Sgiacomo.travaglini@arm.com    } else {
40413414Sgiacomo.travaglini@arm.com        return true;
40513414Sgiacomo.travaglini@arm.com    }
40613414Sgiacomo.travaglini@arm.com}
407449SN/A
40813414Sgiacomo.travaglini@arm.comtemplate <class T>
40913414Sgiacomo.travaglini@arm.comvoid
41013414Sgiacomo.travaglini@arm.comarrayParamOut(CheckpointOut &os, const std::string &name,
41113414Sgiacomo.travaglini@arm.com              const std::vector<T> &param)
41213414Sgiacomo.travaglini@arm.com{
41313414Sgiacomo.travaglini@arm.com    typename std::vector<T>::size_type size = param.size();
41413414Sgiacomo.travaglini@arm.com    os << name << "=";
41513414Sgiacomo.travaglini@arm.com    if (size > 0)
41613414Sgiacomo.travaglini@arm.com        showParam(os, param[0]);
41713414Sgiacomo.travaglini@arm.com    for (typename std::vector<T>::size_type i = 1; i < size; ++i) {
41813414Sgiacomo.travaglini@arm.com        os << " ";
41913414Sgiacomo.travaglini@arm.com        showParam(os, param[i]);
42013414Sgiacomo.travaglini@arm.com    }
42113414Sgiacomo.travaglini@arm.com    os << "\n";
42213414Sgiacomo.travaglini@arm.com}
42313414Sgiacomo.travaglini@arm.com
42413414Sgiacomo.travaglini@arm.comtemplate <class T>
42513414Sgiacomo.travaglini@arm.comvoid
42613414Sgiacomo.travaglini@arm.comarrayParamOut(CheckpointOut &os, const std::string &name,
42713414Sgiacomo.travaglini@arm.com              const std::list<T> &param)
42813414Sgiacomo.travaglini@arm.com{
42913414Sgiacomo.travaglini@arm.com    typename std::list<T>::const_iterator it = param.begin();
43013414Sgiacomo.travaglini@arm.com
43113414Sgiacomo.travaglini@arm.com    os << name << "=";
43213414Sgiacomo.travaglini@arm.com    if (param.size() > 0)
43313414Sgiacomo.travaglini@arm.com        showParam(os, *it);
43413414Sgiacomo.travaglini@arm.com    it++;
43513414Sgiacomo.travaglini@arm.com    while (it != param.end()) {
43613414Sgiacomo.travaglini@arm.com        os << " ";
43713414Sgiacomo.travaglini@arm.com        showParam(os, *it);
43813414Sgiacomo.travaglini@arm.com        it++;
43913414Sgiacomo.travaglini@arm.com    }
44013414Sgiacomo.travaglini@arm.com    os << "\n";
44113414Sgiacomo.travaglini@arm.com}
44213414Sgiacomo.travaglini@arm.com
44313414Sgiacomo.travaglini@arm.comtemplate <class T>
44413414Sgiacomo.travaglini@arm.comvoid
44513414Sgiacomo.travaglini@arm.comarrayParamOut(CheckpointOut &os, const std::string &name,
44613414Sgiacomo.travaglini@arm.com              const std::set<T> &param)
44713414Sgiacomo.travaglini@arm.com{
44813414Sgiacomo.travaglini@arm.com    typename std::set<T>::const_iterator it = param.begin();
44913414Sgiacomo.travaglini@arm.com
45013414Sgiacomo.travaglini@arm.com    os << name << "=";
45113414Sgiacomo.travaglini@arm.com    if (param.size() > 0)
45213414Sgiacomo.travaglini@arm.com        showParam(os, *it);
45313414Sgiacomo.travaglini@arm.com    it++;
45413414Sgiacomo.travaglini@arm.com    while (it != param.end()) {
45513414Sgiacomo.travaglini@arm.com        os << " ";
45613414Sgiacomo.travaglini@arm.com        showParam(os, *it);
45713414Sgiacomo.travaglini@arm.com        it++;
45813414Sgiacomo.travaglini@arm.com    }
45913414Sgiacomo.travaglini@arm.com    os << "\n";
46013414Sgiacomo.travaglini@arm.com}
46113414Sgiacomo.travaglini@arm.com
46213414Sgiacomo.travaglini@arm.comtemplate <class T>
46313414Sgiacomo.travaglini@arm.comvoid
46413414Sgiacomo.travaglini@arm.comarrayParamOut(CheckpointOut &os, const std::string &name,
46513414Sgiacomo.travaglini@arm.com              const T *param, unsigned size)
46613414Sgiacomo.travaglini@arm.com{
46713414Sgiacomo.travaglini@arm.com    os << name << "=";
46813414Sgiacomo.travaglini@arm.com    if (size > 0)
46913414Sgiacomo.travaglini@arm.com        showParam(os, param[0]);
47013414Sgiacomo.travaglini@arm.com    for (unsigned i = 1; i < size; ++i) {
47113414Sgiacomo.travaglini@arm.com        os << " ";
47213414Sgiacomo.travaglini@arm.com        showParam(os, param[i]);
47313414Sgiacomo.travaglini@arm.com    }
47413414Sgiacomo.travaglini@arm.com    os << "\n";
47513414Sgiacomo.travaglini@arm.com}
47613414Sgiacomo.travaglini@arm.com
47713757Sodanrc@yahoo.com.br/**
47813757Sodanrc@yahoo.com.br * Extract values stored in the checkpoint, and assign them to the provided
47913757Sodanrc@yahoo.com.br * array container.
48013757Sodanrc@yahoo.com.br *
48113757Sodanrc@yahoo.com.br * @param cp The checkpoint to be parsed.
48213757Sodanrc@yahoo.com.br * @param name Name of the container.
48313757Sodanrc@yahoo.com.br * @param param The array container.
48413757Sodanrc@yahoo.com.br * @param size The expected number of entries to be extracted.
48513757Sodanrc@yahoo.com.br */
48613414Sgiacomo.travaglini@arm.comtemplate <class T>
48713414Sgiacomo.travaglini@arm.comvoid
48813414Sgiacomo.travaglini@arm.comarrayParamIn(CheckpointIn &cp, const std::string &name,
48913414Sgiacomo.travaglini@arm.com             T *param, unsigned size)
49013414Sgiacomo.travaglini@arm.com{
49113414Sgiacomo.travaglini@arm.com    const std::string &section(Serializable::currentSection());
49213414Sgiacomo.travaglini@arm.com    std::string str;
49313414Sgiacomo.travaglini@arm.com    if (!cp.find(section, name, str)) {
49413414Sgiacomo.travaglini@arm.com        fatal("Can't unserialize '%s:%s'\n", section, name);
49513414Sgiacomo.travaglini@arm.com    }
49613414Sgiacomo.travaglini@arm.com
49713414Sgiacomo.travaglini@arm.com    // code below stolen from VectorParam<T>::parse().
49813414Sgiacomo.travaglini@arm.com    // it would be nice to unify these somehow...
49913414Sgiacomo.travaglini@arm.com
50013414Sgiacomo.travaglini@arm.com    std::vector<std::string> tokens;
50113414Sgiacomo.travaglini@arm.com
50213414Sgiacomo.travaglini@arm.com    tokenize(tokens, str, ' ');
50313414Sgiacomo.travaglini@arm.com
50413414Sgiacomo.travaglini@arm.com    // Need this if we were doing a vector
50513414Sgiacomo.travaglini@arm.com    // value.resize(tokens.size());
50613414Sgiacomo.travaglini@arm.com
50713757Sodanrc@yahoo.com.br    fatal_if(tokens.size() != size,
50813757Sodanrc@yahoo.com.br             "Array size mismatch on %s:%s (Got %u, expected %u)'\n",
50913757Sodanrc@yahoo.com.br             section, name, tokens.size(), size);
51013414Sgiacomo.travaglini@arm.com
51113414Sgiacomo.travaglini@arm.com    for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) {
51213414Sgiacomo.travaglini@arm.com        // need to parse into local variable to handle vector<bool>,
51313414Sgiacomo.travaglini@arm.com        // for which operator[] returns a special reference class
51413414Sgiacomo.travaglini@arm.com        // that's not the same as 'bool&', (since it's a packed
51513414Sgiacomo.travaglini@arm.com        // vector)
51613414Sgiacomo.travaglini@arm.com        T scalar_value;
51713414Sgiacomo.travaglini@arm.com        if (!parseParam(tokens[i], scalar_value)) {
51813414Sgiacomo.travaglini@arm.com            std::string err("could not parse \"");
51913414Sgiacomo.travaglini@arm.com
52013414Sgiacomo.travaglini@arm.com            err += str;
52113414Sgiacomo.travaglini@arm.com            err += "\"";
52213414Sgiacomo.travaglini@arm.com
52313414Sgiacomo.travaglini@arm.com            fatal(err);
52413414Sgiacomo.travaglini@arm.com        }
52513414Sgiacomo.travaglini@arm.com
52613414Sgiacomo.travaglini@arm.com        // assign parsed value to vector
52713414Sgiacomo.travaglini@arm.com        param[i] = scalar_value;
52813414Sgiacomo.travaglini@arm.com    }
52913414Sgiacomo.travaglini@arm.com}
53013414Sgiacomo.travaglini@arm.com
53113414Sgiacomo.travaglini@arm.comtemplate <class T>
53213414Sgiacomo.travaglini@arm.comvoid
53313414Sgiacomo.travaglini@arm.comarrayParamIn(CheckpointIn &cp, const std::string &name, std::vector<T> &param)
53413414Sgiacomo.travaglini@arm.com{
53513414Sgiacomo.travaglini@arm.com    const std::string &section(Serializable::currentSection());
53613414Sgiacomo.travaglini@arm.com    std::string str;
53713414Sgiacomo.travaglini@arm.com    if (!cp.find(section, name, str)) {
53813414Sgiacomo.travaglini@arm.com        fatal("Can't unserialize '%s:%s'\n", section, name);
53913414Sgiacomo.travaglini@arm.com    }
54013414Sgiacomo.travaglini@arm.com
54113414Sgiacomo.travaglini@arm.com    // code below stolen from VectorParam<T>::parse().
54213414Sgiacomo.travaglini@arm.com    // it would be nice to unify these somehow...
54313414Sgiacomo.travaglini@arm.com
54413414Sgiacomo.travaglini@arm.com    std::vector<std::string> tokens;
54513414Sgiacomo.travaglini@arm.com
54613414Sgiacomo.travaglini@arm.com    tokenize(tokens, str, ' ');
54713414Sgiacomo.travaglini@arm.com
54813414Sgiacomo.travaglini@arm.com    // Need this if we were doing a vector
54913414Sgiacomo.travaglini@arm.com    // value.resize(tokens.size());
55013414Sgiacomo.travaglini@arm.com
55113414Sgiacomo.travaglini@arm.com    param.resize(tokens.size());
55213414Sgiacomo.travaglini@arm.com
55313414Sgiacomo.travaglini@arm.com    for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) {
55413414Sgiacomo.travaglini@arm.com        // need to parse into local variable to handle vector<bool>,
55513414Sgiacomo.travaglini@arm.com        // for which operator[] returns a special reference class
55613414Sgiacomo.travaglini@arm.com        // that's not the same as 'bool&', (since it's a packed
55713414Sgiacomo.travaglini@arm.com        // vector)
55813414Sgiacomo.travaglini@arm.com        T scalar_value;
55913414Sgiacomo.travaglini@arm.com        if (!parseParam(tokens[i], scalar_value)) {
56013414Sgiacomo.travaglini@arm.com            std::string err("could not parse \"");
56113414Sgiacomo.travaglini@arm.com
56213414Sgiacomo.travaglini@arm.com            err += str;
56313414Sgiacomo.travaglini@arm.com            err += "\"";
56413414Sgiacomo.travaglini@arm.com
56513414Sgiacomo.travaglini@arm.com            fatal(err);
56613414Sgiacomo.travaglini@arm.com        }
56713414Sgiacomo.travaglini@arm.com
56813414Sgiacomo.travaglini@arm.com        // assign parsed value to vector
56913414Sgiacomo.travaglini@arm.com        param[i] = scalar_value;
57013414Sgiacomo.travaglini@arm.com    }
57113414Sgiacomo.travaglini@arm.com}
57213414Sgiacomo.travaglini@arm.com
57313414Sgiacomo.travaglini@arm.comtemplate <class T>
57413414Sgiacomo.travaglini@arm.comvoid
57513414Sgiacomo.travaglini@arm.comarrayParamIn(CheckpointIn &cp, const std::string &name, std::list<T> &param)
57613414Sgiacomo.travaglini@arm.com{
57713414Sgiacomo.travaglini@arm.com    const std::string &section(Serializable::currentSection());
57813414Sgiacomo.travaglini@arm.com    std::string str;
57913414Sgiacomo.travaglini@arm.com    if (!cp.find(section, name, str)) {
58013414Sgiacomo.travaglini@arm.com        fatal("Can't unserialize '%s:%s'\n", section, name);
58113414Sgiacomo.travaglini@arm.com    }
58213414Sgiacomo.travaglini@arm.com    param.clear();
58313414Sgiacomo.travaglini@arm.com
58413414Sgiacomo.travaglini@arm.com    std::vector<std::string> tokens;
58513414Sgiacomo.travaglini@arm.com    tokenize(tokens, str, ' ');
58613414Sgiacomo.travaglini@arm.com
58713414Sgiacomo.travaglini@arm.com    for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) {
58813414Sgiacomo.travaglini@arm.com        T scalar_value;
58913414Sgiacomo.travaglini@arm.com        if (!parseParam(tokens[i], scalar_value)) {
59013414Sgiacomo.travaglini@arm.com            std::string err("could not parse \"");
59113414Sgiacomo.travaglini@arm.com
59213414Sgiacomo.travaglini@arm.com            err += str;
59313414Sgiacomo.travaglini@arm.com            err += "\"";
59413414Sgiacomo.travaglini@arm.com
59513414Sgiacomo.travaglini@arm.com            fatal(err);
59613414Sgiacomo.travaglini@arm.com        }
59713414Sgiacomo.travaglini@arm.com
59813414Sgiacomo.travaglini@arm.com        // assign parsed value to vector
59913414Sgiacomo.travaglini@arm.com        param.push_back(scalar_value);
60013414Sgiacomo.travaglini@arm.com    }
60113414Sgiacomo.travaglini@arm.com}
60213414Sgiacomo.travaglini@arm.com
60313414Sgiacomo.travaglini@arm.comtemplate <class T>
60413414Sgiacomo.travaglini@arm.comvoid
60513414Sgiacomo.travaglini@arm.comarrayParamIn(CheckpointIn &cp, const std::string &name, std::set<T> &param)
60613414Sgiacomo.travaglini@arm.com{
60713414Sgiacomo.travaglini@arm.com    const std::string &section(Serializable::currentSection());
60813414Sgiacomo.travaglini@arm.com    std::string str;
60913414Sgiacomo.travaglini@arm.com    if (!cp.find(section, name, str)) {
61013414Sgiacomo.travaglini@arm.com        fatal("Can't unserialize '%s:%s'\n", section, name);
61113414Sgiacomo.travaglini@arm.com    }
61213414Sgiacomo.travaglini@arm.com    param.clear();
61313414Sgiacomo.travaglini@arm.com
61413414Sgiacomo.travaglini@arm.com    std::vector<std::string> tokens;
61513414Sgiacomo.travaglini@arm.com    tokenize(tokens, str, ' ');
61613414Sgiacomo.travaglini@arm.com
61713414Sgiacomo.travaglini@arm.com    for (std::vector<std::string>::size_type i = 0; i < tokens.size(); i++) {
61813414Sgiacomo.travaglini@arm.com        T scalar_value;
61913414Sgiacomo.travaglini@arm.com        if (!parseParam(tokens[i], scalar_value)) {
62013414Sgiacomo.travaglini@arm.com            std::string err("could not parse \"");
62113414Sgiacomo.travaglini@arm.com
62213414Sgiacomo.travaglini@arm.com            err += str;
62313414Sgiacomo.travaglini@arm.com            err += "\"";
62413414Sgiacomo.travaglini@arm.com
62513414Sgiacomo.travaglini@arm.com            fatal(err);
62613414Sgiacomo.travaglini@arm.com        }
62713414Sgiacomo.travaglini@arm.com
62813414Sgiacomo.travaglini@arm.com        // assign parsed value to vector
62913414Sgiacomo.travaglini@arm.com        param.insert(scalar_value);
63013414Sgiacomo.travaglini@arm.com    }
63113414Sgiacomo.travaglini@arm.com}
63213414Sgiacomo.travaglini@arm.com
63313414Sgiacomo.travaglini@arm.comvoid
63413414Sgiacomo.travaglini@arm.comdebug_serialize(const std::string &cpt_dir);
63513414Sgiacomo.travaglini@arm.com
63613414Sgiacomo.travaglini@arm.comvoid
63713414Sgiacomo.travaglini@arm.comobjParamIn(CheckpointIn &cp, const std::string &name, SimObject * &param);
63813414Sgiacomo.travaglini@arm.com
63913414Sgiacomo.travaglini@arm.com//
64013414Sgiacomo.travaglini@arm.com// These macros are streamlined to use in serialize/unserialize
64113414Sgiacomo.travaglini@arm.com// functions.  It's assumed that serialize() has a parameter 'os' for
64213414Sgiacomo.travaglini@arm.com// the ostream, and unserialize() has parameters 'cp' and 'section'.
64313414Sgiacomo.travaglini@arm.com#define SERIALIZE_SCALAR(scalar)        paramOut(cp, #scalar, scalar)
64413414Sgiacomo.travaglini@arm.com
64513414Sgiacomo.travaglini@arm.com#define UNSERIALIZE_SCALAR(scalar)      paramIn(cp, #scalar, scalar)
64613414Sgiacomo.travaglini@arm.com#define UNSERIALIZE_OPT_SCALAR(scalar)      optParamIn(cp, #scalar, scalar)
64713414Sgiacomo.travaglini@arm.com
64813414Sgiacomo.travaglini@arm.com// ENUMs are like SCALARs, but we cast them to ints on the way out
64913414Sgiacomo.travaglini@arm.com#define SERIALIZE_ENUM(scalar)          paramOut(cp, #scalar, (int)scalar)
65013414Sgiacomo.travaglini@arm.com
65113414Sgiacomo.travaglini@arm.com#define UNSERIALIZE_ENUM(scalar)                        \
65213414Sgiacomo.travaglini@arm.com    do {                                                \
65313414Sgiacomo.travaglini@arm.com        int tmp;                                        \
65413414Sgiacomo.travaglini@arm.com        paramIn(cp, #scalar, tmp);                      \
65513414Sgiacomo.travaglini@arm.com        scalar = static_cast<decltype(scalar)>(tmp);    \
65613414Sgiacomo.travaglini@arm.com    } while (0)
65713414Sgiacomo.travaglini@arm.com
65813414Sgiacomo.travaglini@arm.com#define SERIALIZE_ARRAY(member, size)           \
65913414Sgiacomo.travaglini@arm.com        arrayParamOut(cp, #member, member, size)
66013414Sgiacomo.travaglini@arm.com
66113414Sgiacomo.travaglini@arm.com#define UNSERIALIZE_ARRAY(member, size)         \
66213414Sgiacomo.travaglini@arm.com        arrayParamIn(cp, #member, member, size)
66313414Sgiacomo.travaglini@arm.com
66413414Sgiacomo.travaglini@arm.com#define SERIALIZE_CONTAINER(member)             \
66513414Sgiacomo.travaglini@arm.com        arrayParamOut(cp, #member, member)
66613414Sgiacomo.travaglini@arm.com
66713414Sgiacomo.travaglini@arm.com#define UNSERIALIZE_CONTAINER(member)           \
66813414Sgiacomo.travaglini@arm.com        arrayParamIn(cp, #member, member)
66913414Sgiacomo.travaglini@arm.com
67013414Sgiacomo.travaglini@arm.com#define SERIALIZE_EVENT(event) event.serializeSection(cp, #event);
67113414Sgiacomo.travaglini@arm.com
67213414Sgiacomo.travaglini@arm.com#define UNSERIALIZE_EVENT(event)                        \
67313414Sgiacomo.travaglini@arm.com    do {                                                \
67413414Sgiacomo.travaglini@arm.com        event.unserializeSection(cp, #event);           \
67513414Sgiacomo.travaglini@arm.com        eventQueue()->checkpointReschedule(&event);     \
67613414Sgiacomo.travaglini@arm.com    } while (0)
67713414Sgiacomo.travaglini@arm.com
67813414Sgiacomo.travaglini@arm.com#define SERIALIZE_OBJ(obj) obj.serializeSection(cp, #obj)
67913414Sgiacomo.travaglini@arm.com#define UNSERIALIZE_OBJ(obj) obj.unserializeSection(cp, #obj)
68013414Sgiacomo.travaglini@arm.com
68113414Sgiacomo.travaglini@arm.com#define SERIALIZE_OBJPTR(objptr)        paramOut(cp, #objptr, (objptr)->name())
68213414Sgiacomo.travaglini@arm.com
68313414Sgiacomo.travaglini@arm.com#define UNSERIALIZE_OBJPTR(objptr)                      \
68413414Sgiacomo.travaglini@arm.com    do {                                                \
68513414Sgiacomo.travaglini@arm.com        SimObject *sptr;                                \
68613414Sgiacomo.travaglini@arm.com        objParamIn(cp, #objptr, sptr);                  \
68713414Sgiacomo.travaglini@arm.com        objptr = dynamic_cast<decltype(objptr)>(sptr);  \
68813414Sgiacomo.travaglini@arm.com    } while (0)
6892SN/A
6902SN/A#endif // __SERIALIZE_HH__
691