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