chromium/components/subresource_filter/core/common/time_measurements.h

// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file provides tools for measuring time intervals and reporting them to
// UMA histograms.
// WARNING: *UMA_HISTOGRAM_* macros in this file are not thread-safe.
// See also: "base/metrics/histogram_macros*.h".
//
// TODO(pkalinnikov): Consider moving content of this file to "base/metrics/*"
// after some refactoring. Note that most of the code generated by the macros
// below is not thread-safe.

#ifndef COMPONENTS_SUBRESOURCE_FILTER_CORE_COMMON_TIME_MEASUREMENTS_H_
#define COMPONENTS_SUBRESOURCE_FILTER_CORE_COMMON_TIME_MEASUREMENTS_H_

#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram.h"
#include "base/time/time.h"
#include "components/subresource_filter/core/common/scoped_timers.h"

namespace subresource_filter {

// Creates a scoped object that measures its lifetime using base::ThreadTicks,
// and reports the result in milliseconds as a UMA statistic to a histogram with
// the provided |name| which is expected to be a runtime constant. The histogram
// collects times up to 10 seconds in 50 buckets.
//
// Under the hood there is a static base::HistogramBase* pointer initialized
// right before the scoped object. The pointer is used by a specific
// |export_functor| passed in to a SCOPED_THREAD_TIMER (see it above).
//
// Example:
//   void Function() {
//     SCOPED_UMA_HISTOGRAM_THREAD_TIMER("Component.FunctionTime");
//     ... Useful things happen here ...
//   }
//
// WARNING: The generated code is not thread-safe.
#define SCOPED_UMA_HISTOGRAM_THREAD_TIMER(name)

// Similar to SCOPED_UMA_HISTOGRAM_THREAD_TIMER above, but the histogram
// collects times in microseconds, up to 1 second, and using 50 buckets.
//
// WARNING: The generated code is not thread-safe.
#define SCOPED_UMA_HISTOGRAM_MICRO_THREAD_TIMER(name)

// Similar to SCOPED_UMA_HISTOGRAM_TIMER in "base/metrics/histogram_macros.h",
// but the histogram stores times in microseconds, up to 1 second, in 50
// buckets.
//
// WARNING: The generated code is not thread-safe.
#define SCOPED_UMA_HISTOGRAM_MICRO_TIMER(name)

// Similar to UMA_HISTOGRAM_TIMES in "base/metrics/histogram_macros.h", but
// the histogram stores times in microseconds, up to 1 second, in 50 buckets.
//
// WARNING: The generated code is not thread-safe.
#define UMA_HISTOGRAM_MICRO_TIMES(name, sample)

// 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 UMA_HISTOGRAM_CUSTOM_MICRO_TIMES(name, sample, min, max, bucket_count)

// -----------------------------------------------------------------------------
// Below are helpers used by other macros. Shouldn't be used directly. ---------

// This is necessary to expand __COUNTER__ to an actual value.
#define IMPL_SCOPED_UMA_HISTOGRAM_TIMER_EXPANDER(               \
    name, time_provider, histogram_exporter, max_value, suffix)

// Creates a static histogram pointer and a scoped object referring to it
// throught the |histogram_exporter| functor. Both the pointer and the scoped
// object are uniquely-named, using the unique |suffix| passed in.
#define IMPL_SCOPED_UMA_HISTOGRAM_TIMER_UNIQUE(                            \
    name, time_provider, histogram_exporter, max_value, suffix)

// This is necessary to expand __COUNTER__ to an actual value.
#define IMPL_UMA_HISTOGRAM_MICRO_TIMES_EXPANDER(name, max_value, suffix, \
                                                sample)

// Defines a static UMA histogram pointer and writes a |sample| to it.
#define IMPL_UMA_HISTOGRAM_ADD(name, sample, min, max, bucket_count)

// Defines a static pointer to a UMA histogram.
//
// WARNING: Static local variable initialization is deliberately *not*
// thread-safe in Chrome builds. See the "-fno-threadsafe-statics" flag in
// "build/config/compiler/BUILD.gn" and "/Zc:threadSafeInit-" in
// "build/config/win/BUILD.gn" for details.
#define IMPL_DEFINE_STATIC_UMA_HISTOGRAM_POINTER(name, min, max, bucket_count, \
                                                 suffix)

namespace impl {

// ExportFunctor implementation that puts measurements into a UMA |histogram|.
template <bool is_microsec_precision>
class ExportTimeDeltaToHistogram {};

ExportMillisecondsToHistogram;
ExportMicrosecondsToHistogram;

}  // namespace impl

// Classes for scoped thread timers --------------------------------------------

// Creates a scoped object that measures its lifetime using base::ThreadTicks,
// and reports the result in milliseconds as a UMA statistic to a histogram with
// the provided `name` which is expected to be a runtime constant. The histogram
// collects times up to 10 seconds in 50 buckets.
//
// Example:
//   void Function() {
//     auto scoped_timer =
//       ScopedUmaHistogramThreadTimer("Component.FunctionTime");
//     ... Useful things happen here ...
//   }
//
// WARNING: The generated code is not thread-safe.
class ScopedUmaHistogramThreadTimer {};

// Creates a scoped object that measures its lifetime using base::ThreadTicks,
// and reports the result in milliseconds as a UMA statistic to a histogram with
// the provided `name` which is expected to be a runtime constant.
//
// Similar to ScopedUmaHistogramThreadTimer above, but the histogram
// collects times in microseconds, up to 1 second, and using 50 buckets.
//
// Example:
//   void Function() {
//     auto scoped_timer =
//       ScopedUmaHistogramMicroThreadTimer("Component.FunctionTime");
//     ... Useful things happen here ...
//   }
//
// WARNING: The generated code is not thread-safe.
class ScopedUmaHistogramMicroThreadTimer {};

}  // namespace subresource_filter

#endif  // COMPONENTS_SUBRESOURCE_FILTER_CORE_COMMON_TIME_MEASUREMENTS_H_