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 |