serialize.hh revision 11069:c5388db11c76
112027Sjungma@eit.uni-kl.de/*
212027Sjungma@eit.uni-kl.de * Copyright (c) 2015 ARM Limited
312027Sjungma@eit.uni-kl.de * All rights reserved
412027Sjungma@eit.uni-kl.de *
512027Sjungma@eit.uni-kl.de * The license below extends only to copyright in the software and shall
612027Sjungma@eit.uni-kl.de * not be construed as granting a license to any other intellectual
712027Sjungma@eit.uni-kl.de * property including but not limited to intellectual property relating
812027Sjungma@eit.uni-kl.de * to a hardware implementation of the functionality of the software
912027Sjungma@eit.uni-kl.de * licensed hereunder.  You may use the software subject to the license
1012027Sjungma@eit.uni-kl.de * terms below provided that you ensure that this notice is replicated
1112027Sjungma@eit.uni-kl.de * unmodified and in its entirety in all distributions of the software,
1212027Sjungma@eit.uni-kl.de * modified or unmodified, in source code or in binary form.
1312027Sjungma@eit.uni-kl.de *
1412027Sjungma@eit.uni-kl.de * Copyright (c) 2002-2005 The Regents of The University of Michigan
1512027Sjungma@eit.uni-kl.de * All rights reserved.
1612027Sjungma@eit.uni-kl.de *
1712027Sjungma@eit.uni-kl.de * Redistribution and use in source and binary forms, with or without
1812027Sjungma@eit.uni-kl.de * modification, are permitted provided that the following conditions are
1912027Sjungma@eit.uni-kl.de * met: redistributions of source code must retain the above copyright
2012027Sjungma@eit.uni-kl.de * notice, this list of conditions and the following disclaimer;
2112027Sjungma@eit.uni-kl.de * redistributions in binary form must reproduce the above copyright
2212027Sjungma@eit.uni-kl.de * notice, this list of conditions and the following disclaimer in the
2312027Sjungma@eit.uni-kl.de * documentation and/or other materials provided with the distribution;
2412027Sjungma@eit.uni-kl.de * neither the name of the copyright holders nor the names of its
2512027Sjungma@eit.uni-kl.de * contributors may be used to endorse or promote products derived from
2612027Sjungma@eit.uni-kl.de * this software without specific prior written permission.
2712027Sjungma@eit.uni-kl.de *
2812027Sjungma@eit.uni-kl.de * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2912027Sjungma@eit.uni-kl.de * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3012027Sjungma@eit.uni-kl.de * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3112027Sjungma@eit.uni-kl.de * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3212027Sjungma@eit.uni-kl.de * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3312027Sjungma@eit.uni-kl.de * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3412027Sjungma@eit.uni-kl.de * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3512027Sjungma@eit.uni-kl.de * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3612027Sjungma@eit.uni-kl.de * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3712027Sjungma@eit.uni-kl.de * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3812027Sjungma@eit.uni-kl.de * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3912027Sjungma@eit.uni-kl.de *
4012027Sjungma@eit.uni-kl.de * Authors: Nathan Binkert
4112027Sjungma@eit.uni-kl.de *          Erik Hallnor
4212027Sjungma@eit.uni-kl.de *          Steve Reinhardt
4312027Sjungma@eit.uni-kl.de *          Andreas Sandberg
4412027Sjungma@eit.uni-kl.de */
4512027Sjungma@eit.uni-kl.de
4612027Sjungma@eit.uni-kl.de/* @file
4712027Sjungma@eit.uni-kl.de * Serialization Interface Declarations
4812027Sjungma@eit.uni-kl.de */
4912027Sjungma@eit.uni-kl.de
5012027Sjungma@eit.uni-kl.de#ifndef __SERIALIZE_HH__
5112027Sjungma@eit.uni-kl.de#define __SERIALIZE_HH__
5212027Sjungma@eit.uni-kl.de
5312027Sjungma@eit.uni-kl.de
5412027Sjungma@eit.uni-kl.de#include <iostream>
5512027Sjungma@eit.uni-kl.de#include <list>
5612027Sjungma@eit.uni-kl.de#include <map>
5712027Sjungma@eit.uni-kl.de#include <stack>
5812027Sjungma@eit.uni-kl.de#include <vector>
5912027Sjungma@eit.uni-kl.de
6012027Sjungma@eit.uni-kl.de#include "base/bitunion.hh"
6112027Sjungma@eit.uni-kl.de#include "base/types.hh"
6212027Sjungma@eit.uni-kl.de
6312027Sjungma@eit.uni-kl.declass IniFile;
6412027Sjungma@eit.uni-kl.declass Serializable;
6512027Sjungma@eit.uni-kl.declass CheckpointIn;
6612027Sjungma@eit.uni-kl.declass SimObject;
6712027Sjungma@eit.uni-kl.declass SimObjectResolver;
6812027Sjungma@eit.uni-kl.declass EventQueue;
6912027Sjungma@eit.uni-kl.de
7012027Sjungma@eit.uni-kl.detypedef std::ostream CheckpointOut;
7112027Sjungma@eit.uni-kl.de
7212027Sjungma@eit.uni-kl.de
7312027Sjungma@eit.uni-kl.de/** The current version of the checkpoint format.
7412027Sjungma@eit.uni-kl.de * This should be incremented by 1 and only 1 for every new version, where a new
7512027Sjungma@eit.uni-kl.de * version is defined as a checkpoint created before this version won't work on
7612027Sjungma@eit.uni-kl.de * the current version until the checkpoint format is updated. Adding a new
7712027Sjungma@eit.uni-kl.de * SimObject shouldn't cause the version number to increase, only changes to
7812027Sjungma@eit.uni-kl.de * existing objects such as serializing/unserializing more state, changing sizes
7912027Sjungma@eit.uni-kl.de * of serialized arrays, etc. */
8012027Sjungma@eit.uni-kl.destatic const uint64_t gem5CheckpointVersion = 0x000000000000000f;
8112027Sjungma@eit.uni-kl.de
8212027Sjungma@eit.uni-kl.detemplate <class T>
8312027Sjungma@eit.uni-kl.devoid paramOut(CheckpointOut &cp, const std::string &name, const T &param);
8412027Sjungma@eit.uni-kl.de
8512027Sjungma@eit.uni-kl.detemplate <typename DataType, typename BitUnion>
8612027Sjungma@eit.uni-kl.devoid paramOut(CheckpointOut &cp, const std::string &name,
8712027Sjungma@eit.uni-kl.de              const BitfieldBackend::BitUnionOperators<DataType, BitUnion> &p)
8812027Sjungma@eit.uni-kl.de{
8912027Sjungma@eit.uni-kl.de    paramOut(cp, name, p.__data);
9012027Sjungma@eit.uni-kl.de}
9112027Sjungma@eit.uni-kl.de
9212027Sjungma@eit.uni-kl.detemplate <class T>
9312027Sjungma@eit.uni-kl.devoid paramIn(CheckpointIn &cp, const std::string &name, T &param);
9412027Sjungma@eit.uni-kl.de
9512027Sjungma@eit.uni-kl.detemplate <typename DataType, typename BitUnion>
9612027Sjungma@eit.uni-kl.devoid paramIn(CheckpointIn &cp, const std::string &name,
9712027Sjungma@eit.uni-kl.de             BitfieldBackend::BitUnionOperators<DataType, BitUnion> &p)
9812027Sjungma@eit.uni-kl.de{
9912027Sjungma@eit.uni-kl.de    paramIn(cp, name, p.__data);
10012027Sjungma@eit.uni-kl.de}
10112027Sjungma@eit.uni-kl.de
10212027Sjungma@eit.uni-kl.detemplate <class T>
10312027Sjungma@eit.uni-kl.debool optParamIn(CheckpointIn &cp, const std::string &name, T &param);
10412027Sjungma@eit.uni-kl.de
10512027Sjungma@eit.uni-kl.detemplate <typename DataType, typename BitUnion>
10612027Sjungma@eit.uni-kl.debool optParamIn(CheckpointIn &cp, const std::string &name,
10712027Sjungma@eit.uni-kl.de                BitfieldBackend::BitUnionOperators<DataType, BitUnion> &p)
10812027Sjungma@eit.uni-kl.de{
10912027Sjungma@eit.uni-kl.de    return optParamIn(cp, name, p.__data);
11012027Sjungma@eit.uni-kl.de}
11112027Sjungma@eit.uni-kl.de
11212027Sjungma@eit.uni-kl.detemplate <class T>
11312027Sjungma@eit.uni-kl.devoid arrayParamOut(CheckpointOut &cp, const std::string &name,
11412027Sjungma@eit.uni-kl.de                   const T *param, unsigned size);
11512027Sjungma@eit.uni-kl.de
11612027Sjungma@eit.uni-kl.detemplate <class T>
11712027Sjungma@eit.uni-kl.devoid arrayParamOut(CheckpointOut &cp, const std::string &name,
11812027Sjungma@eit.uni-kl.de                   const std::vector<T> &param);
11912027Sjungma@eit.uni-kl.de
12012027Sjungma@eit.uni-kl.detemplate <class T>
12112027Sjungma@eit.uni-kl.devoid arrayParamOut(CheckpointOut &cp, const std::string &name,
12212027Sjungma@eit.uni-kl.de                   const std::list<T> &param);
12312027Sjungma@eit.uni-kl.de
12412027Sjungma@eit.uni-kl.detemplate <class T>
12512027Sjungma@eit.uni-kl.devoid arrayParamIn(CheckpointIn &cp, const std::string &name,
12612027Sjungma@eit.uni-kl.de                  T *param, unsigned size);
12712027Sjungma@eit.uni-kl.de
12812027Sjungma@eit.uni-kl.detemplate <class T>
12912027Sjungma@eit.uni-kl.devoid arrayParamIn(CheckpointIn &cp, const std::string &name,
13012027Sjungma@eit.uni-kl.de                  std::vector<T> &param);
13112027Sjungma@eit.uni-kl.de
13212027Sjungma@eit.uni-kl.detemplate <class T>
13312027Sjungma@eit.uni-kl.devoid arrayParamIn(CheckpointIn &cp, const std::string &name,
13412027Sjungma@eit.uni-kl.de                  std::list<T> &param);
13512027Sjungma@eit.uni-kl.de
13612027Sjungma@eit.uni-kl.devoid
13712027Sjungma@eit.uni-kl.deobjParamIn(CheckpointIn &cp, const std::string &name, SimObject * &param);
13812027Sjungma@eit.uni-kl.de
13912027Sjungma@eit.uni-kl.de//
14012027Sjungma@eit.uni-kl.de// These macros are streamlined to use in serialize/unserialize
14112027Sjungma@eit.uni-kl.de// functions.  It's assumed that serialize() has a parameter 'os' for
14212027Sjungma@eit.uni-kl.de// the ostream, and unserialize() has parameters 'cp' and 'section'.
14312027Sjungma@eit.uni-kl.de#define SERIALIZE_SCALAR(scalar)        paramOut(cp, #scalar, scalar)
14412027Sjungma@eit.uni-kl.de
14512027Sjungma@eit.uni-kl.de#define UNSERIALIZE_SCALAR(scalar)      paramIn(cp, #scalar, scalar)
14612027Sjungma@eit.uni-kl.de#define UNSERIALIZE_OPT_SCALAR(scalar)      optParamIn(cp, #scalar, scalar)
14712027Sjungma@eit.uni-kl.de
14812027Sjungma@eit.uni-kl.de// ENUMs are like SCALARs, but we cast them to ints on the way out
14912027Sjungma@eit.uni-kl.de#define SERIALIZE_ENUM(scalar)          paramOut(cp, #scalar, (int)scalar)
15012027Sjungma@eit.uni-kl.de
15112027Sjungma@eit.uni-kl.de#define UNSERIALIZE_ENUM(scalar)                        \
15212027Sjungma@eit.uni-kl.de    do {                                                \
15312027Sjungma@eit.uni-kl.de        int tmp;                                        \
15412027Sjungma@eit.uni-kl.de        paramIn(cp, #scalar, tmp);                      \
15512027Sjungma@eit.uni-kl.de        scalar = static_cast<decltype(scalar)>(tmp);    \
15612027Sjungma@eit.uni-kl.de    } while (0)
15712027Sjungma@eit.uni-kl.de
15812027Sjungma@eit.uni-kl.de#define SERIALIZE_ARRAY(member, size)           \
15912027Sjungma@eit.uni-kl.de        arrayParamOut(cp, #member, member, size)
16012027Sjungma@eit.uni-kl.de
16112027Sjungma@eit.uni-kl.de#define UNSERIALIZE_ARRAY(member, size)         \
16212027Sjungma@eit.uni-kl.de        arrayParamIn(cp, #member, member, size)
16312027Sjungma@eit.uni-kl.de
16412027Sjungma@eit.uni-kl.de#define SERIALIZE_CONTAINER(member)             \
16512027Sjungma@eit.uni-kl.de        arrayParamOut(cp, #member, member)
16612027Sjungma@eit.uni-kl.de
16712027Sjungma@eit.uni-kl.de#define UNSERIALIZE_CONTAINER(member)           \
16812027Sjungma@eit.uni-kl.de        arrayParamIn(cp, #member, member)
16912027Sjungma@eit.uni-kl.de
17012027Sjungma@eit.uni-kl.de#define SERIALIZE_EVENT(event) event.serializeSection(cp, #event);
17112027Sjungma@eit.uni-kl.de
17212027Sjungma@eit.uni-kl.de#define UNSERIALIZE_EVENT(event)                        \
17312027Sjungma@eit.uni-kl.de    do {                                                \
17412027Sjungma@eit.uni-kl.de        event.unserializeSection(cp, #event);           \
17512027Sjungma@eit.uni-kl.de        eventQueue()->checkpointReschedule(&event);     \
17612027Sjungma@eit.uni-kl.de    } while(0)
17712027Sjungma@eit.uni-kl.de
17812027Sjungma@eit.uni-kl.de#define SERIALIZE_OBJ(obj) obj.serializeSection(cp, #obj)
17912027Sjungma@eit.uni-kl.de#define UNSERIALIZE_OBJ(obj) obj.unserializeSection(cp, #obj)
18012027Sjungma@eit.uni-kl.de
18112027Sjungma@eit.uni-kl.de#define SERIALIZE_OBJPTR(objptr)        paramOut(cp, #objptr, (objptr)->name())
18212027Sjungma@eit.uni-kl.de
18312027Sjungma@eit.uni-kl.de#define UNSERIALIZE_OBJPTR(objptr)                      \
18412027Sjungma@eit.uni-kl.de    do {                                                \
18512027Sjungma@eit.uni-kl.de        SimObject *sptr;                                \
18612027Sjungma@eit.uni-kl.de        objParamIn(cp, #objptr, sptr);                  \
18712027Sjungma@eit.uni-kl.de        objptr = dynamic_cast<decltype(objptr)>(sptr);  \
18812027Sjungma@eit.uni-kl.de    } while (0)
18912027Sjungma@eit.uni-kl.de
19012027Sjungma@eit.uni-kl.de/**
19112027Sjungma@eit.uni-kl.de * Basic support for object serialization.
19212027Sjungma@eit.uni-kl.de *
19312027Sjungma@eit.uni-kl.de * Objects that support serialization should derive from this
19412027Sjungma@eit.uni-kl.de * class. Such objects can largely be divided into two categories: 1)
19512027Sjungma@eit.uni-kl.de * True SimObjects (deriving from SimObject), and 2) child objects
19612027Sjungma@eit.uni-kl.de * (non-SimObjects).
19712027Sjungma@eit.uni-kl.de *
19812027Sjungma@eit.uni-kl.de * SimObjects are serialized automatically into their own sections
19912027Sjungma@eit.uni-kl.de * automatically by the SimObject base class (see
20012027Sjungma@eit.uni-kl.de * SimObject::serializeAll().
20112027Sjungma@eit.uni-kl.de *
20212027Sjungma@eit.uni-kl.de * SimObjects can contain other serializable objects that are not
20312027Sjungma@eit.uni-kl.de * SimObjects. Much like normal serialized members are not serialized
20412027Sjungma@eit.uni-kl.de * automatically, these objects will not be serialized automatically
20512027Sjungma@eit.uni-kl.de * and it is expected that the objects owning such serializable
20612027Sjungma@eit.uni-kl.de * objects call the required serialization/unserialization methods on
20712027Sjungma@eit.uni-kl.de * child objects. The preferred method to serialize a child object is
20812027Sjungma@eit.uni-kl.de * to call serializeSection() on the child, which serializes the
20912027Sjungma@eit.uni-kl.de * object into a new subsection in the current section. Another option
21012027Sjungma@eit.uni-kl.de * is to call serialize() directly, which serializes the object into
21112027Sjungma@eit.uni-kl.de * the current section. The latter is not recommended as it can lead
21212027Sjungma@eit.uni-kl.de * to naming clashes between objects.
21312027Sjungma@eit.uni-kl.de *
21412027Sjungma@eit.uni-kl.de * @note Many objects that support serialization need to be put in a
21512027Sjungma@eit.uni-kl.de * consistent state when serialization takes place. We refer to the
21612027Sjungma@eit.uni-kl.de * action of forcing an object into a consistent state as
21712027Sjungma@eit.uni-kl.de * 'draining'. Objects that need draining inherit from Drainable. See
21812027Sjungma@eit.uni-kl.de * Drainable for more information.
21912027Sjungma@eit.uni-kl.de */
22012027Sjungma@eit.uni-kl.declass Serializable
22112027Sjungma@eit.uni-kl.de{
22212027Sjungma@eit.uni-kl.de  protected:
22312027Sjungma@eit.uni-kl.de    /**
22412027Sjungma@eit.uni-kl.de     * Scoped checkpoint section helper class
22512027Sjungma@eit.uni-kl.de     *
22612027Sjungma@eit.uni-kl.de     * This helper class creates a section within a checkpoint without
22712027Sjungma@eit.uni-kl.de     * the need for a separate serializeable object. It is mainly used
22812027Sjungma@eit.uni-kl.de     * within the Serializable class when serializing or unserializing
22912027Sjungma@eit.uni-kl.de     * section (see serializeSection() and unserializeSection()). It
23012027Sjungma@eit.uni-kl.de     * can also be used to maintain backwards compatibility in
23112027Sjungma@eit.uni-kl.de     * existing code that serializes structs that are not inheriting
23212027Sjungma@eit.uni-kl.de     * from Serializable into subsections.
23312027Sjungma@eit.uni-kl.de     *
23412027Sjungma@eit.uni-kl.de     * When the class is instantiated, it appends a name to the active
23512027Sjungma@eit.uni-kl.de     * path in a checkpoint. The old path is later restored when the
23612027Sjungma@eit.uni-kl.de     * instance is destroyed. For example, serializeSection() could be
23712027Sjungma@eit.uni-kl.de     * implemented by instantiating a ScopedCheckpointSection and then
23812027Sjungma@eit.uni-kl.de     * calling serialize() on an object.
23912027Sjungma@eit.uni-kl.de     */
24012027Sjungma@eit.uni-kl.de    class ScopedCheckpointSection {
24112027Sjungma@eit.uni-kl.de      public:
24212027Sjungma@eit.uni-kl.de        template<class CP>
24312027Sjungma@eit.uni-kl.de        ScopedCheckpointSection(CP &cp, const char *name) {
24412027Sjungma@eit.uni-kl.de            pushName(name);
24512027Sjungma@eit.uni-kl.de            nameOut(cp);
24612027Sjungma@eit.uni-kl.de        }
24712027Sjungma@eit.uni-kl.de
24812027Sjungma@eit.uni-kl.de        template<class CP>
24912027Sjungma@eit.uni-kl.de        ScopedCheckpointSection(CP &cp, const std::string &name) {
25012027Sjungma@eit.uni-kl.de            pushName(name.c_str());
25112027Sjungma@eit.uni-kl.de            nameOut(cp);
25212027Sjungma@eit.uni-kl.de        }
25312027Sjungma@eit.uni-kl.de
25412027Sjungma@eit.uni-kl.de        ~ScopedCheckpointSection();
25512027Sjungma@eit.uni-kl.de
25612027Sjungma@eit.uni-kl.de        ScopedCheckpointSection() = delete;
25712027Sjungma@eit.uni-kl.de        ScopedCheckpointSection(const ScopedCheckpointSection &) = delete;
25812027Sjungma@eit.uni-kl.de        ScopedCheckpointSection &operator=(
25912027Sjungma@eit.uni-kl.de            const ScopedCheckpointSection &) = delete;
26012027Sjungma@eit.uni-kl.de        ScopedCheckpointSection &operator=(
26112027Sjungma@eit.uni-kl.de            ScopedCheckpointSection &&) = delete;
26212027Sjungma@eit.uni-kl.de
26312027Sjungma@eit.uni-kl.de      private:
26412027Sjungma@eit.uni-kl.de        void pushName(const char *name);
26512027Sjungma@eit.uni-kl.de        void nameOut(CheckpointOut &cp);
26612027Sjungma@eit.uni-kl.de        void nameOut(CheckpointIn &cp) {};
26712027Sjungma@eit.uni-kl.de    };
26812027Sjungma@eit.uni-kl.de
26912027Sjungma@eit.uni-kl.de  public:
27012027Sjungma@eit.uni-kl.de    Serializable();
27112027Sjungma@eit.uni-kl.de    virtual ~Serializable();
27212027Sjungma@eit.uni-kl.de
27312027Sjungma@eit.uni-kl.de    /**
27412027Sjungma@eit.uni-kl.de     * Serialize an object
27512027Sjungma@eit.uni-kl.de     *
27612027Sjungma@eit.uni-kl.de     * Output an object's state into the current checkpoint section.
27712027Sjungma@eit.uni-kl.de     *
27812027Sjungma@eit.uni-kl.de     * @param cp Checkpoint state
27912027Sjungma@eit.uni-kl.de     */
28012027Sjungma@eit.uni-kl.de    virtual void serialize(CheckpointOut &cp) const = 0;
28112027Sjungma@eit.uni-kl.de
28212027Sjungma@eit.uni-kl.de    /**
28312027Sjungma@eit.uni-kl.de     * Unserialize an object
28412027Sjungma@eit.uni-kl.de     *
28512027Sjungma@eit.uni-kl.de     * Read an object's state from the current checkpoint section.
28612027Sjungma@eit.uni-kl.de     *
28712027Sjungma@eit.uni-kl.de     * @param cp Checkpoint state
28812027Sjungma@eit.uni-kl.de     */
28912027Sjungma@eit.uni-kl.de    virtual void unserialize(CheckpointIn &cp) = 0;
29012027Sjungma@eit.uni-kl.de
29112027Sjungma@eit.uni-kl.de    /**
29212027Sjungma@eit.uni-kl.de     * Serialize an object into a new section
29312027Sjungma@eit.uni-kl.de     *
29412027Sjungma@eit.uni-kl.de     * This method creates a new section in a checkpoint and calls
29512027Sjungma@eit.uni-kl.de     * serialize() to serialize the current object into that
29612027Sjungma@eit.uni-kl.de     * section. The name of the section is appended to the current
29712027Sjungma@eit.uni-kl.de     * checkpoint path.
29812027Sjungma@eit.uni-kl.de     *
29912027Sjungma@eit.uni-kl.de     * @param cp Checkpoint state
30012027Sjungma@eit.uni-kl.de     * @param name Name to append to the active path
30112027Sjungma@eit.uni-kl.de     */
30212027Sjungma@eit.uni-kl.de    void serializeSection(CheckpointOut &cp, const char *name) const;
30312027Sjungma@eit.uni-kl.de
30412027Sjungma@eit.uni-kl.de    void serializeSection(CheckpointOut &cp, const std::string &name) const {
30512027Sjungma@eit.uni-kl.de        serializeSection(cp, name.c_str());
30612027Sjungma@eit.uni-kl.de    }
30712027Sjungma@eit.uni-kl.de
30812027Sjungma@eit.uni-kl.de    /**
30912027Sjungma@eit.uni-kl.de     * Unserialize an a child object
31012027Sjungma@eit.uni-kl.de     *
31112027Sjungma@eit.uni-kl.de     * This method loads a child object from a checkpoint. The object
31212027Sjungma@eit.uni-kl.de     * name is appended to the active path to form a fully qualified
31312027Sjungma@eit.uni-kl.de     * section name and unserialize() is called.
31412027Sjungma@eit.uni-kl.de     *
31512027Sjungma@eit.uni-kl.de     * @param cp Checkpoint state
31612027Sjungma@eit.uni-kl.de     * @param name Name to append to the active path
31712027Sjungma@eit.uni-kl.de     */
31812027Sjungma@eit.uni-kl.de    void unserializeSection(CheckpointIn &cp, const char *name);
31912027Sjungma@eit.uni-kl.de
32012027Sjungma@eit.uni-kl.de    void unserializeSection(CheckpointIn &cp, const std::string &name) {
32112027Sjungma@eit.uni-kl.de        unserializeSection(cp, name.c_str());
32212027Sjungma@eit.uni-kl.de    }
32312027Sjungma@eit.uni-kl.de
32412027Sjungma@eit.uni-kl.de    /**
32512027Sjungma@eit.uni-kl.de     * @{
32612027Sjungma@eit.uni-kl.de     * @name Legacy interface
32712027Sjungma@eit.uni-kl.de     *
32812027Sjungma@eit.uni-kl.de     * Interface for objects that insist on changing their state when
32912027Sjungma@eit.uni-kl.de     * serializing. Such state change should be done in drain(),
33012027Sjungma@eit.uni-kl.de     * memWriteback(), or memInvalidate() and not in the serialization
33112027Sjungma@eit.uni-kl.de     * method. In general, if state changes occur in serialize, it
33212027Sjungma@eit.uni-kl.de     * complicates testing since it breaks assumptions about draining
33312027Sjungma@eit.uni-kl.de     * and serialization. It potentially also makes components more
33412027Sjungma@eit.uni-kl.de     * fragile since they there are no ordering guarantees when
33512027Sjungma@eit.uni-kl.de     * serializing SimObjects.
33612027Sjungma@eit.uni-kl.de     *
33712027Sjungma@eit.uni-kl.de     * @warn This interface is considered deprecated and should never
33812027Sjungma@eit.uni-kl.de     * be used.
339     */
340
341    virtual void serializeOld(CheckpointOut &cp) {
342        serialize(cp);
343    }
344    void serializeSectionOld(CheckpointOut &cp, const char *name);
345    void serializeSectionOld(CheckpointOut &cp, const std::string &name) {
346        serializeSectionOld(cp, name.c_str());
347    }
348    /** @} */
349
350    /** Get the fully-qualified name of the active section */
351    static const std::string &currentSection();
352
353    static Serializable *create(CheckpointIn &cp, const std::string &section);
354
355    static int ckptCount;
356    static int ckptMaxCount;
357    static int ckptPrevCount;
358    static void serializeAll(const std::string &cpt_dir);
359    static void unserializeGlobals(CheckpointIn &cp);
360
361  private:
362    static std::stack<std::string> path;
363};
364
365void debug_serialize(const std::string &cpt_dir);
366
367//
368// An instance of SerializableClass corresponds to a class derived from
369// Serializable.  The SerializableClass instance serves to bind the string
370// name (found in the config file) to a function that creates an
371// instance of the appropriate derived class.
372//
373// This would be much cleaner in Smalltalk or Objective-C, where types
374// are first-class objects themselves.
375//
376class SerializableClass
377{
378  public:
379
380    // Type CreateFunc is a pointer to a function that creates a new
381    // simulation object builder based on a .ini-file parameter
382    // section (specified by the first string argument), a unique name
383    // for the object (specified by the second string argument), and
384    // an optional config hierarchy node (specified by the third
385    // argument).  A pointer to the new SerializableBuilder is returned.
386    typedef Serializable *(*CreateFunc)(CheckpointIn &cp,
387                                        const std::string &section);
388
389    static std::map<std::string,CreateFunc> *classMap;
390
391    // Constructor.  For example:
392    //
393    // SerializableClass baseCacheSerializableClass("BaseCacheSerializable",
394    //                         newBaseCacheSerializableBuilder);
395    //
396    SerializableClass(const std::string &className, CreateFunc createFunc);
397
398    // create Serializable given name of class and pointer to
399    // configuration hierarchy node
400    static Serializable *createObject(CheckpointIn &cp,
401                                      const std::string &section);
402};
403
404//
405// Macros to encapsulate the magic of declaring & defining
406// SerializableBuilder and SerializableClass objects
407//
408
409#define REGISTER_SERIALIZEABLE(CLASS_NAME, OBJ_CLASS)                      \
410SerializableClass the##OBJ_CLASS##Class(CLASS_NAME,                        \
411                                         OBJ_CLASS::createForUnserialize);
412
413
414class CheckpointIn
415{
416  private:
417
418    IniFile *db;
419
420    SimObjectResolver &objNameResolver;
421
422  public:
423    CheckpointIn(const std::string &cpt_dir, SimObjectResolver &resolver);
424    ~CheckpointIn();
425
426    const std::string cptDir;
427
428    bool find(const std::string &section, const std::string &entry,
429              std::string &value);
430
431    bool findObj(const std::string &section, const std::string &entry,
432                 SimObject *&value);
433
434    bool sectionExists(const std::string &section);
435
436    // The following static functions have to do with checkpoint
437    // creation rather than restoration.  This class makes a handy
438    // namespace for them though.  Currently no Checkpoint object is
439    // created on serialization (only unserialization) so we track the
440    // directory name as a global.  It would be nice to change this
441    // someday
442
443  private:
444    // current directory we're serializing into.
445    static std::string currentDirectory;
446
447  public:
448    // Set the current directory.  This function takes care of
449    // inserting curTick() if there's a '%d' in the argument, and
450    // appends a '/' if necessary.  The final name is returned.
451    static std::string setDir(const std::string &base_name);
452
453    // Export current checkpoint directory name so other objects can
454    // derive filenames from it (e.g., memory).  The return value is
455    // guaranteed to end in '/' so filenames can be directly appended.
456    // This function is only valid while a checkpoint is being created.
457    static std::string dir();
458
459    // Filename for base checkpoint file within directory.
460    static const char *baseFilename;
461};
462
463#endif // __SERIALIZE_HH__
464