Chromium Code Reviews| Index: base/tracked_objects.h |
| diff --git a/base/tracked_objects.h b/base/tracked_objects.h |
| index 511a289066184074110405bb254d568473d8423a..7d018d3b8fb289f9e13baba3a03515787ab9d2c8 100644 |
| --- a/base/tracked_objects.h |
| +++ b/base/tracked_objects.h |
| @@ -352,6 +352,8 @@ struct BASE_EXPORT TaskSnapshot { |
| // harvest data from all existing instances. |
| struct ProcessDataSnapshot; |
| +class BASE_EXPORT TaskStopwatch; |
| + |
| class BASE_EXPORT ThreadData { |
| public: |
| // Current allowable states of the tracking system. The states can vary |
| @@ -403,8 +405,7 @@ class BASE_EXPORT ThreadData { |
| // finished). It is provided as an argument to help with testing. |
| static void TallyRunOnNamedThreadIfTracking( |
| const base::TrackingInfo& completed_task, |
| - const TrackedTime& start_of_run, |
| - const TrackedTime& end_of_run); |
| + const TaskStopwatch& stopwatch); |
| // Record the end of a timed run of an object. The |birth| is the record for |
| // the instance, the |time_posted| records that instant, which is presumed to |
| @@ -416,15 +417,13 @@ class BASE_EXPORT ThreadData { |
| static void TallyRunOnWorkerThreadIfTracking( |
| const Births* birth, |
| const TrackedTime& time_posted, |
| - const TrackedTime& start_of_run, |
| - const TrackedTime& end_of_run); |
| + const TaskStopwatch& stopwatch); |
| // Record the end of execution in region, generally corresponding to a scope |
| // being exited. |
| static void TallyRunInAScopedRegionIfTracking( |
| const Births* birth, |
| - const TrackedTime& start_of_run, |
| - const TrackedTime& end_of_run); |
| + const TaskStopwatch& stopwatch); |
| const std::string& thread_name() const { return thread_name_; } |
| @@ -460,14 +459,12 @@ class BASE_EXPORT ThreadData { |
| // on. This is currently a compiled option, atop TrackingStatus(). |
| static bool TrackingParentChildStatus(); |
| - // Special versions of Now() for getting times at start and end of a tracked |
| - // run. They are super fast when tracking is disabled, and have some internal |
| - // side effects when we are tracking, so that we can deduce the amount of time |
| - // accumulated outside of execution of tracked runs. |
| + // Marks a start of a tracked run. It's super fast when tracking is disabled, |
| + // and has some internal side effects when we are tracking, so that we can |
| + // deduce the amount of time accumulated outside of execution of tracked runs. |
| // The task that will be tracked is passed in as |parent| so that parent-child |
| // relationships can be (optionally) calculated. |
| - static TrackedTime NowForStartOfRun(const Births* parent); |
| - static TrackedTime NowForEndOfRun(); |
| + static void PrepareForStartOfRun(const Births* parent); |
| // Provide a time function that does nothing (runs fast) when we don't have |
| // the profiler enabled. It will generally be optimized away when it is |
| @@ -487,6 +484,7 @@ class BASE_EXPORT ThreadData { |
| static void EnsureCleanupWasCalled(int major_threads_shutdown_count); |
| private: |
| + friend class TaskStopwatch; |
| // Allow only tests to call ShutdownSingleThreadedCleanup. We NEVER call it |
| // in production code. |
| // TODO(jar): Make this a friend in DEBUG only, so that the optimizer has a |
| @@ -523,7 +521,9 @@ class BASE_EXPORT ThreadData { |
| Births* TallyABirth(const Location& location); |
| // Find a place to record a death on this thread. |
| - void TallyADeath(const Births& birth, int32 queue_duration, int32 duration); |
| + void TallyADeath(const Births& birth, |
| + int32 queue_duration, |
| + const TaskStopwatch& stopwatch); |
| // Snapshot (under a lock) the profiled data for the tasks in each ThreadData |
| // instance. Also updates the |birth_counts| tally for each task to keep |
| @@ -582,6 +582,10 @@ class BASE_EXPORT ThreadData { |
| // increasing time functcion. |
| static NowFunction* now_function_; |
| + // If true, now_function_ returns values that can be used to calculate queue |
| + // time. |
| + static bool now_function_is_time_; |
| + |
| // We use thread local store to identify which ThreadData to interact with. |
| static base::ThreadLocalStorage::StaticSlot tls_index_; |
| @@ -686,10 +690,74 @@ class BASE_EXPORT ThreadData { |
| // incarnations). |
| int incarnation_count_for_pool_; |
| + // Most recently started (i.e. most nested) stopwatch on the current thread, |
| + // if it exists; NULL otherwise. |
| + TaskStopwatch* current_stopwatch_; |
| + |
| DISALLOW_COPY_AND_ASSIGN(ThreadData); |
| }; |
| //------------------------------------------------------------------------------ |
| +// Stopwatch to measure task run time or simply create a time interval that will |
| +// be subtracted from the current most nested task's run time. Stopwatches |
| +// coordinate with the stopwatches in which they are nested to avoid |
| +// double-counting nested tasks run times. |
| + |
| +class BASE_EXPORT TaskStopwatch { |
| + public: |
| + // Starts the stopwatch. |
| + TaskStopwatch(); |
| + ~TaskStopwatch(); |
| + |
| + // Stops stopwatch. |
| + void Stop(); |
| + |
| + // Returns the start time. |
| + TrackedTime StartTime() const; |
| + |
| + // Task's duration is calculated as the wallclock duration between starting |
| + // and stopping this stopwatch, minus the wallclock durations of any other |
| + // instances that are immediately nested in this one, started and stopped on |
| + // this thread during that period. |
| + int32 RunDurationMs() const; |
| + |
| + // Returns tracking info for the current thread. |
| + ThreadData* GetThreadData() const; |
| + |
| + private: |
| + // Time when the stopwatch was started. |
| + TrackedTime start_time_; |
| + |
| + // Wallclock duration of the task. |
| + int32 wallclock_duration_ms_; |
| + |
| + // Tracking info for the current thread. |
| + ThreadData* current_thread_data_; |
| + |
| + // Sum of wallclock durations of all stopwatches that were directly nested in |
| + // this one. |
| + int32 excluded_duration_ms_; |
| + |
| + // Stopwatch which was running on our thread when this stopwatch was started. |
| + // That preexisting stopwatch must be adjusted to the exclude the wallclock |
| + // duration of this stopwatch. |
| + TaskStopwatch* parent_stopwatch_; |
| + |
| +#ifndef NDEBUG |
| + // State of the stopwatch. Stopwatch is reusable, i.e. it can be started after |
| + // it was stopped. |
| + enum { |
| + RUNNING, |
| + STOPPED |
| + } state_; |
| + |
| + // Currently running stopwatch that is directly nested in this one, if such |
| + // stopwatch exists. NULL otherwise. |
| + TaskStopwatch* running_child_; |
|
jar (doing other things)
2014/09/05 04:36:05
nit: Clean up names. This is really a backward li
vadimt
2014/09/05 20:25:55
Done.
|
| +#endif |
| +}; |
| + |
| +//------------------------------------------------------------------------------ |
| // A snapshotted representation of a (parent, child) task pair, for tracking |
| // hierarchical profiles. |