| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef BASE_TRACKED_OBJECTS_H_ | 5 #ifndef BASE_TRACKED_OBJECTS_H_ |
| 6 #define BASE_TRACKED_OBJECTS_H_ | 6 #define BASE_TRACKED_OBJECTS_H_ |
| 7 | 7 |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <map> | 10 #include <map> |
| 11 #include <set> | 11 #include <set> |
| 12 #include <stack> | 12 #include <stack> |
| 13 #include <string> | 13 #include <string> |
| 14 #include <unordered_map> | 14 #include <unordered_map> |
| 15 #include <utility> | 15 #include <utility> |
| 16 #include <vector> | 16 #include <vector> |
| 17 | 17 |
| 18 #include "base/allocator/features.h" | 18 #include "base/allocator/features.h" |
| 19 #include "base/atomicops.h" | 19 #include "base/atomicops.h" |
| 20 #include "base/base_export.h" | 20 #include "base/base_export.h" |
| 21 #include "base/containers/hash_tables.h" | 21 #include "base/containers/hash_tables.h" |
| 22 #include "base/debug/debugging_flags.h" | 22 #include "base/debug/debugging_flags.h" |
| 23 #include "base/debug/thread_heap_usage_tracker.h" | 23 #include "base/debug/thread_heap_usage_tracker.h" |
| 24 #include "base/gtest_prod_util.h" | 24 #include "base/gtest_prod_util.h" |
| 25 #include "base/lazy_instance.h" | 25 #include "base/lazy_instance.h" |
| 26 #include "base/location.h" | 26 #include "base/location.h" |
| 27 #include "base/macros.h" | 27 #include "base/macros.h" |
| 28 #include "base/process/process_handle.h" | 28 #include "base/process/process_handle.h" |
| 29 #include "base/profiler/tracked_time.h" | |
| 30 #include "base/synchronization/lock.h" | 29 #include "base/synchronization/lock.h" |
| 31 #include "base/threading/thread_local_storage.h" | 30 #include "base/threading/thread_local_storage.h" |
| 32 | 31 |
| 33 namespace base { | 32 namespace base { |
| 34 struct TrackingInfo; | 33 struct TrackingInfo; |
| 35 } | 34 } |
| 36 | 35 |
| 37 // TrackedObjects provides a database of stats about objects (generally Tasks) | 36 // TrackedObjects provides a database of stats about objects (generally Tasks) |
| 38 // that are tracked. Tracking means their birth, death, duration, birth thread, | 37 // that are tracked. Tracking means their birth, death, duration, birth thread, |
| 39 // death thread, and birth place are recorded. This data is carefully spread | 38 // death thread, and birth place are recorded. This data is carefully spread |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 339 // snapshotted. | 338 // snapshotted. |
| 340 | 339 |
| 341 class BASE_EXPORT DeathData { | 340 class BASE_EXPORT DeathData { |
| 342 public: | 341 public: |
| 343 DeathData(); | 342 DeathData(); |
| 344 DeathData(const DeathData& other); | 343 DeathData(const DeathData& other); |
| 345 ~DeathData(); | 344 ~DeathData(); |
| 346 | 345 |
| 347 // Update stats for a task destruction (death) that had a Run() time of | 346 // Update stats for a task destruction (death) that had a Run() time of |
| 348 // |duration|, and has had a queueing delay of |queue_duration|. | 347 // |duration|, and has had a queueing delay of |queue_duration|. |
| 349 void RecordDurations(const int32_t queue_duration, | 348 void RecordDurations(const base::TimeDelta queue_duration, |
| 350 const int32_t run_duration, | 349 const base::TimeDelta run_duration, |
| 351 const uint32_t random_number); | 350 const uint32_t random_number); |
| 352 | 351 |
| 353 // Update stats for a task destruction that performed |alloc_ops| | 352 // Update stats for a task destruction that performed |alloc_ops| |
| 354 // allocations, |free_ops| frees, allocated |allocated_bytes| bytes, freed | 353 // allocations, |free_ops| frees, allocated |allocated_bytes| bytes, freed |
| 355 // |freed_bytes|, where an estimated |alloc_overhead_bytes| went to heap | 354 // |freed_bytes|, where an estimated |alloc_overhead_bytes| went to heap |
| 356 // overhead, and where at most |max_allocated_bytes| were outstanding at any | 355 // overhead, and where at most |max_allocated_bytes| were outstanding at any |
| 357 // one time. | 356 // one time. |
| 358 // Note that |alloc_overhead_bytes|/|alloc_ops| yields the average estimated | 357 // Note that |alloc_overhead_bytes|/|alloc_ops| yields the average estimated |
| 359 // heap overhead of allocations in the task, and |allocated_bytes|/|alloc_ops| | 358 // heap overhead of allocations in the task, and |allocated_bytes|/|alloc_ops| |
| 360 // yields the average size of allocation. | 359 // yields the average size of allocation. |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 602 const base::TrackingInfo& completed_task, | 601 const base::TrackingInfo& completed_task, |
| 603 const TaskStopwatch& stopwatch); | 602 const TaskStopwatch& stopwatch); |
| 604 | 603 |
| 605 // Record the end of a timed run of an object. The |birth| is the record for | 604 // Record the end of a timed run of an object. The |birth| is the record for |
| 606 // the instance, the |time_posted| records that instant, which is presumed to | 605 // the instance, the |time_posted| records that instant, which is presumed to |
| 607 // be when the task was posted into a queue to run on a worker thread. | 606 // be when the task was posted into a queue to run on a worker thread. |
| 608 // The |start_of_run| is when the worker thread started to perform the run of | 607 // The |start_of_run| is when the worker thread started to perform the run of |
| 609 // the task. | 608 // the task. |
| 610 // The |end_of_run| was just obtained by a call to Now() (just after the task | 609 // The |end_of_run| was just obtained by a call to Now() (just after the task |
| 611 // finished). | 610 // finished). |
| 612 static void TallyRunOnWorkerThreadIfTracking(const Births* births, | 611 static void TallyRunOnWorkerThreadIfTracking( |
| 613 const TrackedTime& time_posted, | 612 const Births* births, |
| 614 const TaskStopwatch& stopwatch); | 613 const base::TimeTicks& time_posted, |
| 614 const TaskStopwatch& stopwatch); |
| 615 | 615 |
| 616 // Record the end of execution in region, generally corresponding to a scope | 616 // Record the end of execution in region, generally corresponding to a scope |
| 617 // being exited. | 617 // being exited. |
| 618 static void TallyRunInAScopedRegionIfTracking(const Births* births, | 618 static void TallyRunInAScopedRegionIfTracking(const Births* births, |
| 619 const TaskStopwatch& stopwatch); | 619 const TaskStopwatch& stopwatch); |
| 620 | 620 |
| 621 const std::string& sanitized_thread_name() const { | 621 const std::string& sanitized_thread_name() const { |
| 622 return sanitized_thread_name_; | 622 return sanitized_thread_name_; |
| 623 } | 623 } |
| 624 | 624 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 637 // DEACTIVATED). | 637 // DEACTIVATED). |
| 638 static bool TrackingStatus(); | 638 static bool TrackingStatus(); |
| 639 | 639 |
| 640 // Enables profiler timing. | 640 // Enables profiler timing. |
| 641 static void EnableProfilerTiming(); | 641 static void EnableProfilerTiming(); |
| 642 | 642 |
| 643 // Provide a time function that does nothing (runs fast) when we don't have | 643 // Provide a time function that does nothing (runs fast) when we don't have |
| 644 // the profiler enabled. It will generally be optimized away when it is | 644 // the profiler enabled. It will generally be optimized away when it is |
| 645 // ifdef'ed to be small enough (allowing the profiler to be "compiled out" of | 645 // ifdef'ed to be small enough (allowing the profiler to be "compiled out" of |
| 646 // the code). | 646 // the code). |
| 647 static TrackedTime Now(); | 647 static base::TimeTicks Now(); |
| 648 | 648 |
| 649 // This function can be called at process termination to validate that thread | 649 // This function can be called at process termination to validate that thread |
| 650 // cleanup routines have been called for at least some number of named | 650 // cleanup routines have been called for at least some number of named |
| 651 // threads. | 651 // threads. |
| 652 static void EnsureCleanupWasCalled(int major_threads_shutdown_count); | 652 static void EnsureCleanupWasCalled(int major_threads_shutdown_count); |
| 653 | 653 |
| 654 private: | 654 private: |
| 655 friend class TaskStopwatch; | 655 friend class TaskStopwatch; |
| 656 // Allow only tests to call ShutdownSingleThreadedCleanup. We NEVER call it | 656 // Allow only tests to call ShutdownSingleThreadedCleanup. We NEVER call it |
| 657 // in production code. | 657 // in production code. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 682 | 682 |
| 683 // Iterate through the null terminated list of ThreadData instances. | 683 // Iterate through the null terminated list of ThreadData instances. |
| 684 ThreadData* next() const; | 684 ThreadData* next() const; |
| 685 | 685 |
| 686 | 686 |
| 687 // In this thread's data, record a new birth. | 687 // In this thread's data, record a new birth. |
| 688 Births* TallyABirth(const Location& location); | 688 Births* TallyABirth(const Location& location); |
| 689 | 689 |
| 690 // Find a place to record a death on this thread. | 690 // Find a place to record a death on this thread. |
| 691 void TallyADeath(const Births& births, | 691 void TallyADeath(const Births& births, |
| 692 int32_t queue_duration, | 692 base::TimeDelta queue_duration, |
| 693 const TaskStopwatch& stopwatch); | 693 const TaskStopwatch& stopwatch); |
| 694 | 694 |
| 695 // Snapshots (under a lock) the profiled data for the tasks for this thread | 695 // Snapshots (under a lock) the profiled data for the tasks for this thread |
| 696 // and writes all of the executed tasks' data -- i.e. the data for all | 696 // and writes all of the executed tasks' data -- i.e. the data for all |
| 697 // profiling phases (including the current one: |current_profiling_phase|) for | 697 // profiling phases (including the current one: |current_profiling_phase|) for |
| 698 // the tasks with with entries in the death_map_ -- into |phased_snapshots|. | 698 // the tasks with with entries in the death_map_ -- into |phased_snapshots|. |
| 699 // Also updates the |birth_counts| tally for each task to keep track of the | 699 // Also updates the |birth_counts| tally for each task to keep track of the |
| 700 // number of living instances of the task -- that is, each task maps to the | 700 // number of living instances of the task -- that is, each task maps to the |
| 701 // number of births for the task that have not yet been balanced by a death. | 701 // number of births for the task that have not yet been balanced by a death. |
| 702 void SnapshotExecutedTasks(int current_profiling_phase, | 702 void SnapshotExecutedTasks(int current_profiling_phase, |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 838 TaskStopwatch(); | 838 TaskStopwatch(); |
| 839 ~TaskStopwatch(); | 839 ~TaskStopwatch(); |
| 840 | 840 |
| 841 // Starts stopwatch. | 841 // Starts stopwatch. |
| 842 void Start(); | 842 void Start(); |
| 843 | 843 |
| 844 // Stops stopwatch. | 844 // Stops stopwatch. |
| 845 void Stop(); | 845 void Stop(); |
| 846 | 846 |
| 847 // Returns the start time. | 847 // Returns the start time. |
| 848 TrackedTime StartTime() const; | 848 base::TimeTicks StartTime() const; |
| 849 | 849 |
| 850 // Task's duration is calculated as the wallclock duration between starting | 850 // Task's duration is calculated as the wallclock duration between starting |
| 851 // and stopping this stopwatch, minus the wallclock durations of any other | 851 // and stopping this stopwatch, minus the wallclock durations of any other |
| 852 // instances that are immediately nested in this one, started and stopped on | 852 // instances that are immediately nested in this one, started and stopped on |
| 853 // this thread during that period. | 853 // this thread during that period. |
| 854 int32_t RunDurationMs() const; | 854 base::TimeDelta RunDuration() const; |
| 855 | 855 |
| 856 #if BUILDFLAG(USE_ALLOCATOR_SHIM) | 856 #if BUILDFLAG(USE_ALLOCATOR_SHIM) |
| 857 const base::debug::ThreadHeapUsageTracker& heap_usage() const { | 857 const base::debug::ThreadHeapUsageTracker& heap_usage() const { |
| 858 return heap_usage_; | 858 return heap_usage_; |
| 859 } | 859 } |
| 860 bool heap_tracking_enabled() const { return heap_tracking_enabled_; } | 860 bool heap_tracking_enabled() const { return heap_tracking_enabled_; } |
| 861 #endif | 861 #endif |
| 862 | 862 |
| 863 // Returns tracking info for the current thread. | 863 // Returns tracking info for the current thread. |
| 864 ThreadData* GetThreadData() const; | 864 ThreadData* GetThreadData() const; |
| 865 | 865 |
| 866 private: | 866 private: |
| 867 // Time when the stopwatch was started. | 867 // Time when the stopwatch was started. |
| 868 TrackedTime start_time_; | 868 base::TimeTicks start_time_; |
| 869 | 869 |
| 870 #if BUILDFLAG(USE_ALLOCATOR_SHIM) | 870 #if BUILDFLAG(USE_ALLOCATOR_SHIM) |
| 871 base::debug::ThreadHeapUsageTracker heap_usage_; | 871 base::debug::ThreadHeapUsageTracker heap_usage_; |
| 872 bool heap_tracking_enabled_; | 872 bool heap_tracking_enabled_; |
| 873 #endif | 873 #endif |
| 874 | 874 |
| 875 // Wallclock duration of the task. | 875 // Wallclock duration of the task. |
| 876 int32_t wallclock_duration_ms_; | 876 base::TimeDelta wallclock_duration_; |
| 877 | 877 |
| 878 // Tracking info for the current thread. | 878 // Tracking info for the current thread. |
| 879 ThreadData* current_thread_data_; | 879 ThreadData* current_thread_data_; |
| 880 | 880 |
| 881 // Sum of wallclock durations of all stopwatches that were directly nested in | 881 // Sum of wallclock durations of all stopwatches that were directly nested in |
| 882 // this one. | 882 // this one. |
| 883 int32_t excluded_duration_ms_; | 883 base::TimeDelta excluded_duration_; |
| 884 | 884 |
| 885 // Stopwatch which was running on our thread when this stopwatch was started. | 885 // Stopwatch which was running on our thread when this stopwatch was started. |
| 886 // That preexisting stopwatch must be adjusted to the exclude the wallclock | 886 // That preexisting stopwatch must be adjusted to the exclude the wallclock |
| 887 // duration of this stopwatch. | 887 // duration of this stopwatch. |
| 888 TaskStopwatch* parent_; | 888 TaskStopwatch* parent_; |
| 889 | 889 |
| 890 #if DCHECK_IS_ON() | 890 #if DCHECK_IS_ON() |
| 891 // State of the stopwatch. Stopwatch is first constructed in a created state | 891 // State of the stopwatch. Stopwatch is first constructed in a created state |
| 892 // state, then is optionally started/stopped, then destructed. | 892 // state, then is optionally started/stopped, then destructed. |
| 893 enum { CREATED, RUNNING, STOPPED } state_; | 893 enum { CREATED, RUNNING, STOPPED } state_; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 921 ProcessDataSnapshot(const ProcessDataSnapshot& other); | 921 ProcessDataSnapshot(const ProcessDataSnapshot& other); |
| 922 ~ProcessDataSnapshot(); | 922 ~ProcessDataSnapshot(); |
| 923 | 923 |
| 924 PhasedProcessDataSnapshotMap phased_snapshots; | 924 PhasedProcessDataSnapshotMap phased_snapshots; |
| 925 base::ProcessId process_id; | 925 base::ProcessId process_id; |
| 926 }; | 926 }; |
| 927 | 927 |
| 928 } // namespace tracked_objects | 928 } // namespace tracked_objects |
| 929 | 929 |
| 930 #endif // BASE_TRACKED_OBJECTS_H_ | 930 #endif // BASE_TRACKED_OBJECTS_H_ |
| OLD | NEW |