From e59557af500d1633b1f41b023d6c072acaf145a0 Mon Sep 17 00:00:00 2001 From: "Daniel R. Carvalho" Date: Wed, 5 Feb 2020 09:46:18 +0100 Subject: [PATCH] base: Move Stats::Info functions to its own source file Move information needed by Stats::Info and its derived classes from base/statistics.cc to its own source file. Create a SConscript in the stats sub-dir to start clustering stats related files. Change-Id: I1e5e828c7814748c2582755f664550241caf860e Signed-off-by: Daniel R. Carvalho Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/25424 Reviewed-by: Bobby R. Bruce Maintainer: Bobby R. Bruce Tested-by: kokoro --- src/base/SConscript | 8 -- src/base/statistics.cc | 177 +----------------------------- src/base/statistics.hh | 5 - src/base/stats/SConscript | 40 +++++++ src/base/stats/info.cc | 222 ++++++++++++++++++++++++++++++++++++++ src/base/stats/info.hh | 3 + 6 files changed, 267 insertions(+), 188 deletions(-) create mode 100644 src/base/stats/SConscript create mode 100644 src/base/stats/info.cc diff --git a/src/base/SConscript b/src/base/SConscript index ff32166f8..f8cd4ba07 100644 --- a/src/base/SConscript +++ b/src/base/SConscript @@ -80,14 +80,6 @@ Source('types.cc') GTest('types.test', 'types.test.cc', 'types.cc') GTest('uncontended_mutex.test', 'uncontended_mutex.test.cc') -Source('stats/group.cc') -Source('stats/text.cc') -if env['USE_HDF5']: - if main['GCC']: - Source('stats/hdf5.cc', append={'CXXFLAGS': '-Wno-deprecated-copy'}) - else: - Source('stats/hdf5.cc') - GTest('addr_range.test', 'addr_range.test.cc') GTest('addr_range_map.test', 'addr_range_map.test.cc') GTest('bitunion.test', 'bitunion.test.cc') diff --git a/src/base/statistics.cc b/src/base/statistics.cc index f59fe1ce7..80c71abf7 100644 --- a/src/base/statistics.cc +++ b/src/base/statistics.cc @@ -40,26 +40,18 @@ #include "base/statistics.hh" -#include -#include +#include #include #include #include +#include #include "base/callback.hh" -#include "base/cprintf.hh" -#include "base/debug.hh" -#include "base/hostinfo.hh" #include "base/logging.hh" -#include "base/str.hh" -#include "base/time.hh" -#include "base/trace.hh" #include "sim/root.hh" namespace Stats { -std::string Info::separatorString = "::"; - // We wrap these in a function to make sure they're built in time. std::list & statsList() @@ -143,171 +135,6 @@ StorageParams::~StorageParams() { } -NameMapType & -nameMap() -{ - static NameMapType the_map; - return the_map; -} - -int Info::id_count = 0; - -int debug_break_id = -1; - -Info::Info() - : flags(none), precision(-1), prereq(0), storageParams(NULL) -{ - id = id_count++; - if (debug_break_id >= 0 and debug_break_id == id) - Debug::breakpoint(); -} - -Info::~Info() -{ -} - -bool -validateStatName(const std::string &name) -{ - if (name.empty()) - return false; - - std::vector vec; - tokenize(vec, name, '.'); - std::vector::const_iterator item = vec.begin(); - while (item != vec.end()) { - if (item->empty()) - return false; - - std::string::const_iterator c = item->begin(); - - // The first character is different - if (!isalpha(*c) && *c != '_') - return false; - - // The rest of the characters have different rules. - while (++c != item->end()) { - if (!isalnum(*c) && *c != '_') - return false; - } - - ++item; - } - - return true; -} - -void -Info::setName(const std::string &name) -{ - setName(nullptr, name); -} - -void -Info::setName(const Group *parent, const std::string &name) -{ - if (!validateStatName(name)) - panic("invalid stat name '%s'", name); - - // We only register the stat with the nameMap() if we are using - // old-style stats without a parent group. New-style stats should - // be unique since their names should correspond to a member - // variable. - if (!parent) { - auto p = nameMap().insert(make_pair(name, this)); - - if (!p.second) - panic("same statistic name used twice! name=%s\n", - name); - } - - this->name = name; -} - -bool -Info::less(Info *stat1, Info *stat2) -{ - const std::string &name1 = stat1->name; - const std::string &name2 = stat2->name; - - std::vector v1; - std::vector v2; - - tokenize(v1, name1, '.'); - tokenize(v2, name2, '.'); - - size_type last = std::min(v1.size(), v2.size()) - 1; - for (off_type i = 0; i < last; ++i) - if (v1[i] != v2[i]) - return v1[i] < v2[i]; - - // Special compare for last element. - if (v1[last] == v2[last]) - return v1.size() < v2.size(); - else - return v1[last] < v2[last]; - - return false; -} - -bool -Info::baseCheck() const -{ - if (!(flags & Stats::init)) { -#ifdef DEBUG - cprintf("this is stat number %d\n", id); -#endif - panic("Not all stats have been initialized.\n" - "You may need to add ::regStats() to a" - " new SimObject's regStats() function. Name: %s", - name); - return false; - } - - if ((flags & display) && name.empty()) { - panic("all printable stats must be named"); - return false; - } - - return true; -} - -void -Info::enable() -{ -} - -void -VectorInfo::enable() -{ - size_type s = size(); - if (subnames.size() < s) - subnames.resize(s); - if (subdescs.size() < s) - subdescs.resize(s); -} - -void -VectorDistInfo::enable() -{ - size_type s = size(); - if (subnames.size() < s) - subnames.resize(s); - if (subdescs.size() < s) - subdescs.resize(s); -} - -void -Vector2dInfo::enable() -{ - if (subnames.size() < x) - subnames.resize(x); - if (subdescs.size() < x) - subdescs.resize(x); - if (y_subnames.size() < y) - y_subnames.resize(y); -} - void HistStor::grow_out() { diff --git a/src/base/statistics.hh b/src/base/statistics.hh index 7115b88f3..20544c2a1 100644 --- a/src/base/statistics.hh +++ b/src/base/statistics.hh @@ -3414,11 +3414,6 @@ std::list &statsList(); typedef std::map MapType; MapType &statsMap(); -typedef std::map NameMapType; -NameMapType &nameMap(); - -bool validateStatName(const std::string &name); - } // namespace Stats void debugDumpStats(); diff --git a/src/base/stats/SConscript b/src/base/stats/SConscript new file mode 100644 index 000000000..953999c13 --- /dev/null +++ b/src/base/stats/SConscript @@ -0,0 +1,40 @@ +# -*- mode:python -*- +# +# Copyright (c) 2021 Daniel R. Carvalho +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Import('*') + +Source('group.cc') +Source('info.cc') +Source('text.cc') + +if env['USE_HDF5']: + if main['GCC']: + Source('hdf5.cc', append={'CXXFLAGS': '-Wno-deprecated-copy'}) + else: + Source('hdf5.cc') + diff --git a/src/base/stats/info.cc b/src/base/stats/info.cc new file mode 100644 index 000000000..b2ad86b68 --- /dev/null +++ b/src/base/stats/info.cc @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2021 Daniel R. Carvalho + * Copyright (c) 2019 Arm Limited + * All rights reserved. + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "base/stats/info.hh" + +#include +#include +#include + +#include "base/cprintf.hh" +#include "base/debug.hh" +#include "base/logging.hh" +#include "base/str.hh" + +namespace Stats { + +std::string Info::separatorString = "::"; + +int Info::id_count = 0; + +int debug_break_id = -1; + +NameMapType & +nameMap() +{ + static NameMapType the_map; + return the_map; +} + +Info::Info() + : flags(none), precision(-1), prereq(0), storageParams(NULL) +{ + id = id_count++; + if (debug_break_id >= 0 and debug_break_id == id) + Debug::breakpoint(); +} + +Info::~Info() +{ +} + +bool +validateStatName(const std::string &name) +{ + if (name.empty()) + return false; + + std::vector vec; + tokenize(vec, name, '.'); + std::vector::const_iterator item = vec.begin(); + while (item != vec.end()) { + if (item->empty()) + return false; + + std::string::const_iterator c = item->begin(); + + // The first character is different + if (!isalpha(*c) && *c != '_') + return false; + + // The rest of the characters have different rules. + while (++c != item->end()) { + if (!isalnum(*c) && *c != '_') + return false; + } + + ++item; + } + + return true; +} + +void +Info::setName(const std::string &name) +{ + setName(nullptr, name); +} + +void +Info::setName(const Group *parent, const std::string &name) +{ + if (!validateStatName(name)) + panic("invalid stat name '%s'", name); + + // We only register the stat with the nameMap() if we are using + // old-style stats without a parent group. New-style stats should + // be unique since their names should correspond to a member + // variable. + if (!parent) { + auto p = nameMap().insert(make_pair(name, this)); + + if (!p.second) + panic("same statistic name used twice! name=%s\n", + name); + } + + this->name = name; +} + +bool +Info::less(Info *stat1, Info *stat2) +{ + const std::string &name1 = stat1->name; + const std::string &name2 = stat2->name; + + std::vector v1; + std::vector v2; + + tokenize(v1, name1, '.'); + tokenize(v2, name2, '.'); + + size_type last = std::min(v1.size(), v2.size()) - 1; + for (off_type i = 0; i < last; ++i) + if (v1[i] != v2[i]) + return v1[i] < v2[i]; + + // Special compare for last element. + if (v1[last] == v2[last]) + return v1.size() < v2.size(); + else + return v1[last] < v2[last]; + + return false; +} + +bool +Info::baseCheck() const +{ + if (!(flags & Stats::init)) { +#ifdef DEBUG + cprintf("this is stat number %d\n", id); +#endif + panic("Not all stats have been initialized.\n" + "You may need to add ::regStats() to a" + " new SimObject's regStats() function. Name: %s", + name); + return false; + } + + if ((flags & display) && name.empty()) { + panic("all printable stats must be named"); + return false; + } + + return true; +} + +void +Info::enable() +{ +} + +void +VectorInfo::enable() +{ + size_type s = size(); + if (subnames.size() < s) + subnames.resize(s); + if (subdescs.size() < s) + subdescs.resize(s); +} + +void +VectorDistInfo::enable() +{ + size_type s = size(); + if (subnames.size() < s) + subnames.resize(s); + if (subdescs.size() < s) + subdescs.resize(s); +} + +void +Vector2dInfo::enable() +{ + if (subnames.size() < x) + subnames.resize(x); + if (subdescs.size() < x) + subdescs.resize(x); + if (y_subnames.size() < y) + y_subnames.resize(y); +} + +} // namespace Stats diff --git a/src/base/stats/info.hh b/src/base/stats/info.hh index ad34b3916..d9a66548d 100644 --- a/src/base/stats/info.hh +++ b/src/base/stats/info.hh @@ -255,6 +255,9 @@ class SparseHistInfo : public Info SparseHistData data; }; +typedef std::map NameMapType; +NameMapType &nameMap(); + } // namespace Stats #endif // __BASE_STATS_INFO_HH__ -- 2.30.2