OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 //------------------------------------------------------------------------------ | 8 //------------------------------------------------------------------------------ |
9 #include <map> | 9 #include <map> |
10 #include <string> | 10 #include <string> |
(...skipping 21 matching lines...) Expand all Loading... |
32 private: | 32 private: |
33 // File/lineno of birth. This defines the essence of the type, as the context | 33 // File/lineno of birth. This defines the essence of the type, as the context |
34 // of the birth (construction) often tell what the item is for. This field | 34 // of the birth (construction) often tell what the item is for. This field |
35 // is const, and hence safe to access from any thread. | 35 // is const, and hence safe to access from any thread. |
36 const Location location_; | 36 const Location location_; |
37 | 37 |
38 // The thread that records births into this object. Only this thread is | 38 // The thread that records births into this object. Only this thread is |
39 // allowed to access birth_count_ (which changes over time). | 39 // allowed to access birth_count_ (which changes over time). |
40 const ThreadData* birth_thread_; // The thread this birth took place on. | 40 const ThreadData* birth_thread_; // The thread this birth took place on. |
41 | 41 |
42 DISALLOW_EVIL_CONSTRUCTORS(BirthOnThread); | 42 DISALLOW_COPY_AND_ASSIGN(BirthOnThread); |
43 }; | 43 }; |
44 | 44 |
45 //------------------------------------------------------------------------------ | 45 //------------------------------------------------------------------------------ |
46 // A class for accumulating counts of births (without bothering with a map<>). | 46 // A class for accumulating counts of births (without bothering with a map<>). |
47 | 47 |
48 class Births: public BirthOnThread { | 48 class Births: public BirthOnThread { |
49 public: | 49 public: |
50 explicit Births(const Location& location); | 50 explicit Births(const Location& location); |
51 | 51 |
52 int birth_count() const { return birth_count_; } | 52 int birth_count() const { return birth_count_; } |
53 | 53 |
54 // When we have a birth we update the count for this BirhPLace. | 54 // When we have a birth we update the count for this BirhPLace. |
55 void RecordBirth() { ++birth_count_; } | 55 void RecordBirth() { ++birth_count_; } |
56 | 56 |
57 // When a birthplace is changed (updated), we need to decrement the counter | 57 // When a birthplace is changed (updated), we need to decrement the counter |
58 // for the old instance. | 58 // for the old instance. |
59 void ForgetBirth() { --birth_count_; } // We corrected a birth place. | 59 void ForgetBirth() { --birth_count_; } // We corrected a birth place. |
60 | 60 |
61 private: | 61 private: |
62 // The number of births on this thread for our location_. | 62 // The number of births on this thread for our location_. |
63 int birth_count_; | 63 int birth_count_; |
64 | 64 |
65 DISALLOW_EVIL_CONSTRUCTORS(Births); | 65 DISALLOW_COPY_AND_ASSIGN(Births); |
66 }; | 66 }; |
67 | 67 |
68 //------------------------------------------------------------------------------ | 68 //------------------------------------------------------------------------------ |
69 // Basic info summarizing multiple destructions of an object with a single | 69 // Basic info summarizing multiple destructions of an object with a single |
70 // birthplace (fixed Location). Used both on specific threads, and also used | 70 // birthplace (fixed Location). Used both on specific threads, and also used |
71 // in snapshots when integrating assembled data. | 71 // in snapshots when integrating assembled data. |
72 | 72 |
73 class DeathData { | 73 class DeathData { |
74 public: | 74 public: |
75 // Default initializer. | 75 // Default initializer. |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 // The array that we collect data into. | 176 // The array that we collect data into. |
177 Collection collection_; | 177 Collection collection_; |
178 | 178 |
179 // The total number of births recorded at each location for which we have not | 179 // The total number of births recorded at each location for which we have not |
180 // seen a death count. | 180 // seen a death count. |
181 typedef std::map<const BirthOnThread*, int> BirthCount; | 181 typedef std::map<const BirthOnThread*, int> BirthCount; |
182 BirthCount global_birth_count_; | 182 BirthCount global_birth_count_; |
183 | 183 |
184 Lock accumulation_lock_; // Protects access during accumulation phase. | 184 Lock accumulation_lock_; // Protects access during accumulation phase. |
185 | 185 |
186 DISALLOW_EVIL_CONSTRUCTORS(DataCollector); | 186 DISALLOW_COPY_AND_ASSIGN(DataCollector); |
187 }; | 187 }; |
188 | 188 |
189 //------------------------------------------------------------------------------ | 189 //------------------------------------------------------------------------------ |
190 // Aggregation contains summaries (totals and subtotals) of groups of Snapshot | 190 // Aggregation contains summaries (totals and subtotals) of groups of Snapshot |
191 // instances to provide printing of these collections on a single line. | 191 // instances to provide printing of these collections on a single line. |
192 | 192 |
193 class Aggregation: public DeathData { | 193 class Aggregation: public DeathData { |
194 public: | 194 public: |
195 Aggregation() : birth_count_(0) {} | 195 Aggregation() : birth_count_(0) {} |
196 | 196 |
197 void AddDeathSnapshot(const Snapshot& snapshot); | 197 void AddDeathSnapshot(const Snapshot& snapshot); |
198 void AddBirths(const Births& births); | 198 void AddBirths(const Births& births); |
199 void AddBirth(const BirthOnThread& birth); | 199 void AddBirth(const BirthOnThread& birth); |
200 void AddBirthPlace(const Location& location); | 200 void AddBirthPlace(const Location& location); |
201 void Write(std::string* output) const; | 201 void Write(std::string* output) const; |
202 void Clear(); | 202 void Clear(); |
203 | 203 |
204 private: | 204 private: |
205 int birth_count_; | 205 int birth_count_; |
206 std::map<std::string, int> birth_files_; | 206 std::map<std::string, int> birth_files_; |
207 std::map<Location, int> locations_; | 207 std::map<Location, int> locations_; |
208 std::map<const ThreadData*, int> birth_threads_; | 208 std::map<const ThreadData*, int> birth_threads_; |
209 DeathData death_data_; | 209 DeathData death_data_; |
210 std::map<const ThreadData*, int> death_threads_; | 210 std::map<const ThreadData*, int> death_threads_; |
211 | 211 |
212 DISALLOW_EVIL_CONSTRUCTORS(Aggregation); | 212 DISALLOW_COPY_AND_ASSIGN(Aggregation); |
213 }; | 213 }; |
214 | 214 |
215 //------------------------------------------------------------------------------ | 215 //------------------------------------------------------------------------------ |
216 // Comparator does the comparison of Snapshot instances. It is | 216 // Comparator does the comparison of Snapshot instances. It is |
217 // used to order the instances in a vector. It orders them into groups (for | 217 // used to order the instances in a vector. It orders them into groups (for |
218 // aggregation), and can also order instances within the groups (for detailed | 218 // aggregation), and can also order instances within the groups (for detailed |
219 // rendering of the instances). | 219 // rendering of the instances). |
220 | 220 |
221 class Comparator { | 221 class Comparator { |
222 public: | 222 public: |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
421 ThreadSafeDownCounter* counter); | 421 ThreadSafeDownCounter* counter); |
422 // Run the supplied static method, and optionally set the event. | 422 // Run the supplied static method, and optionally set the event. |
423 void Run(); | 423 void Run(); |
424 | 424 |
425 private: | 425 private: |
426 FunctionPointer function_; | 426 FunctionPointer function_; |
427 HANDLE completion_handle_; | 427 HANDLE completion_handle_; |
428 // Make sure enough tasks are called before completion is signaled. | 428 // Make sure enough tasks are called before completion is signaled. |
429 ThreadSafeDownCounter* counter_; | 429 ThreadSafeDownCounter* counter_; |
430 | 430 |
431 DISALLOW_EVIL_CONSTRUCTORS(RunTheStatic); | 431 DISALLOW_COPY_AND_ASSIGN(RunTheStatic); |
432 }; | 432 }; |
433 #endif | 433 #endif |
434 | 434 |
435 // Each registered thread is called to set status_ to SHUTDOWN. | 435 // Each registered thread is called to set status_ to SHUTDOWN. |
436 // This is done redundantly on every registered thread because it is not | 436 // This is done redundantly on every registered thread because it is not |
437 // protected by a mutex. Running on all threads guarantees we get the | 437 // protected by a mutex. Running on all threads guarantees we get the |
438 // notification into the memory cache of all possible threads. | 438 // notification into the memory cache of all possible threads. |
439 static void ShutdownDisablingFurtherTracking(); | 439 static void ShutdownDisablingFurtherTracking(); |
440 | 440 |
441 // We use thread local store to identify which ThreadData to interact with. | 441 // We use thread local store to identify which ThreadData to interact with. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 // instances (i.e., when a tracked instance was destroyed on this thread). | 473 // instances (i.e., when a tracked instance was destroyed on this thread). |
474 DeathMap death_map_; | 474 DeathMap death_map_; |
475 | 475 |
476 // Lock to protect *some* access to BirthMap and DeathMap. We only use | 476 // Lock to protect *some* access to BirthMap and DeathMap. We only use |
477 // locking protection when we are growing the maps, or using an iterator. We | 477 // locking protection when we are growing the maps, or using an iterator. We |
478 // only do writes to members from this thread, so the updates of values are | 478 // only do writes to members from this thread, so the updates of values are |
479 // atomic. Folks can read from other threads, and get (via races) new or old | 479 // atomic. Folks can read from other threads, and get (via races) new or old |
480 // data, but that is considered acceptable errors (mis-information). | 480 // data, but that is considered acceptable errors (mis-information). |
481 Lock lock_; | 481 Lock lock_; |
482 | 482 |
483 DISALLOW_EVIL_CONSTRUCTORS(ThreadData); | 483 DISALLOW_COPY_AND_ASSIGN(ThreadData); |
484 }; | 484 }; |
485 | 485 |
| 486 |
| 487 //------------------------------------------------------------------------------ |
| 488 // Provide simple way to to start global tracking, and to tear down tracking |
| 489 // when done. Note that construction and destruction of this object must be |
| 490 // done when running in single threaded mode (before spawning a lot of threads |
| 491 // for construction, and after shutting down all the threads for destruction). |
| 492 |
| 493 class AutoTracking { |
| 494 public: |
| 495 AutoTracking() { ThreadData::StartTracking(true); } |
| 496 |
| 497 ~AutoTracking() { |
| 498 #ifndef NDEBUG // Don't call these in a Release build: they just waste time. |
| 499 // The following should ONLY be called when in single threaded mode. It is |
| 500 // unsafe to do this cleanup if other threads are still active. |
| 501 // It is also very unnecessary, so I'm only doing this in debug to satisfy |
| 502 // purify (if we need to!). |
| 503 ThreadData::ShutdownSingleThreadedCleanup(); |
| 504 #endif |
| 505 } |
| 506 |
| 507 private: |
| 508 DISALLOW_COPY_AND_ASSIGN(AutoTracking); |
| 509 }; |
| 510 |
| 511 |
486 } // namespace tracked_objects | 512 } // namespace tracked_objects |
487 | 513 |
488 #endif // BASE_TRACKED_OBJECTS_H_ | 514 #endif // BASE_TRACKED_OBJECTS_H_ |
489 | 515 |
OLD | NEW |