| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #pragma once | 7 #pragma once |
| 8 | 8 |
| 9 #include <map> | 9 #include <map> |
| 10 #include <stack> | 10 #include <stack> |
| 11 #include <string> | 11 #include <string> |
| 12 #include <vector> | 12 #include <vector> |
| 13 | 13 |
| 14 #include "base/base_export.h" | 14 #include "base/base_export.h" |
| 15 #include "base/location.h" | 15 #include "base/location.h" |
| 16 #include "base/profiler/tracked_time.h" | |
| 17 #include "base/time.h" | 16 #include "base/time.h" |
| 18 #include "base/synchronization/lock.h" | 17 #include "base/synchronization/lock.h" |
| 19 #include "base/threading/thread_local_storage.h" | 18 #include "base/threading/thread_local_storage.h" |
| 20 #include "base/tracking_info.h" | 19 #include "base/tracking_info.h" |
| 21 #include "base/values.h" | 20 #include "base/values.h" |
| 22 | 21 |
| 22 #if defined(OS_WIN) |
| 23 #include <mmsystem.h> // Declare timeGetTime(); |
| 24 #endif |
| 25 |
| 23 // TrackedObjects provides a database of stats about objects (generally Tasks) | 26 // TrackedObjects provides a database of stats about objects (generally Tasks) |
| 24 // that are tracked. Tracking means their birth, death, duration, birth thread, | 27 // that are tracked. Tracking means their birth, death, duration, birth thread, |
| 25 // death thread, and birth place are recorded. This data is carefully spread | 28 // death thread, and birth place are recorded. This data is carefully spread |
| 26 // across a series of objects so that the counts and times can be rapidly | 29 // across a series of objects so that the counts and times can be rapidly |
| 27 // updated without (usually) having to lock the data, and hence there is usually | 30 // updated without (usually) having to lock the data, and hence there is usually |
| 28 // very little contention caused by the tracking. The data can be viewed via | 31 // very little contention caused by the tracking. The data can be viewed via |
| 29 // the about:tracking URL, with a variety of sorting and filtering choices. | 32 // the about:tracking URL, with a variety of sorting and filtering choices. |
| 30 // | 33 // |
| 31 // These classes serve as the basis of a profiler of sorts for the Tasks system. | 34 // These classes serve as the basis of a profiler of sorts for the Tasks system. |
| 32 // As a result, design decisions were made to maximize speed, by minimizing | 35 // As a result, design decisions were made to maximize speed, by minimizing |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 // For basic profiling, this will work "most of the time," and should be | 166 // For basic profiling, this will work "most of the time," and should be |
| 164 // sufficient... but storing away DataCollections is the "right way" to do this. | 167 // sufficient... but storing away DataCollections is the "right way" to do this. |
| 165 // We'll accomplish this via JavaScript storage of snapshots, and then we'll | 168 // We'll accomplish this via JavaScript storage of snapshots, and then we'll |
| 166 // remove the Reset() methods. | 169 // remove the Reset() methods. |
| 167 | 170 |
| 168 class MessageLoop; | 171 class MessageLoop; |
| 169 | 172 |
| 170 namespace tracked_objects { | 173 namespace tracked_objects { |
| 171 | 174 |
| 172 //------------------------------------------------------------------------------ | 175 //------------------------------------------------------------------------------ |
| 176 |
| 177 #define USE_FAST_TIME_CLASS_FOR_DURATION_CALCULATIONS |
| 178 |
| 179 #if defined(USE_FAST_TIME_CLASS_FOR_DURATION_CALCULATIONS) |
| 180 |
| 181 // TimeTicks maintains a wasteful 64 bits of data (we need less than 32), and on |
| 182 // windows, a 64 bit timer is expensive to even obtain. We use a simple |
| 183 // millisecond counter for most of our time values, as well as millisecond units |
| 184 // of duration between those values. This means we can only handle durations |
| 185 // up to 49 days (range), or 24 days (non-negative time durations). |
| 186 // We only define enough methods to service the needs of the tracking classes, |
| 187 // and our interfaces are modeled after what TimeTicks and TimeDelta use (so we |
| 188 // can swap them into place if we want to use the "real" classes). |
| 189 |
| 190 class BASE_EXPORT Duration { // Similar to base::TimeDelta. |
| 191 public: |
| 192 Duration() : ms_(0) {} |
| 193 |
| 194 Duration& operator+=(const Duration& other) { |
| 195 ms_ += other.ms_; |
| 196 return *this; |
| 197 } |
| 198 |
| 199 Duration operator+(const Duration& other) const { |
| 200 return Duration(ms_ + other.ms_); |
| 201 } |
| 202 |
| 203 bool operator==(const Duration& other) const { return ms_ == other.ms_; } |
| 204 bool operator!=(const Duration& other) const { return ms_ != other.ms_; } |
| 205 bool operator>(const Duration& other) const { return ms_ > other.ms_; } |
| 206 |
| 207 static Duration FromMilliseconds(int ms) { return Duration(ms); } |
| 208 |
| 209 int32 InMilliseconds() const { return ms_; } |
| 210 |
| 211 private: |
| 212 friend class TrackedTime; |
| 213 explicit Duration(int32 duration) : ms_(duration) {} |
| 214 |
| 215 // Internal time is stored directly in milliseconds. |
| 216 int32 ms_; |
| 217 }; |
| 218 |
| 219 class BASE_EXPORT TrackedTime { // Similar to base::TimeTicks. |
| 220 public: |
| 221 TrackedTime() : ms_(0) {} |
| 222 explicit TrackedTime(const base::TimeTicks& time) |
| 223 : ms_((time - base::TimeTicks()).InMilliseconds()) { |
| 224 } |
| 225 |
| 226 static TrackedTime Now() { |
| 227 #if defined(OS_WIN) |
| 228 // Use lock-free accessor to 32 bit time. |
| 229 // Note that TimeTicks::Now() is built on this, so we have "compatible" |
| 230 // times when we down-convert a TimeTicks sample. |
| 231 // TODO(jar): Surface this interface via something in base/time.h. |
| 232 return TrackedTime(static_cast<int32>(::timeGetTime())); |
| 233 #else |
| 234 // Posix has nice cheap 64 bit times, so we just down-convert it. |
| 235 return TrackedTime(base::TimeTicks::Now()); |
| 236 #endif // OS_WIN |
| 237 } |
| 238 |
| 239 Duration operator-(const TrackedTime& other) const { |
| 240 return Duration(ms_ - other.ms_); |
| 241 } |
| 242 |
| 243 TrackedTime operator+(const Duration& other) const { |
| 244 return TrackedTime(ms_ + other.ms_); |
| 245 } |
| 246 |
| 247 bool is_null() const { return ms_ == 0; } |
| 248 |
| 249 private: |
| 250 friend class Duration; |
| 251 explicit TrackedTime(int32 ms) : ms_(ms) {} |
| 252 |
| 253 // Internal duration is stored directly in milliseconds. |
| 254 uint32 ms_; |
| 255 }; |
| 256 |
| 257 #else |
| 258 |
| 259 // Just use full 64 bit time calculations, and the slower TimeTicks::Now(). |
| 260 typedef base::TimeTicks TrackedTime; |
| 261 typedef base::TimeDelta Duration; |
| 262 |
| 263 #endif // USE_FAST_TIME_CLASS_FOR_DURATION_CALCULATIONS |
| 264 |
| 265 //------------------------------------------------------------------------------ |
| 173 // For a specific thread, and a specific birth place, the collection of all | 266 // For a specific thread, and a specific birth place, the collection of all |
| 174 // death info (with tallies for each death thread, to prevent access conflicts). | 267 // death info (with tallies for each death thread, to prevent access conflicts). |
| 175 class ThreadData; | 268 class ThreadData; |
| 176 class BASE_EXPORT BirthOnThread { | 269 class BASE_EXPORT BirthOnThread { |
| 177 public: | 270 public: |
| 178 BirthOnThread(const Location& location, const ThreadData& current); | 271 BirthOnThread(const Location& location, const ThreadData& current); |
| 179 | 272 |
| 180 const Location location() const { return location_; } | 273 const Location location() const { return location_; } |
| 181 const ThreadData* birth_thread() const { return birth_thread_; } | 274 const ThreadData* birth_thread() const { return birth_thread_; } |
| 182 | 275 |
| (...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 613 // The |start_of_run| is when the worker thread started to perform the run of | 706 // The |start_of_run| is when the worker thread started to perform the run of |
| 614 // the task. | 707 // the task. |
| 615 // The |end_of_run| was just obtained by a call to Now() (just after the task | 708 // The |end_of_run| was just obtained by a call to Now() (just after the task |
| 616 // finished). | 709 // finished). |
| 617 static void TallyRunOnWorkerThreadIfTracking( | 710 static void TallyRunOnWorkerThreadIfTracking( |
| 618 const Births* birth, | 711 const Births* birth, |
| 619 const TrackedTime& time_posted, | 712 const TrackedTime& time_posted, |
| 620 const TrackedTime& start_of_run, | 713 const TrackedTime& start_of_run, |
| 621 const TrackedTime& end_of_run); | 714 const TrackedTime& end_of_run); |
| 622 | 715 |
| 623 // Record the end of execution in region, generally corresponding to a scope | |
| 624 // being exited. | |
| 625 static void TallyRunInAScopedRegionIfTracking( | |
| 626 const Births* birth, | |
| 627 const TrackedTime& start_of_run, | |
| 628 const TrackedTime& end_of_run); | |
| 629 | |
| 630 const std::string thread_name() const { return thread_name_; } | 716 const std::string thread_name() const { return thread_name_; } |
| 631 | 717 |
| 632 // --------------------- | 718 // --------------------- |
| 633 // TODO(jar): | |
| 634 // The following functions should all be private, and are only public because | 719 // The following functions should all be private, and are only public because |
| 635 // the collection is done externally. We need to relocate that code from the | 720 // the collection is done externally. We need to relocate that code from the |
| 636 // collection class into this class, and then all these methods can be made | 721 // collection class into this class, and then all these methods can be made |
| 637 // private. | 722 // private. |
| 638 // (Thread safe) Get start of list of all ThreadData instances. | 723 // (Thread safe) Get start of list of all ThreadData instances. |
| 639 static ThreadData* first(); | 724 static ThreadData* first(); |
| 640 // Iterate through the null terminated list of ThreadData instances. | 725 // Iterate through the null terminated list of ThreadData instances. |
| 641 ThreadData* next() const { return next_; } | 726 ThreadData* next() const { return next_; } |
| 642 // Using our lock, make a copy of the specified maps. These calls may arrive | 727 // Using our lock, make a copy of the specified maps. These calls may arrive |
| 643 // from non-local threads, and are used to quickly scan data from all threads | 728 // from non-local threads, and are used to quickly scan data from all threads |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 806 } | 891 } |
| 807 | 892 |
| 808 private: | 893 private: |
| 809 | 894 |
| 810 DISALLOW_COPY_AND_ASSIGN(AutoTracking); | 895 DISALLOW_COPY_AND_ASSIGN(AutoTracking); |
| 811 }; | 896 }; |
| 812 | 897 |
| 813 } // namespace tracked_objects | 898 } // namespace tracked_objects |
| 814 | 899 |
| 815 #endif // BASE_TRACKED_OBJECTS_H_ | 900 #endif // BASE_TRACKED_OBJECTS_H_ |
| OLD | NEW |