1 // Copyright 2014 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_PROFILER_SCOPED_TRACKER_H_ 6 #define BASE_PROFILER_SCOPED_TRACKER_H_ 7 8 //------------------------------------------------------------------------------ 9 // Utilities for temporarily instrumenting code to dig into issues that were 10 // found using profiler data. 11 12 #include "base/base_export.h" 13 #include "base/bind.h" 14 #include "base/callback_forward.h" 15 #include "base/location.h" 16 #include "base/macros.h" 17 #include "base/profiler/scoped_profile.h" 18 19 namespace tracked_objects { 20 21 // ScopedTracker instruments a region within the code if the instrumentation is 22 // enabled. It can be used, for example, to find out if a source of jankiness is 23 // inside the instrumented code region. 24 // Details: 25 // 1. This class creates a task (like ones created by PostTask calls or IPC 26 // message handlers). This task can be seen in chrome://profiler and is sent as 27 // a part of profiler data to the UMA server. See profiler_event.proto. 28 // 2. That task's lifetime is same as the lifetime of the ScopedTracker 29 // instance. 30 // 3. The execution time associated with the task is the wallclock time between 31 // its constructor and destructor, minus wallclock times of directly nested 32 // tasks. 33 // 4. Task creation that this class utilizes is highly optimized. 34 // 5. The class doesn't create a task unless this was enabled for the current 35 // process. Search for ScopedTracker::Enable for the current list of processes 36 // and channels where it's activated. 37 // 6. The class is designed for temporarily instrumenting code to find 38 // performance problems, after which the instrumentation must be removed. 39 class BASE_EXPORT ScopedTracker { 40 public: 41 ScopedTracker(const Location& location); 42 43 // Enables instrumentation for the remainder of the current process' life. If 44 // this function is not called, all profiler instrumentations are no-ops. 45 static void Enable(); 46 47 // Augments a |callback| with provided |location|. This is useful for 48 // instrumenting cases when we know that a jank is in a callback and there are 49 // many possible callbacks, but they come from a relatively small number of 50 // places. We can instrument these few places and at least know which one 51 // passes the janky callback. 52 template <typename P1> TrackCallback(const Location & location,const base::Callback<void (P1)> & callback)53 static base::Callback<void(P1)> TrackCallback( 54 const Location& location, 55 const base::Callback<void(P1)>& callback) { 56 return base::Bind(&ScopedTracker::ExecuteAndTrackCallback<P1>, location, 57 callback); 58 } 59 60 private: 61 // Executes |callback|, augmenting it with provided |location|. 62 template <typename P1> ExecuteAndTrackCallback(const Location & location,const base::Callback<void (P1)> & callback,P1 p1)63 static void ExecuteAndTrackCallback(const Location& location, 64 const base::Callback<void(P1)>& callback, 65 P1 p1) { 66 ScopedTracker tracking_profile(location); 67 callback.Run(p1); 68 } 69 70 const ScopedProfile scoped_profile_; 71 72 DISALLOW_COPY_AND_ASSIGN(ScopedTracker); 73 }; 74 75 } // namespace tracked_objects 76 77 #endif // BASE_PROFILER_SCOPED_TRACKER_H_ 78