/* * Copyright (c) 2021 The Regents of the University of California. * 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. */ #ifndef __BASE_STATS_UNITS_HH__ #define __BASE_STATS_UNITS_HH__ #include #include "base/compiler.hh" #include "base/cprintf.hh" namespace gem5 { /** * Convenience macros to declare the unit of a stat. */ #define UNIT_CYCLE GEM5_DEPRECATED_MACRO( \ UNIT_CYCLE, statistics::units::Cycle::get(), \ "Use statistics::units::Cycle::get()") #define UNIT_TICK GEM5_DEPRECATED_MACRO( \ UNIT_TICK, statistics::units::Tick::get(), "Use statistics::units::Tick::get()") #define UNIT_SECOND GEM5_DEPRECATED_MACRO( \ UNIT_SECOND, statistics::units::Second::get(), \ "Use statistics::units::Second::get()") #define UNIT_BIT GEM5_DEPRECATED_MACRO( \ UNIT_BIT, statistics::units::Bit::get(), "Use statistics::units::Bit::get()") #define UNIT_BYTE GEM5_DEPRECATED_MACRO( \ UNIT_BYTE, statistics::units::Byte::get(), "Use statistics::units::Byte::get()") #define UNIT_JOULE GEM5_DEPRECATED_MACRO( \ UNIT_JOULE, statistics::units::Joule::get(), \ "Use statistics::units::Joule::get()") #define UNIT_VOLT GEM5_DEPRECATED_MACRO( \ UNIT_VOLD, statistics::units::Volt::get(), "Use statistics::units::Volt::get()") #define UNIT_CELSIUS GEM5_DEPRECATED_MACRO( \ UNIT_CELSIUS, statistics::units::DegreeCelsius::get(), \ "Use statistics::units::DegreeCelsius::get()") #define UNIT_RATE(T1, T2) GEM5_DEPRECATED_MACRO( \ UNIT_RATE, (statistics::units::Rate::get()), \ "Use statistics::units::Rate::get()") #define UNIT_RATIO GEM5_DEPRECATED_MACRO( \ UNIT_RATIO, statistics::units::Ratio::get(), \ "Use statistics::units::Ratio::get()") #define UNIT_COUNT GEM5_DEPRECATED_MACRO( \ UNIT_COUNT, statistics::units::Count::get(), \ "Use statistics::units::Count::get()") #define UNIT_WATT GEM5_DEPRECATED_MACRO( \ UNIT_WATT, statistics::units::Watt::get(), "Use statistics::units::Watt::get()") #define UNIT_UNSPECIFIED GEM5_DEPRECATED_MACRO( \ UNIT_UNSPECIFIED, statistics::units::Unspecified::get(), \ "Use statistics::units::Unspecified::get()") GEM5_DEPRECATED_NAMESPACE(Stats, statistics); namespace statistics { /** * Units for Stats. * * This header file provides an ability to associate a stat object with a * specific unit. * * The supported units are: * - Cycle: represents clock cycles. * - Tick: represents the count of gem5's Tick. * - Second: represents the base unit of time defined by SI. * - Bit: represents the number of computer bits. * - Byte: represents 8 bits. * - Volt: a SI derived unit measuring potential difference. * - Joule: represents joule, a unit of energy, as defined by SI. * - Watt: represents 1 watt, where 1 watt = 1 joule / second. * - Celsius: represents 1 Celsius degree as defined by SI. * - Rate(T1, T2): represents the unit of a quantity of T1 divided by * a quantity of T2. * - Ratio: represents the unit of a quantity of unit T divided by a quantity * of T. * - Count: represents the count of a quantity that is not defined above. * - Unspecified: the unit of the stat is unspecified. * * Each unit class is intended to be a singleton, which means only each unit * class has at most one object of that class exist throughout the program. * Therefore, copy constructors and assignment operators are deleted functions. * * When any of the following criteria is met, a new unit should be added, * - The new unit is significant enough to be not included in Count unit. * (e.g. Cycle unit, Tick unit) */ GEM5_DEPRECATED_NAMESPACE(Units, units); namespace units { /** * The Base class is the parent class of all unit classes. * This class is intended to an abstract class specifying common behaviors of * all unit classes. */ class Base { public: virtual std::string getUnitString() const = 0; }; class Cycle : public Base { private: Cycle() {} public: Cycle(Cycle const&) = delete; void operator=(Cycle const&) = delete; static Cycle* get() { static Cycle instance; return &instance; } static std::string toString() { return "Cycle"; } std::string getUnitString() const override { return Cycle::toString(); } }; class Tick : public Base { private: Tick() {} public: Tick(Tick const&) = delete; void operator=(Tick const&) = delete; static Tick* get() { static Tick instance; return &instance; } static std::string toString() { return "Tick"; } std::string getUnitString() const override { return Tick::toString(); } }; class Second : public Base { private: Second() {} public: Second(Second const&) = delete; void operator=(Second const&) = delete; static Second* get() { static Second instance; return &instance; } static std::string toString() { return "Second"; } std::string getUnitString() const override { return Second::toString(); } }; class Bit : public Base { private: Bit() {} public: Bit(Bit const&) = delete; void operator=(Bit const&) = delete; static Bit* get() { static Bit instance; return &instance; } static std::string toString() { return "Bit"; } std::string getUnitString() const override { return Bit::toString(); } }; class Byte : public Base { private: Byte() {} public: Byte(Byte const&) = delete; void operator=(Byte const&) = delete; static Byte* get() { static Byte instance; return &instance; } static std::string toString() { return "Byte"; } std::string getUnitString() const override { return Byte::toString(); } }; class Watt : public Base { private: Watt() {} public: Watt(Watt const&) = delete; void operator=(Watt const&) = delete; static Watt* get() { static Watt instance; return &instance; } static std::string toString() { return "Watt"; } std::string getUnitString() const override { return Watt::toString(); } }; class Joule : public Base { private: Joule() {} public: Joule(Joule const&) = delete; void operator=(Joule const&) = delete; static Joule* get() { static Joule instance; return &instance; } static std::string toString() { return "Joule"; } std::string getUnitString() const override { return Joule::toString(); } }; class Volt : public Base { private: Volt() {} public: Volt(Volt const&) = delete; void operator=(Volt const&) = delete; static Volt* get() { static Volt instance; return &instance; } static std::string toString() { return "Volt"; } std::string getUnitString() const override { return Volt::toString(); } }; class DegreeCelsius : public Base { private: DegreeCelsius() {} public: DegreeCelsius(DegreeCelsius const&) = delete; void operator=(DegreeCelsius const&) = delete; static DegreeCelsius* get() { static DegreeCelsius instance; return &instance; } static std::string toString() { return "Celsius"; } std::string getUnitString() const override { return DegreeCelsius::toString(); } }; class Count : public Base { private: Count() {} public: Count(Count const&) = delete; void operator=(Count const&) = delete; static Count* get() { static Count instance; return &instance; } static std::string toString() { return "Count"; } std::string getUnitString() const override { return Count::toString(); } }; class Ratio : public Base { private: Ratio() {} public: Ratio(Ratio const&) = delete; void operator=(Ratio const&) = delete; static Ratio* get() { static Ratio instance; return &instance; } static std::string toString() { return "Ratio"; } std::string getUnitString() const override { return Ratio::toString(); } }; class Unspecified : public Base { private: Unspecified() {} public: Unspecified(Unspecified const&) = delete; void operator=(Unspecified const&) = delete; static Unspecified* get() { static Unspecified instance; return &instance; } static std::string toString() { return "Unspecified"; } std::string getUnitString() const override { return Unspecified::toString(); } }; template class Rate : public Base { static_assert(std::is_base_of::value, "Rate(T1,T2) must have " "T1 and T2 derived from statistics::units::Base"); static_assert(std::is_base_of::value, "Rate(T1,T2) must have " "T1 and T2 derived from statistics::units::Base"); static_assert(!std::is_same::value || std::is_same::value || std::is_same::value, "Rate(T1,T2) must have T1 and T2 of different types; " "otherwise, it would be a Ratio"); private: Rate() {} public: Rate(Rate const&) = delete; void operator=(Rate const&) = delete; static Rate* get() { static Rate instance; return &instance; } static std::string toString() { return csprintf("(%s/%s)", T1::toString(), T2::toString()); } std::string getUnitString() const override { return Rate::toString(); } }; } // namespace units } // namespace statistics } // namespace gem5 #endif // __BASE_STATS_UNITS_HH__