Fix emulator build error
[platform/framework/web/chromium-efl.git] / base / profiler / sample_metadata.h
1 // Copyright 2019 The Chromium Authors
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_PROFILER_SAMPLE_METADATA_H_
6 #define BASE_PROFILER_SAMPLE_METADATA_H_
7
8 #include "base/base_export.h"
9 #include "base/profiler/metadata_recorder.h"
10 #include "base/strings/string_piece.h"
11 #include "base/threading/platform_thread.h"
12 #include "third_party/abseil-cpp/absl/types/optional.h"
13
14 // -----------------------------------------------------------------------------
15 // Usage documentation
16 // -----------------------------------------------------------------------------
17 //
18 // Overview:
19 // These functions provide a means to control the metadata attached to samples
20 // collected by the stack sampling profiler. SampleMetadataScope controls the
21 // scope covered by the metadata (thread, process).
22 //
23 // Any samples collected by the sampling profiler will include the active
24 // metadata. This enables us to later analyze targeted subsets of samples
25 // (e.g. those collected during paint or layout).
26 //
27 // For example:
28 //
29 //   void DidStartLoad() {
30 //     is_loading_metadata_.Set(1);
31 //   }
32 //
33 //   void DidFinishLoad() {
34 //     is_loading_metadata_.Remove();
35 //   }
36 //
37 //   base::SampleMetadata is_loading_metadata_;
38 //
39 // Alternatively, ScopedSampleMetadata can be used to ensure that the metadata
40 // is removed correctly.
41 //
42 // For example:
43 //
44 //   void DoExpensiveWork() {
45 //     base::ScopedSampleMetadata metadata("xyz", 1);
46 //     if (...) {
47 //       ...
48 //       if (...) {
49 //         ...
50 //         return;
51 //       }
52 //     }
53 //     ...
54 //   }
55
56 namespace base {
57
58 class TimeTicks;
59
60 enum class SampleMetadataScope {
61   // All threads in the current process will have the associated metadata
62   // attached to their samples.
63   kProcess,
64   // The metadata will only be attached to samples for the current thread.
65   kThread
66 };
67
68 class BASE_EXPORT SampleMetadata {
69  public:
70   // Set the metadata value associated with |name| to be recorded for |scope|.
71   explicit SampleMetadata(StringPiece name, SampleMetadataScope scope);
72
73   SampleMetadata(const SampleMetadata&) = default;
74   ~SampleMetadata() = default;
75
76   SampleMetadata& operator=(const SampleMetadata&) = delete;
77
78   // Set the metadata value associated with |name| in the process-global stack
79   // sampling profiler metadata, overwriting any previous value set for that
80   // |name|.
81   void Set(int64_t value);
82
83   // Set the metadata value associated with the pair (|name|, |key|) in the
84   // process-global stack sampling profiler metadata, overwriting any previous
85   // value set for that (|name|, |key|) pair. This constructor allows the
86   // metadata to be associated with an additional user-defined key. One might
87   // supply a key based on the frame id, for example, to distinguish execution
88   // in service of scrolling between different frames. Prefer the previous
89   // function if no user-defined metadata is required. Note: values specified
90   // for a name and key are stored separately from values specified with only a
91   // name.
92   void Set(int64_t key, int64_t value);
93
94   // Removes the metadata item with the specified name from the process-global
95   // stack sampling profiler metadata.
96   //
97   // If such an item doesn't exist, this has no effect.
98   void Remove();
99
100   // Removes the metadata item with the specified (|name|, |key|) pair from the
101   // process-global stack sampling profiler metadata. This function does not
102   // alter values set with the name |name| but no key.
103   //
104   // If such an item doesn't exist, this has no effect.
105   void Remove(int64_t key);
106
107  private:
108   const uint64_t name_hash_;
109   // Scope is kept as-is instead of retrieving a PlatformThreadId in case
110   // Set()/Remove() is called on a thread different from where the object was
111   // constructed.
112   const SampleMetadataScope scope_;
113 };
114
115 class BASE_EXPORT ScopedSampleMetadata {
116  public:
117   // Set the metadata value associated with |name| for |scope|.
118   ScopedSampleMetadata(StringPiece name,
119                        int64_t value,
120                        SampleMetadataScope scope);
121
122   // Set the metadata value associated with the pair (|name|, |key|) for
123   // |scope|. This constructor allows the metadata to be associated with an
124   // additional user-defined key. One might supply a key based on the frame id,
125   // for example, to distinguish execution in service of scrolling between
126   // different frames. Prefer the previous constructor if no user-defined
127   // metadata is required. Note: values specified for a name and key are stored
128   // separately from values specified with only a name.
129   ScopedSampleMetadata(StringPiece name,
130                        int64_t key,
131                        int64_t value,
132                        SampleMetadataScope scope);
133
134   ScopedSampleMetadata(const ScopedSampleMetadata&) = delete;
135   ~ScopedSampleMetadata();
136
137   ScopedSampleMetadata& operator=(const ScopedSampleMetadata&) = delete;
138
139  private:
140   const uint64_t name_hash_;
141   absl::optional<int64_t> key_;
142   absl::optional<PlatformThreadId> thread_id_;
143 };
144
145 // Applies the specified metadata to samples already recorded between
146 // |period_start| and |period_end| in all thread's active profiles, subject to
147 // the condition that the profile fully encompasses the period and the profile
148 // has not already completed. The condition ensures that the metadata is applied
149 // only if all execution during its scope was seen in the profile. This avoids
150 // biasng the samples towards the 'middle' of the execution seen during the
151 // metadata scope (i.e. because the start or end of execution was missed), at
152 // the cost of missing execution that are longer than the profiling period, or
153 // extend before or after it. |period_end| must be <= TimeTicks::Now().
154 BASE_EXPORT void ApplyMetadataToPastSamples(TimeTicks period_start,
155                                             TimeTicks period_end,
156                                             StringPiece name,
157                                             int64_t value,
158                                             SampleMetadataScope scope);
159 BASE_EXPORT void ApplyMetadataToPastSamples(TimeTicks period_start,
160                                             TimeTicks period_end,
161                                             StringPiece name,
162                                             int64_t key,
163                                             int64_t value,
164                                             SampleMetadataScope scope);
165
166 // Adds metadata as metadata global to the sampling profile. Has the effect of
167 // applying the metadata to all samples in the profile, even ones collected
168 // earlier in time. This is probably not what you want for most use cases;
169 // prefer using SampleMetadata / ScopedSampleMetadata /
170 // ApplyMetadataToPastSamples instead.
171 BASE_EXPORT void AddProfileMetadata(StringPiece name,
172                                     int64_t key,
173                                     int64_t value,
174                                     SampleMetadataScope scope);
175
176 // Returns the process-global metadata recorder instance used for tracking
177 // sampling profiler metadata.
178 //
179 // This function should not be called by non-profiler related code.
180 BASE_EXPORT MetadataRecorder* GetSampleMetadataRecorder();
181
182 }  // namespace base
183
184 #endif  // BASE_PROFILER_SAMPLE_METADATA_H_