114205Sandreas.sandberg@arm.com/*
214205Sandreas.sandberg@arm.com * Copyright (c) 2019 Arm Limited
314205Sandreas.sandberg@arm.com * All rights reserved
414205Sandreas.sandberg@arm.com *
514205Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall
614205Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual
714205Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating
814205Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software
914205Sandreas.sandberg@arm.com * licensed hereunder.  You may use the software subject to the license
1014205Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated
1114205Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software,
1214205Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form.
1314205Sandreas.sandberg@arm.com *
1414205Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without
1514205Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are
1614205Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright
1714205Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer;
1814205Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright
1914205Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the
2014205Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution;
2114205Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its
2214205Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from
2314205Sandreas.sandberg@arm.com * this software without specific prior written permission.
2414205Sandreas.sandberg@arm.com *
2514205Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2614205Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2714205Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2814205Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2914205Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3014205Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3114205Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3214205Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3314205Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3414205Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3514205Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3614205Sandreas.sandberg@arm.com *
3714205Sandreas.sandberg@arm.com * Authors: Andreas Sandberg
3814205Sandreas.sandberg@arm.com */
3914205Sandreas.sandberg@arm.com
4014205Sandreas.sandberg@arm.com#ifndef __BASE_STATS_GROUP_HH__
4114205Sandreas.sandberg@arm.com#define __BASE_STATS_GROUP_HH__
4214205Sandreas.sandberg@arm.com
4314205Sandreas.sandberg@arm.com#include <map>
4414205Sandreas.sandberg@arm.com#include <vector>
4514205Sandreas.sandberg@arm.com#include <string>
4614205Sandreas.sandberg@arm.com
4714205Sandreas.sandberg@arm.com/**
4814205Sandreas.sandberg@arm.com * Convenience macro to add a stat to a statistics group.
4914205Sandreas.sandberg@arm.com *
5014205Sandreas.sandberg@arm.com * This macro is used to add a stat to a Stats::Group in the
5114205Sandreas.sandberg@arm.com * initilization list in the Group's constructor. The macro
5214205Sandreas.sandberg@arm.com * automatically assigns the stat to the current group and gives it
5314205Sandreas.sandberg@arm.com * the same name as in the class. For example:
5414205Sandreas.sandberg@arm.com *
5514205Sandreas.sandberg@arm.com * \code
5614205Sandreas.sandberg@arm.com * struct MyStats : public Stats::Group
5714205Sandreas.sandberg@arm.com * {
5814205Sandreas.sandberg@arm.com *     Stats::Scalar scalar0;
5914205Sandreas.sandberg@arm.com *     Stats::Scalar scalar1;
6014205Sandreas.sandberg@arm.com *
6114205Sandreas.sandberg@arm.com *     Group()
6214205Sandreas.sandberg@arm.com *         : ADD_STAT(scalar0, "Description of scalar0"),
6314205Sandreas.sandberg@arm.com *           scalar1(this, "scalar1", "Description of scalar1")
6414205Sandreas.sandberg@arm.com *     {
6514205Sandreas.sandberg@arm.com *     }
6614205Sandreas.sandberg@arm.com * };
6714205Sandreas.sandberg@arm.com * \endcode
6814205Sandreas.sandberg@arm.com */
6914205Sandreas.sandberg@arm.com#define ADD_STAT(n, ...) n(this, # n, __VA_ARGS__)
7014205Sandreas.sandberg@arm.com
7114205Sandreas.sandberg@arm.comnamespace Stats {
7214205Sandreas.sandberg@arm.com
7314205Sandreas.sandberg@arm.comclass Info;
7414205Sandreas.sandberg@arm.com
7514205Sandreas.sandberg@arm.com/**
7614205Sandreas.sandberg@arm.com * Statistics container.
7714205Sandreas.sandberg@arm.com *
7814205Sandreas.sandberg@arm.com * A stat group is a hierarchical structure that contain statistics
7914205Sandreas.sandberg@arm.com * and other groups. Groups are used by the stat system to reflect
8014205Sandreas.sandberg@arm.com * gem5's SimObject hierarchy and to expose internal hierarchy within
8114205Sandreas.sandberg@arm.com * an object. They can also be used to conveniently group stats into
8214205Sandreas.sandberg@arm.com * their own class/struct and then be merged into the parent group
8314205Sandreas.sandberg@arm.com * (typically a SimObject).
8414205Sandreas.sandberg@arm.com */
8514205Sandreas.sandberg@arm.comclass Group
8614205Sandreas.sandberg@arm.com{
8714205Sandreas.sandberg@arm.com  public:
8814205Sandreas.sandberg@arm.com    Group() = delete;
8914205Sandreas.sandberg@arm.com    Group(const Group &) = delete;
9014205Sandreas.sandberg@arm.com    Group &operator=(const Group &) = delete;
9114205Sandreas.sandberg@arm.com
9214205Sandreas.sandberg@arm.com    /**
9314205Sandreas.sandberg@arm.com     * Construct a new statistics group.
9414205Sandreas.sandberg@arm.com     *
9514205Sandreas.sandberg@arm.com     * The constructor takes two parameters, a parent and a name. The
9614205Sandreas.sandberg@arm.com     * parent group should typically be specified. However, there are
9714205Sandreas.sandberg@arm.com     * special cases where the parent group may be null. One such
9814205Sandreas.sandberg@arm.com     * special case is SimObjects where the Python code performs late
9914205Sandreas.sandberg@arm.com     * binding of the group parent.
10014205Sandreas.sandberg@arm.com     *
10114205Sandreas.sandberg@arm.com     * If the name parameter is NULL, the group gets merged into the
10214205Sandreas.sandberg@arm.com     * parent group instead of creating a sub-group. Stats belonging
10314205Sandreas.sandberg@arm.com     * to a merged group behave as if they have been added directly to
10414205Sandreas.sandberg@arm.com     * the parent group.
10514205Sandreas.sandberg@arm.com     *
10614205Sandreas.sandberg@arm.com     * @param parent Parent group to associate this object to.
10714205Sandreas.sandberg@arm.com     * @param name Name of this group, can be NULL to merge this group
10814205Sandreas.sandberg@arm.com     * with the parent group.
10914205Sandreas.sandberg@arm.com     */
11014205Sandreas.sandberg@arm.com    Group(Group *parent, const char *name = nullptr);
11114205Sandreas.sandberg@arm.com
11214205Sandreas.sandberg@arm.com    virtual ~Group();
11314205Sandreas.sandberg@arm.com
11414205Sandreas.sandberg@arm.com    /**
11514205Sandreas.sandberg@arm.com     * Callback to set stat parameters.
11614205Sandreas.sandberg@arm.com     *
11714205Sandreas.sandberg@arm.com     * This callback is typically used for complex stats (e.g.,
11814205Sandreas.sandberg@arm.com     * distributions) that need parameters in addition to a name and a
11914205Sandreas.sandberg@arm.com     * description. Stat names and descriptions should typically be
12014205Sandreas.sandberg@arm.com     * set from the constructor usingo from the constructor using the
12114205Sandreas.sandberg@arm.com     * ADD_STAT macro.
12214205Sandreas.sandberg@arm.com     */
12314205Sandreas.sandberg@arm.com    virtual void regStats();
12414205Sandreas.sandberg@arm.com
12514205Sandreas.sandberg@arm.com    /**
12614205Sandreas.sandberg@arm.com     * Callback to reset stats.
12714205Sandreas.sandberg@arm.com     */
12814205Sandreas.sandberg@arm.com    virtual void resetStats();
12914205Sandreas.sandberg@arm.com
13014205Sandreas.sandberg@arm.com    /**
13114205Sandreas.sandberg@arm.com     * Register a stat with this group. This method is normally called
13214205Sandreas.sandberg@arm.com     * automatically when a stat is instantiated.
13314205Sandreas.sandberg@arm.com     */
13414205Sandreas.sandberg@arm.com    void addStat(Stats::Info *info);
13514205Sandreas.sandberg@arm.com
13614205Sandreas.sandberg@arm.com    /**
13714205Sandreas.sandberg@arm.com     * Get all child groups associated with this object.
13814205Sandreas.sandberg@arm.com     */
13914205Sandreas.sandberg@arm.com    const std::map<std::string, Group *> &getStatGroups() const;
14014205Sandreas.sandberg@arm.com
14114205Sandreas.sandberg@arm.com    /**
14214205Sandreas.sandberg@arm.com     * Get all stats associated with this object.
14314205Sandreas.sandberg@arm.com     */
14414205Sandreas.sandberg@arm.com    const std::vector<Info *> &getStats() const;
14514205Sandreas.sandberg@arm.com
14614205Sandreas.sandberg@arm.com     /**
14714205Sandreas.sandberg@arm.com     * Add a stat block as a child of this block
14814205Sandreas.sandberg@arm.com     *
14914205Sandreas.sandberg@arm.com     * This method may only be called from a Group constructor or from
15014205Sandreas.sandberg@arm.com     * regStats. It's typically only called explicitly from Python
15114205Sandreas.sandberg@arm.com     * when setting up the SimObject hierarchy.
15214205Sandreas.sandberg@arm.com     */
15314205Sandreas.sandberg@arm.com    void addStatGroup(const char *name, Group *block);
15414205Sandreas.sandberg@arm.com
15514205Sandreas.sandberg@arm.com  private:
15614205Sandreas.sandberg@arm.com    /**
15714205Sandreas.sandberg@arm.com     * Merge the contents (stats & children) of a block to this block.
15814205Sandreas.sandberg@arm.com     *
15914205Sandreas.sandberg@arm.com     * This is called on a parent group by the child when it is being
16014205Sandreas.sandberg@arm.com     * merged into the parent.
16114205Sandreas.sandberg@arm.com     */
16214205Sandreas.sandberg@arm.com    void mergeStatGroup(Group *block);
16314205Sandreas.sandberg@arm.com
16414205Sandreas.sandberg@arm.com  private:
16514205Sandreas.sandberg@arm.com    /** Parent pointer if merged into parent */
16614205Sandreas.sandberg@arm.com    Group *const mergedParent;
16714205Sandreas.sandberg@arm.com
16814205Sandreas.sandberg@arm.com    std::map<std::string, Group *> statGroups;
16914205Sandreas.sandberg@arm.com    std::vector<Group *> mergedStatGroups;
17014205Sandreas.sandberg@arm.com    std::vector<Info *> stats;
17114205Sandreas.sandberg@arm.com};
17214205Sandreas.sandberg@arm.com
17314205Sandreas.sandberg@arm.com} // namespace Stats
17414205Sandreas.sandberg@arm.com
17514205Sandreas.sandberg@arm.com#endif // __BASE_STATS_GROUP_HH__
176