// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef BASE_PROFILER_SCOPED_TRACKER_H_ #define BASE_PROFILER_SCOPED_TRACKER_H_ //------------------------------------------------------------------------------ // Utilities for temporarily instrumenting code to dig into issues that were // found using profiler data. #include "base/base_export.h" #include "base/bind.h" #include "base/callback_forward.h" #include "base/location.h" #include "base/macros.h" #include "base/profiler/scoped_profile.h" namespace tracked_objects { // ScopedTracker instruments a region within the code if the instrumentation is // enabled. It can be used, for example, to find out if a source of jankiness is // inside the instrumented code region. // Details: // 1. This class creates a task (like ones created by PostTask calls or IPC // message handlers). This task can be seen in chrome://profiler and is sent as // a part of profiler data to the UMA server. See profiler_event.proto. // 2. That task's lifetime is same as the lifetime of the ScopedTracker // instance. // 3. The execution time associated with the task is the wallclock time between // its constructor and destructor, minus wallclock times of directly nested // tasks. // 4. Task creation that this class utilizes is highly optimized. // 5. The class doesn't create a task unless this was enabled for the current // process. Search for ScopedTracker::Enable for the current list of processes // and channels where it's activated. // 6. The class is designed for temporarily instrumenting code to find // performance problems, after which the instrumentation must be removed. class BASE_EXPORT ScopedTracker { public: ScopedTracker(const Location& location); // Enables instrumentation for the remainder of the current process' life. If // this function is not called, all profiler instrumentations are no-ops. static void Enable(); // Augments a |callback| with provided |location|. This is useful for // instrumenting cases when we know that a jank is in a callback and there are // many possible callbacks, but they come from a relatively small number of // places. We can instrument these few places and at least know which one // passes the janky callback. template <typename P1> static base::Callback<void(P1)> TrackCallback( const Location& location, const base::Callback<void(P1)>& callback) { return base::Bind(&ScopedTracker::ExecuteAndTrackCallback<P1>, location, callback); } private: // Executes |callback|, augmenting it with provided |location|. template <typename P1> static void ExecuteAndTrackCallback(const Location& location, const base::Callback<void(P1)>& callback, P1 p1) { ScopedTracker tracking_profile(location); callback.Run(p1); } const ScopedProfile scoped_profile_; DISALLOW_COPY_AND_ASSIGN(ScopedTracker); }; } // namespace tracked_objects #endif // BASE_PROFILER_SCOPED_TRACKER_H_