xref: /aosp_15_r20/external/libchrome/base/profiler/stack_sampling_profiler.h (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright 2015 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #ifndef BASE_PROFILER_STACK_SAMPLING_PROFILER_H_
6*635a8641SAndroid Build Coastguard Worker #define BASE_PROFILER_STACK_SAMPLING_PROFILER_H_
7*635a8641SAndroid Build Coastguard Worker 
8*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
9*635a8641SAndroid Build Coastguard Worker 
10*635a8641SAndroid Build Coastguard Worker #include <map>
11*635a8641SAndroid Build Coastguard Worker #include <memory>
12*635a8641SAndroid Build Coastguard Worker #include <string>
13*635a8641SAndroid Build Coastguard Worker #include <vector>
14*635a8641SAndroid Build Coastguard Worker 
15*635a8641SAndroid Build Coastguard Worker #include "base/base_export.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/files/file_path.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
18*635a8641SAndroid Build Coastguard Worker #include "base/strings/string16.h"
19*635a8641SAndroid Build Coastguard Worker #include "base/synchronization/waitable_event.h"
20*635a8641SAndroid Build Coastguard Worker #include "base/threading/platform_thread.h"
21*635a8641SAndroid Build Coastguard Worker #include "base/time/time.h"
22*635a8641SAndroid Build Coastguard Worker 
23*635a8641SAndroid Build Coastguard Worker namespace base {
24*635a8641SAndroid Build Coastguard Worker 
25*635a8641SAndroid Build Coastguard Worker // Identifies an unknown module.
26*635a8641SAndroid Build Coastguard Worker BASE_EXPORT extern const size_t kUnknownModuleIndex;
27*635a8641SAndroid Build Coastguard Worker 
28*635a8641SAndroid Build Coastguard Worker class NativeStackSamplerTestDelegate;
29*635a8641SAndroid Build Coastguard Worker 
30*635a8641SAndroid Build Coastguard Worker // StackSamplingProfiler periodically stops a thread to sample its stack, for
31*635a8641SAndroid Build Coastguard Worker // the purpose of collecting information about which code paths are
32*635a8641SAndroid Build Coastguard Worker // executing. This information is used in aggregate by UMA to identify hot
33*635a8641SAndroid Build Coastguard Worker // and/or janky code paths.
34*635a8641SAndroid Build Coastguard Worker //
35*635a8641SAndroid Build Coastguard Worker // Sample StackSamplingProfiler usage:
36*635a8641SAndroid Build Coastguard Worker //
37*635a8641SAndroid Build Coastguard Worker //   // Create and customize params as desired.
38*635a8641SAndroid Build Coastguard Worker //   base::StackStackSamplingProfiler::SamplingParams params;
39*635a8641SAndroid Build Coastguard Worker //
40*635a8641SAndroid Build Coastguard Worker //   // To process the profiles, use a custom ProfileBuilder subclass:
41*635a8641SAndroid Build Coastguard Worker //   class SubProfileBuilder :
42*635a8641SAndroid Build Coastguard Worker //       public base::StackSamplingProfiler::ProfileBuilder{...}
43*635a8641SAndroid Build Coastguard Worker //   base::StackSamplingProfiler profiler(base::PlatformThread::CurrentId()),
44*635a8641SAndroid Build Coastguard Worker //       params, std::make_unique<SubProfileBuilder>(...));
45*635a8641SAndroid Build Coastguard Worker //
46*635a8641SAndroid Build Coastguard Worker //   profiler.Start();
47*635a8641SAndroid Build Coastguard Worker //   // ... work being done on the target thread here ...
48*635a8641SAndroid Build Coastguard Worker //   profiler.Stop();  // optional, stops collection before complete per params
49*635a8641SAndroid Build Coastguard Worker //
50*635a8641SAndroid Build Coastguard Worker // The default SamplingParams causes stacks to be recorded in a single profile
51*635a8641SAndroid Build Coastguard Worker // at a 10Hz interval for a total of 30 seconds. All of these parameters may be
52*635a8641SAndroid Build Coastguard Worker // altered as desired.
53*635a8641SAndroid Build Coastguard Worker //
54*635a8641SAndroid Build Coastguard Worker // When a call stack profile is complete, or the profiler is stopped,
55*635a8641SAndroid Build Coastguard Worker // ProfileBuilder's OnProfileCompleted function is called from a thread created
56*635a8641SAndroid Build Coastguard Worker // by the profiler.
57*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT StackSamplingProfiler {
58*635a8641SAndroid Build Coastguard Worker  public:
59*635a8641SAndroid Build Coastguard Worker   // Module represents the module (DLL or exe) corresponding to a stack frame.
60*635a8641SAndroid Build Coastguard Worker   struct BASE_EXPORT Module {
61*635a8641SAndroid Build Coastguard Worker     Module();
62*635a8641SAndroid Build Coastguard Worker     Module(uintptr_t base_address,
63*635a8641SAndroid Build Coastguard Worker            const std::string& id,
64*635a8641SAndroid Build Coastguard Worker            const FilePath& filename);
65*635a8641SAndroid Build Coastguard Worker     ~Module();
66*635a8641SAndroid Build Coastguard Worker 
67*635a8641SAndroid Build Coastguard Worker     // Points to the base address of the module.
68*635a8641SAndroid Build Coastguard Worker     uintptr_t base_address;
69*635a8641SAndroid Build Coastguard Worker 
70*635a8641SAndroid Build Coastguard Worker     // An opaque binary string that uniquely identifies a particular program
71*635a8641SAndroid Build Coastguard Worker     // version with high probability. This is parsed from headers of the loaded
72*635a8641SAndroid Build Coastguard Worker     // module.
73*635a8641SAndroid Build Coastguard Worker     // For binaries generated by GNU tools:
74*635a8641SAndroid Build Coastguard Worker     //   Contents of the .note.gnu.build-id field.
75*635a8641SAndroid Build Coastguard Worker     // On Windows:
76*635a8641SAndroid Build Coastguard Worker     //   GUID + AGE in the debug image headers of a module.
77*635a8641SAndroid Build Coastguard Worker     std::string id;
78*635a8641SAndroid Build Coastguard Worker 
79*635a8641SAndroid Build Coastguard Worker     // The filename of the module.
80*635a8641SAndroid Build Coastguard Worker     FilePath filename;
81*635a8641SAndroid Build Coastguard Worker   };
82*635a8641SAndroid Build Coastguard Worker 
83*635a8641SAndroid Build Coastguard Worker   // InternalModule represents the module (DLL or exe) and its validness state.
84*635a8641SAndroid Build Coastguard Worker   // Different from Module, it has an additional field "is_valid".
85*635a8641SAndroid Build Coastguard Worker   //
86*635a8641SAndroid Build Coastguard Worker   // This struct is only used for sampling data transfer from NativeStackSampler
87*635a8641SAndroid Build Coastguard Worker   // to ProfileBuilder.
88*635a8641SAndroid Build Coastguard Worker   struct BASE_EXPORT InternalModule {
89*635a8641SAndroid Build Coastguard Worker     InternalModule();
90*635a8641SAndroid Build Coastguard Worker     InternalModule(uintptr_t base_address,
91*635a8641SAndroid Build Coastguard Worker                    const std::string& id,
92*635a8641SAndroid Build Coastguard Worker                    const FilePath& filename);
93*635a8641SAndroid Build Coastguard Worker     ~InternalModule();
94*635a8641SAndroid Build Coastguard Worker 
95*635a8641SAndroid Build Coastguard Worker     // Points to the base address of the module.
96*635a8641SAndroid Build Coastguard Worker     uintptr_t base_address;
97*635a8641SAndroid Build Coastguard Worker 
98*635a8641SAndroid Build Coastguard Worker     // An opaque binary string that uniquely identifies a particular program
99*635a8641SAndroid Build Coastguard Worker     // version with high probability. This is parsed from headers of the loaded
100*635a8641SAndroid Build Coastguard Worker     // module.
101*635a8641SAndroid Build Coastguard Worker     // For binaries generated by GNU tools:
102*635a8641SAndroid Build Coastguard Worker     //   Contents of the .note.gnu.build-id field.
103*635a8641SAndroid Build Coastguard Worker     // On Windows:
104*635a8641SAndroid Build Coastguard Worker     //   GUID + AGE in the debug image headers of a module.
105*635a8641SAndroid Build Coastguard Worker     std::string id;
106*635a8641SAndroid Build Coastguard Worker 
107*635a8641SAndroid Build Coastguard Worker     // The filename of the module.
108*635a8641SAndroid Build Coastguard Worker     FilePath filename;
109*635a8641SAndroid Build Coastguard Worker 
110*635a8641SAndroid Build Coastguard Worker     // The validness of the module.
111*635a8641SAndroid Build Coastguard Worker     bool is_valid;
112*635a8641SAndroid Build Coastguard Worker   };
113*635a8641SAndroid Build Coastguard Worker 
114*635a8641SAndroid Build Coastguard Worker   // Frame represents an individual sampled stack frame with module information.
115*635a8641SAndroid Build Coastguard Worker   struct BASE_EXPORT Frame {
116*635a8641SAndroid Build Coastguard Worker     Frame(uintptr_t instruction_pointer, size_t module_index);
117*635a8641SAndroid Build Coastguard Worker     ~Frame();
118*635a8641SAndroid Build Coastguard Worker 
119*635a8641SAndroid Build Coastguard Worker     // Default constructor to satisfy IPC macros. Do not use explicitly.
120*635a8641SAndroid Build Coastguard Worker     Frame();
121*635a8641SAndroid Build Coastguard Worker 
122*635a8641SAndroid Build Coastguard Worker     // The sampled instruction pointer within the function.
123*635a8641SAndroid Build Coastguard Worker     uintptr_t instruction_pointer;
124*635a8641SAndroid Build Coastguard Worker 
125*635a8641SAndroid Build Coastguard Worker     // Index of the module in CallStackProfile::modules. We don't represent
126*635a8641SAndroid Build Coastguard Worker     // module state directly here to save space.
127*635a8641SAndroid Build Coastguard Worker     size_t module_index;
128*635a8641SAndroid Build Coastguard Worker   };
129*635a8641SAndroid Build Coastguard Worker 
130*635a8641SAndroid Build Coastguard Worker   // InternalFrame represents an individual sampled stack frame with full module
131*635a8641SAndroid Build Coastguard Worker   // information. This is different from Frame which only contains module index.
132*635a8641SAndroid Build Coastguard Worker   //
133*635a8641SAndroid Build Coastguard Worker   // This struct is only used for sampling data transfer from NativeStackSampler
134*635a8641SAndroid Build Coastguard Worker   // to ProfileBuilder.
135*635a8641SAndroid Build Coastguard Worker   struct BASE_EXPORT InternalFrame {
136*635a8641SAndroid Build Coastguard Worker     InternalFrame(uintptr_t instruction_pointer,
137*635a8641SAndroid Build Coastguard Worker                   InternalModule internal_module);
138*635a8641SAndroid Build Coastguard Worker     ~InternalFrame();
139*635a8641SAndroid Build Coastguard Worker 
140*635a8641SAndroid Build Coastguard Worker     // The sampled instruction pointer within the function.
141*635a8641SAndroid Build Coastguard Worker     uintptr_t instruction_pointer;
142*635a8641SAndroid Build Coastguard Worker 
143*635a8641SAndroid Build Coastguard Worker     // The module information.
144*635a8641SAndroid Build Coastguard Worker     InternalModule internal_module;
145*635a8641SAndroid Build Coastguard Worker   };
146*635a8641SAndroid Build Coastguard Worker 
147*635a8641SAndroid Build Coastguard Worker   // Sample represents a set of stack frames with some extra information.
148*635a8641SAndroid Build Coastguard Worker   struct BASE_EXPORT Sample {
149*635a8641SAndroid Build Coastguard Worker     Sample();
150*635a8641SAndroid Build Coastguard Worker     Sample(const Sample& sample);
151*635a8641SAndroid Build Coastguard Worker     ~Sample();
152*635a8641SAndroid Build Coastguard Worker 
153*635a8641SAndroid Build Coastguard Worker     // These constructors are used only during testing.
154*635a8641SAndroid Build Coastguard Worker     Sample(const Frame& frame);
155*635a8641SAndroid Build Coastguard Worker     Sample(const std::vector<Frame>& frames);
156*635a8641SAndroid Build Coastguard Worker 
157*635a8641SAndroid Build Coastguard Worker     // The entire stack frame when the sample is taken.
158*635a8641SAndroid Build Coastguard Worker     std::vector<Frame> frames;
159*635a8641SAndroid Build Coastguard Worker 
160*635a8641SAndroid Build Coastguard Worker     // A bit-field indicating which process milestones have passed. This can be
161*635a8641SAndroid Build Coastguard Worker     // used to tell where in the process lifetime the samples are taken. Just
162*635a8641SAndroid Build Coastguard Worker     // as a "lifetime" can only move forward, these bits mark the milestones of
163*635a8641SAndroid Build Coastguard Worker     // the processes life as they occur. Bits can be set but never reset. The
164*635a8641SAndroid Build Coastguard Worker     // actual definition of the individual bits is left to the user of this
165*635a8641SAndroid Build Coastguard Worker     // module.
166*635a8641SAndroid Build Coastguard Worker     uint32_t process_milestones = 0;
167*635a8641SAndroid Build Coastguard Worker   };
168*635a8641SAndroid Build Coastguard Worker 
169*635a8641SAndroid Build Coastguard Worker   // CallStackProfile represents a set of samples.
170*635a8641SAndroid Build Coastguard Worker   struct BASE_EXPORT CallStackProfile {
171*635a8641SAndroid Build Coastguard Worker     CallStackProfile();
172*635a8641SAndroid Build Coastguard Worker     CallStackProfile(CallStackProfile&& other);
173*635a8641SAndroid Build Coastguard Worker     ~CallStackProfile();
174*635a8641SAndroid Build Coastguard Worker 
175*635a8641SAndroid Build Coastguard Worker     CallStackProfile& operator=(CallStackProfile&& other);
176*635a8641SAndroid Build Coastguard Worker 
177*635a8641SAndroid Build Coastguard Worker     CallStackProfile CopyForTesting() const;
178*635a8641SAndroid Build Coastguard Worker 
179*635a8641SAndroid Build Coastguard Worker     std::vector<Module> modules;
180*635a8641SAndroid Build Coastguard Worker     std::vector<Sample> samples;
181*635a8641SAndroid Build Coastguard Worker 
182*635a8641SAndroid Build Coastguard Worker     // Duration of this profile.
183*635a8641SAndroid Build Coastguard Worker     TimeDelta profile_duration;
184*635a8641SAndroid Build Coastguard Worker 
185*635a8641SAndroid Build Coastguard Worker     // Time between samples.
186*635a8641SAndroid Build Coastguard Worker     TimeDelta sampling_period;
187*635a8641SAndroid Build Coastguard Worker 
188*635a8641SAndroid Build Coastguard Worker    private:
189*635a8641SAndroid Build Coastguard Worker     // Copying is possible but expensive so disallow it except for internal use
190*635a8641SAndroid Build Coastguard Worker     // (i.e. CopyForTesting); use std::move instead.
191*635a8641SAndroid Build Coastguard Worker     CallStackProfile(const CallStackProfile& other);
192*635a8641SAndroid Build Coastguard Worker 
193*635a8641SAndroid Build Coastguard Worker     DISALLOW_ASSIGN(CallStackProfile);
194*635a8641SAndroid Build Coastguard Worker   };
195*635a8641SAndroid Build Coastguard Worker 
196*635a8641SAndroid Build Coastguard Worker   // Represents parameters that configure the sampling.
197*635a8641SAndroid Build Coastguard Worker   struct BASE_EXPORT SamplingParams {
198*635a8641SAndroid Build Coastguard Worker     // Time to delay before first samples are taken.
199*635a8641SAndroid Build Coastguard Worker     TimeDelta initial_delay = TimeDelta::FromMilliseconds(0);
200*635a8641SAndroid Build Coastguard Worker 
201*635a8641SAndroid Build Coastguard Worker     // Number of samples to record per profile.
202*635a8641SAndroid Build Coastguard Worker     int samples_per_profile = 300;
203*635a8641SAndroid Build Coastguard Worker 
204*635a8641SAndroid Build Coastguard Worker     // Interval between samples during a sampling profile. This is the desired
205*635a8641SAndroid Build Coastguard Worker     // duration from the start of one sample to the start of the next sample.
206*635a8641SAndroid Build Coastguard Worker     TimeDelta sampling_interval = TimeDelta::FromMilliseconds(100);
207*635a8641SAndroid Build Coastguard Worker   };
208*635a8641SAndroid Build Coastguard Worker 
209*635a8641SAndroid Build Coastguard Worker   // Testing support. These methods are static beause they interact with the
210*635a8641SAndroid Build Coastguard Worker   // sampling thread, a singleton used by all StackSamplingProfiler objects.
211*635a8641SAndroid Build Coastguard Worker   // These methods can only be called by the same thread that started the
212*635a8641SAndroid Build Coastguard Worker   // sampling.
213*635a8641SAndroid Build Coastguard Worker   class BASE_EXPORT TestAPI {
214*635a8641SAndroid Build Coastguard Worker    public:
215*635a8641SAndroid Build Coastguard Worker     // Resets the internal state to that of a fresh start. This is necessary
216*635a8641SAndroid Build Coastguard Worker     // so that tests don't inherit state from previous tests.
217*635a8641SAndroid Build Coastguard Worker     static void Reset();
218*635a8641SAndroid Build Coastguard Worker 
219*635a8641SAndroid Build Coastguard Worker     // Returns whether the sampling thread is currently running or not.
220*635a8641SAndroid Build Coastguard Worker     static bool IsSamplingThreadRunning();
221*635a8641SAndroid Build Coastguard Worker 
222*635a8641SAndroid Build Coastguard Worker     // Disables inherent idle-shutdown behavior.
223*635a8641SAndroid Build Coastguard Worker     static void DisableIdleShutdown();
224*635a8641SAndroid Build Coastguard Worker 
225*635a8641SAndroid Build Coastguard Worker     // Initiates an idle shutdown task, as though the idle timer had expired,
226*635a8641SAndroid Build Coastguard Worker     // causing the thread to exit. There is no "idle" check so this must be
227*635a8641SAndroid Build Coastguard Worker     // called only when all sampling tasks have completed. This blocks until
228*635a8641SAndroid Build Coastguard Worker     // the task has been executed, though the actual stopping of the thread
229*635a8641SAndroid Build Coastguard Worker     // still happens asynchronously. Watch IsSamplingThreadRunning() to know
230*635a8641SAndroid Build Coastguard Worker     // when the thread has exited. If |simulate_intervening_start| is true then
231*635a8641SAndroid Build Coastguard Worker     // this method will make it appear to the shutdown task that a new profiler
232*635a8641SAndroid Build Coastguard Worker     // was started between when the idle-shutdown was initiated and when it
233*635a8641SAndroid Build Coastguard Worker     // runs.
234*635a8641SAndroid Build Coastguard Worker     static void PerformSamplingThreadIdleShutdown(
235*635a8641SAndroid Build Coastguard Worker         bool simulate_intervening_start);
236*635a8641SAndroid Build Coastguard Worker   };
237*635a8641SAndroid Build Coastguard Worker 
238*635a8641SAndroid Build Coastguard Worker   // The ProfileBuilder interface allows the user to record profile information
239*635a8641SAndroid Build Coastguard Worker   // on the fly in whatever format is desired. Functions are invoked by the
240*635a8641SAndroid Build Coastguard Worker   // profiler on its own thread so must not block or perform expensive
241*635a8641SAndroid Build Coastguard Worker   // operations.
242*635a8641SAndroid Build Coastguard Worker   class BASE_EXPORT ProfileBuilder {
243*635a8641SAndroid Build Coastguard Worker    public:
244*635a8641SAndroid Build Coastguard Worker     ProfileBuilder() = default;
245*635a8641SAndroid Build Coastguard Worker     virtual ~ProfileBuilder() = default;
246*635a8641SAndroid Build Coastguard Worker 
247*635a8641SAndroid Build Coastguard Worker     // Metadata associated with the sample to be saved off.
248*635a8641SAndroid Build Coastguard Worker     // The code implementing this method must not do anything that could acquire
249*635a8641SAndroid Build Coastguard Worker     // a mutex, including allocating memory (which includes LOG messages)
250*635a8641SAndroid Build Coastguard Worker     // because that mutex could be held by a stopped thread, thus resulting in
251*635a8641SAndroid Build Coastguard Worker     // deadlock.
252*635a8641SAndroid Build Coastguard Worker     virtual void RecordAnnotations() = 0;
253*635a8641SAndroid Build Coastguard Worker 
254*635a8641SAndroid Build Coastguard Worker     // Records a new set of internal frames. Invoked when sampling a sample
255*635a8641SAndroid Build Coastguard Worker     // completes.
256*635a8641SAndroid Build Coastguard Worker     virtual void OnSampleCompleted(
257*635a8641SAndroid Build Coastguard Worker         std::vector<InternalFrame> internal_frames) = 0;
258*635a8641SAndroid Build Coastguard Worker 
259*635a8641SAndroid Build Coastguard Worker     // Finishes the profile construction with |profile_duration| and
260*635a8641SAndroid Build Coastguard Worker     // |sampling_period|. Invoked when sampling a profile completes.
261*635a8641SAndroid Build Coastguard Worker     virtual void OnProfileCompleted(TimeDelta profile_duration,
262*635a8641SAndroid Build Coastguard Worker                                     TimeDelta sampling_period) = 0;
263*635a8641SAndroid Build Coastguard Worker 
264*635a8641SAndroid Build Coastguard Worker    private:
265*635a8641SAndroid Build Coastguard Worker     DISALLOW_COPY_AND_ASSIGN(ProfileBuilder);
266*635a8641SAndroid Build Coastguard Worker   };
267*635a8641SAndroid Build Coastguard Worker 
268*635a8641SAndroid Build Coastguard Worker   // Creates a profiler for the CURRENT thread. An optional |test_delegate| can
269*635a8641SAndroid Build Coastguard Worker   // be supplied by tests. The caller must ensure that this object gets
270*635a8641SAndroid Build Coastguard Worker   // destroyed before the current thread exits.
271*635a8641SAndroid Build Coastguard Worker   StackSamplingProfiler(
272*635a8641SAndroid Build Coastguard Worker       const SamplingParams& params,
273*635a8641SAndroid Build Coastguard Worker       std::unique_ptr<ProfileBuilder> profile_builder,
274*635a8641SAndroid Build Coastguard Worker       NativeStackSamplerTestDelegate* test_delegate = nullptr);
275*635a8641SAndroid Build Coastguard Worker 
276*635a8641SAndroid Build Coastguard Worker   // Creates a profiler for ANOTHER thread. An optional |test_delegate| can be
277*635a8641SAndroid Build Coastguard Worker   // supplied by tests.
278*635a8641SAndroid Build Coastguard Worker   //
279*635a8641SAndroid Build Coastguard Worker   // IMPORTANT: The caller must ensure that the thread being sampled does not
280*635a8641SAndroid Build Coastguard Worker   // exit before this object gets destructed or Bad Things(tm) may occur.
281*635a8641SAndroid Build Coastguard Worker   StackSamplingProfiler(
282*635a8641SAndroid Build Coastguard Worker       PlatformThreadId thread_id,
283*635a8641SAndroid Build Coastguard Worker       const SamplingParams& params,
284*635a8641SAndroid Build Coastguard Worker       std::unique_ptr<ProfileBuilder> profile_builder,
285*635a8641SAndroid Build Coastguard Worker       NativeStackSamplerTestDelegate* test_delegate = nullptr);
286*635a8641SAndroid Build Coastguard Worker 
287*635a8641SAndroid Build Coastguard Worker   // Stops any profiling currently taking place before destroying the profiler.
288*635a8641SAndroid Build Coastguard Worker   // This will block until profile_builder_'s OnProfileCompleted function has
289*635a8641SAndroid Build Coastguard Worker   // executed if profiling has started but not already finished.
290*635a8641SAndroid Build Coastguard Worker   ~StackSamplingProfiler();
291*635a8641SAndroid Build Coastguard Worker 
292*635a8641SAndroid Build Coastguard Worker   // Initializes the profiler and starts sampling. Might block on a
293*635a8641SAndroid Build Coastguard Worker   // WaitableEvent if this StackSamplingProfiler was previously started and
294*635a8641SAndroid Build Coastguard Worker   // recently stopped, while the previous profiling phase winds down.
295*635a8641SAndroid Build Coastguard Worker   void Start();
296*635a8641SAndroid Build Coastguard Worker 
297*635a8641SAndroid Build Coastguard Worker   // Stops the profiler and any ongoing sampling. This method will return
298*635a8641SAndroid Build Coastguard Worker   // immediately with the profile_builder_'s OnProfileCompleted function being
299*635a8641SAndroid Build Coastguard Worker   // run asynchronously. At most one more stack sample will be taken after this
300*635a8641SAndroid Build Coastguard Worker   // method returns. Calling this function is optional; if not invoked profiling
301*635a8641SAndroid Build Coastguard Worker   // terminates when all the profiling samples specified in the SamplingParams
302*635a8641SAndroid Build Coastguard Worker   // are completed or the profiler object is destroyed, whichever occurs first.
303*635a8641SAndroid Build Coastguard Worker   void Stop();
304*635a8641SAndroid Build Coastguard Worker 
305*635a8641SAndroid Build Coastguard Worker  private:
306*635a8641SAndroid Build Coastguard Worker   friend class TestAPI;
307*635a8641SAndroid Build Coastguard Worker 
308*635a8641SAndroid Build Coastguard Worker   // SamplingThread is a separate thread used to suspend and sample stacks from
309*635a8641SAndroid Build Coastguard Worker   // the target thread.
310*635a8641SAndroid Build Coastguard Worker   class SamplingThread;
311*635a8641SAndroid Build Coastguard Worker 
312*635a8641SAndroid Build Coastguard Worker   // The thread whose stack will be sampled.
313*635a8641SAndroid Build Coastguard Worker   PlatformThreadId thread_id_;
314*635a8641SAndroid Build Coastguard Worker 
315*635a8641SAndroid Build Coastguard Worker   const SamplingParams params_;
316*635a8641SAndroid Build Coastguard Worker 
317*635a8641SAndroid Build Coastguard Worker   // Receives the sampling data and builds a CallStackProfile. The ownership of
318*635a8641SAndroid Build Coastguard Worker   // this object will be transferred to the sampling thread when thread sampling
319*635a8641SAndroid Build Coastguard Worker   // starts.
320*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<ProfileBuilder> profile_builder_;
321*635a8641SAndroid Build Coastguard Worker 
322*635a8641SAndroid Build Coastguard Worker   // This starts "signaled", is reset when sampling begins, and is signaled
323*635a8641SAndroid Build Coastguard Worker   // when that sampling is complete and the profile_builder_'s
324*635a8641SAndroid Build Coastguard Worker   // OnProfileCompleted function has executed.
325*635a8641SAndroid Build Coastguard Worker   WaitableEvent profiling_inactive_;
326*635a8641SAndroid Build Coastguard Worker 
327*635a8641SAndroid Build Coastguard Worker   // An ID uniquely identifying this profiler to the sampling thread. This
328*635a8641SAndroid Build Coastguard Worker   // will be an internal "null" value when no collection has been started.
329*635a8641SAndroid Build Coastguard Worker   int profiler_id_;
330*635a8641SAndroid Build Coastguard Worker 
331*635a8641SAndroid Build Coastguard Worker   // Stored until it can be passed to the NativeStackSampler created in Start().
332*635a8641SAndroid Build Coastguard Worker   NativeStackSamplerTestDelegate* const test_delegate_;
333*635a8641SAndroid Build Coastguard Worker 
334*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(StackSamplingProfiler);
335*635a8641SAndroid Build Coastguard Worker };
336*635a8641SAndroid Build Coastguard Worker 
337*635a8641SAndroid Build Coastguard Worker // These operators permit types to be compared and used in a map of Samples, as
338*635a8641SAndroid Build Coastguard Worker // done in tests and by the metrics provider code.
339*635a8641SAndroid Build Coastguard Worker BASE_EXPORT bool operator==(const StackSamplingProfiler::Module& a,
340*635a8641SAndroid Build Coastguard Worker                             const StackSamplingProfiler::Module& b);
341*635a8641SAndroid Build Coastguard Worker BASE_EXPORT bool operator==(const StackSamplingProfiler::Sample& a,
342*635a8641SAndroid Build Coastguard Worker                             const StackSamplingProfiler::Sample& b);
343*635a8641SAndroid Build Coastguard Worker BASE_EXPORT bool operator!=(const StackSamplingProfiler::Sample& a,
344*635a8641SAndroid Build Coastguard Worker                             const StackSamplingProfiler::Sample& b);
345*635a8641SAndroid Build Coastguard Worker BASE_EXPORT bool operator<(const StackSamplingProfiler::Sample& a,
346*635a8641SAndroid Build Coastguard Worker                            const StackSamplingProfiler::Sample& b);
347*635a8641SAndroid Build Coastguard Worker BASE_EXPORT bool operator==(const StackSamplingProfiler::Frame& a,
348*635a8641SAndroid Build Coastguard Worker                             const StackSamplingProfiler::Frame& b);
349*635a8641SAndroid Build Coastguard Worker BASE_EXPORT bool operator<(const StackSamplingProfiler::Frame& a,
350*635a8641SAndroid Build Coastguard Worker                            const StackSamplingProfiler::Frame& b);
351*635a8641SAndroid Build Coastguard Worker 
352*635a8641SAndroid Build Coastguard Worker }  // namespace base
353*635a8641SAndroid Build Coastguard Worker 
354*635a8641SAndroid Build Coastguard Worker #endif  // BASE_PROFILER_STACK_SAMPLING_PROFILER_H_
355