Home | History | Annotate | Download | only in profiler
      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>
     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>
     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