// Copyright 2023 The Dawn & Tint Authors // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // // 2. 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. // // 3. Neither the name of the copyright holder 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 HOLDER 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. // This header provides macros for adding Chromium UMA histogram stats. // See the detailed description in the Chromium codebase: // https://source.chromium.org/chromium/chromium/src/+/main:base/metrics/histogram_macros.h #ifndef SRC_DAWN_PLATFORM_METRICS_HISTOGRAM_MACROS_H_ #define SRC_DAWN_PLATFORM_METRICS_HISTOGRAM_MACROS_H_ #include "dawn/platform/DawnPlatform.h" #include "dawn/platform/dawn_platform_export.h" #include "partition_alloc/pointers/raw_ptr.h" // Short timings - up to 10 seconds. #define DAWN_HISTOGRAM_TIMES(platform, name, sample_ms) … // Medium timings - up to 3 minutes. Note this starts at 10ms (no good reason, // but not worth changing). #define DAWN_HISTOGRAM_MEDIUM_TIMES(platform, name, sample_ms) … // Long timings - up to an hour. #define DAWN_HISTOGRAM_LONG_TIMES(platform, name, sample_ms) … // Use this macro when times can routinely be much longer than 10 seconds and #define DAWN_HISTOGRAM_LONG_TIMES_100(platform, name, sample_ms) … // This can be used when the default ranges are not sufficient. This macro lets // the metric developer customize the min and max of the sampled range, as well // as the number of buckets recorded. #define DAWN_HISTOGRAM_CUSTOM_TIMES(platform, name, sample_ms, min, max, bucket_count) … // Same as DAWN_HISTOGRAM_CUSTOM_TIMES but reports |sample| in microseconds, // dropping the report if this client doesn't have a high-resolution clock. #define DAWN_HISTOGRAM_CUSTOM_MICROSECOND_TIMES(platform, name, sample_us, min, max, bucket_count) … //------------------------------------------------------------------------------ // Count histograms. These are used for collecting numeric data. Note that we // have macros for more specialized use cases below (memory, time, percentages). // The number suffixes here refer to the max size of the sample, i.e. COUNT_1000 // will be able to collect samples of counts up to 1000. The default number of // buckets in all default macros is 50. We recommend erring on the side of too // large a range versus too short a range. // These macros default to exponential histograms - i.e. the lengths of the // bucket ranges exponentially increase as the sample range increases. // These should *not* be used if you are interested in exact counts, i.e. a // bucket range of 1. In these cases, you should use the ENUMERATION macros // defined later. These should also not be used to capture the number of some // event, i.e. "button X was clicked N times". In this cases, an enum should be // used, ideally with an appropriate baseline enum entry included. // All of these macros must be called with |name| as a runtime constant. // Used for capturing generic numeric data, from 1 to 1 million. #define DAWN_HISTOGRAM_COUNTS(platform, name, sample) … // Used for capturing generic numeric data, from 1 to 100. #define DAWN_HISTOGRAM_COUNTS_100(platform, name, sample) … // Used for capturing generic numeric data, from 1 to 10,000. #define DAWN_HISTOGRAM_COUNTS_10000(platform, name, sample) … // This macro allows the min, max, and number of buckets to be customized. Any // samples whose values are outside of [min, exclusive_max-1] are put in the // underflow or overflow buckets. Note that |min| should be >=1 as emitted 0s go // into the underflow bucket. #define DAWN_HISTOGRAM_CUSTOM_COUNTS(platformObj, name, sample, min, max, bucket_count) … // Same as DAWN_HISTOGRAM_CUSTOM_COUNTS, but the stat will be dropped if the // client does not support high-performance counters (HPC). Useful for logging // microsecond-resolution timings. #define DAWN_HISTOGRAM_CUSTOM_COUNTS_HPC(platformObj, name, sample, min, max, bucket_count) … // Used for capturing basic percentages. This will be 100 buckets of size 1. #define DAWN_HISTOGRAM_PERCENTAGE(platform, name, percent_as_int) … // Histogram for boolean values. #define DAWN_HISTOGRAM_BOOLEAN(platformObj, name, true_or_false) … // Histogram for enumeration values. #define DAWN_HISTOGRAM_ENUMERATION(platformObj, name, enum_value, enum_boundary_value) … // Used to measure common KB-granularity memory stats. Range is up to 500000KB - // approximately 500M. #define DAWN_HISTOGRAM_MEMORY_KB(platform, name, sample_kb) … // MB-granularity memory metric. This has a short max (1G). #define DAWN_HISTOGRAM_MEMORY_MB(platform, name, sample_mb) … // Used to measure common MB-granularity memory stats. Range is up to 4000MiB - // approximately 4GiB. #define DAWN_HISTOGRAM_MEMORY_MEDIUM_MB(name, sample_mb) … // Used to measure common MB-granularity memory stats. Range is up to ~64G. #define DAWN_HISTOGRAM_MEMORY_LARGE_MB(name, sample_mb) … // Sparse histograms are well suited for recording counts of exact sample values // that are sparsely distributed over a relatively large range, in cases where // ultra-fast performance is not critical. For instance, Sqlite.Version.* are // sparse because for any given database, there's going to be exactly one // version logged. // // For important details on performance, data size, and usage, see the // documentation on the regular function equivalents (histogram_functions.h). #define DAWN_HISTOGRAM_SPARSE(platformObj, name, sparse_sample) … namespace dawn::detail { enum class ScopedHistogramTiming { … }; } // Scoped class which logs its time on this earth as a UMA statistic. This is // recommended for when you want a histogram which measures the time it takes // for a method to execute. This measures up to 10 seconds. #define SCOPED_DAWN_HISTOGRAM_TIMER(platform, name) … // Similar scoped histogram timer, but this uses DAWN_HISTOGRAM_LONG_TIMES_100, // which measures up to an hour, and uses 100 buckets. This is more expensive // to store, so only use if this often takes >10 seconds. #define SCOPED_DAWN_HISTOGRAM_LONG_TIMER(platform, name) … // Similar scoped histogram timer, but this uses // DAWN_HISTOGRAM_CUSTOM_MICROSECOND_TIMES, measuring from 1 microseconds to 1 second, // with 50 buckets. #define SCOPED_DAWN_HISTOGRAM_TIMER_MICROS(platform, name) … // This nested macro is necessary to expand __COUNTER__ to an actual value. #define SCOPED_DAWN_HISTOGRAM_TIMER_EXPANDER(platform, name, timing, key) … // This is a helper macro used by other macros and shouldn't be used directly. #define SCOPED_DAWN_HISTOGRAM_TIMER_UNIQUE(platform, name, timing, key) … namespace dawn::platform::metrics { // Timer class that gives more flexibility for recording over the macros when there may be // conditionals on the name or whether to record at all. class DAWN_PLATFORM_EXPORT DawnHistogramTimer { … }; } // namespace dawn::platform::metrics #endif // SRC_DAWN_PLATFORM_METRICS_HISTOGRAM_MACROS_H_