Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: base/metrics/histogram_macros_internal.h

Issue 2361933002: Refactor histogram_macros.h. This improves documentation for the macros in the file, moves LOCAL_* … (Closed)
Patch Set: asvitkine Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef BASE_METRICS_HISTOGRAM_MACROS_INTERNAL_H_
6 #define BASE_METRICS_HISTOGRAM_MACROS_INTERNAL_H_
7
8 #include "base/atomicops.h"
9 #include "base/logging.h"
10 #include "base/metrics/histogram.h"
11 #include "base/time/time.h"
12
13 // TODO(rkaplow): Improve commenting of these methods.
Alexei Svitkine (slow) 2016/09/26 21:25:17 Please add a top level comment mentioning that the
rkaplow 2016/09/26 21:37:48 Done.
14
15 //------------------------------------------------------------------------------
16 // Histograms are often put in areas where they are called many many times, and
17 // performance is critical. As a result, they are designed to have a very low
18 // recurring cost of executing (adding additional samples). Toward that end,
19 // the macros declare a static pointer to the histogram in question, and only
20 // take a "slow path" to construct (or find) the histogram on the first run
21 // through the macro. We leak the histograms at shutdown time so that we don't
22 // have to validate using the pointers at any time during the running of the
23 // process.
24
25
26 // In some cases (integration into 3rd party code), it's useful to separate the
27 // definition of |atomic_histogram_pointer| from its use. To achieve this we
28 // define HISTOGRAM_POINTER_USE, which uses an |atomic_histogram_pointer|, and
29 // STATIC_HISTOGRAM_POINTER_BLOCK, which defines an |atomic_histogram_pointer|
30 // and forwards to HISTOGRAM_POINTER_USE.
31 #define HISTOGRAM_POINTER_USE(atomic_histogram_pointer, \
32 constant_histogram_name, \
33 histogram_add_method_invocation, \
34 histogram_factory_get_invocation) \
35 do { \
36 /* \
37 * Acquire_Load() ensures that we acquire visibility to the \
38 * pointed-to data in the histogram. \
39 */ \
40 base::HistogramBase* histogram_pointer( \
41 reinterpret_cast<base::HistogramBase*>( \
42 base::subtle::Acquire_Load(atomic_histogram_pointer))); \
43 if (!histogram_pointer) { \
44 /* \
45 * This is the slow path, which will construct OR find the \
46 * matching histogram. histogram_factory_get_invocation includes \
47 * locks on a global histogram name map and is completely thread \
48 * safe. \
49 */ \
50 histogram_pointer = histogram_factory_get_invocation; \
51 \
52 /* \
53 * Use Release_Store to ensure that the histogram data is made \
54 * available globally before we make the pointer visible. Several \
55 * threads may perform this store, but the same value will be \
56 * stored in all cases (for a given named/spec'ed histogram). \
57 * We could do this without any barrier, since FactoryGet entered \
58 * and exited a lock after construction, but this barrier makes \
59 * things clear. \
60 */ \
61 base::subtle::Release_Store( \
62 atomic_histogram_pointer, \
63 reinterpret_cast<base::subtle::AtomicWord>(histogram_pointer)); \
64 } \
65 if (DCHECK_IS_ON()) \
66 histogram_pointer->CheckName(constant_histogram_name); \
67 histogram_pointer->histogram_add_method_invocation; \
68 } while (0)
69
70 // This is a helper macro used by other macros and shouldn't be used directly.
71 // Defines the static |atomic_histogram_pointer| and forwards to
72 // HISTOGRAM_POINTER_USE.
73 #define STATIC_HISTOGRAM_POINTER_BLOCK(constant_histogram_name, \
74 histogram_add_method_invocation, \
75 histogram_factory_get_invocation) \
76 do { \
77 /* \
78 * The pointer's presence indicates that the initialization is complete. \
79 * Initialization is idempotent, so it can safely be atomically repeated. \
80 */ \
81 static base::subtle::AtomicWord atomic_histogram_pointer = 0; \
82 HISTOGRAM_POINTER_USE(&atomic_histogram_pointer, constant_histogram_name, \
83 histogram_add_method_invocation, \
84 histogram_factory_get_invocation); \
85 } while (0)
86
87 // This is a helper macro used by other macros and shouldn't be used directly.
88 #define INTERNAL_HISTOGRAM_CUSTOM_COUNTS_WITH_FLAG(name, sample, min, max, \
89 bucket_count, flag) \
90 STATIC_HISTOGRAM_POINTER_BLOCK( \
91 name, Add(sample), \
92 base::Histogram::FactoryGet(name, min, max, bucket_count, flag))
93
94 // This is a helper macro used by other macros and shouldn't be used directly.
95 // One additional bucket is created in the LinearHistogram for the illegal
96 // values >= boundary_value so that mistakes in calling the UMA enumeration
97 // macros can be detected.
98 #define INTERNAL_HISTOGRAM_ENUMERATION_WITH_FLAG(name, sample, boundary, flag) \
99 STATIC_HISTOGRAM_POINTER_BLOCK( \
100 name, Add(sample), \
101 base::LinearHistogram::FactoryGet( \
102 name, 1, boundary, boundary + 1, flag))
103
104 // This is a helper macro used by other macros and shouldn't be used directly.
105 // This is necessary to expand __COUNTER__ to an actual value.
106 #define INTERNAL_SCOPED_UMA_HISTOGRAM_TIMER_EXPANDER(name, is_long, key) \
107 INTERNAL_SCOPED_UMA_HISTOGRAM_TIMER_UNIQUE(name, is_long, key)
108
109 // This is a helper macro used by other macros and shouldn't be used directly.
110 #define INTERNAL_SCOPED_UMA_HISTOGRAM_TIMER_UNIQUE(name, is_long, key) \
Alexei Svitkine (slow) 2016/09/26 21:25:17 Reduce spaces to make \ fit in 80 cols. Same on li
rkaplow 2016/09/26 21:37:48 Done. Surprised the presubmit didn't catch this, i
111 class ScopedHistogramTimer##key { \
112 public: \
113 ScopedHistogramTimer##key() : constructed_(base::TimeTicks::Now()) {} \
114 ~ScopedHistogramTimer##key() { \
115 base::TimeDelta elapsed = base::TimeTicks::Now() - constructed_; \
116 if (is_long) { \
117 UMA_HISTOGRAM_LONG_TIMES_100(name, elapsed); \
118 } else { \
119 UMA_HISTOGRAM_TIMES(name, elapsed); \
120 } \
121 } \
122 private: \
123 base::TimeTicks constructed_; \
124 } scoped_histogram_timer_##key
125
126 #endif // BASE_METRICS_HISTOGRAM_MACROS_INTERNAL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698