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 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <map> | 9 #include <map> |
10 #include <set> | 10 #include <set> |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 // very little global performance impact. | 122 // very little global performance impact. |
123 // | 123 // |
124 // The above description tries to define the high performance (run time) | 124 // The above description tries to define the high performance (run time) |
125 // portions of these classes. After gathering statistics, calls instigated | 125 // portions of these classes. After gathering statistics, calls instigated |
126 // by visiting about:profiler will assemble and aggregate data for display. The | 126 // by visiting about:profiler will assemble and aggregate data for display. The |
127 // following data structures are used for producing such displays. They are | 127 // following data structures are used for producing such displays. They are |
128 // not performance critical, and their only major constraint is that they should | 128 // not performance critical, and their only major constraint is that they should |
129 // be able to run concurrently with ongoing augmentation of the birth and death | 129 // be able to run concurrently with ongoing augmentation of the birth and death |
130 // data. | 130 // data. |
131 // | 131 // |
| 132 // This header also exports collection of classes that provide serialized |
| 133 // representations of the core classes tracked_objects:: classes. These |
| 134 // serialized representations are designed for safe transmission of the |
| 135 // tracked_objects:: data across process boundaries. Each consists of: |
| 136 // (1) a default constructor, to support the IPC serialization macros, |
| 137 // (2) a simple constructor that extracts data from the type being serialized, |
| 138 // (3) a ToValue() function that writes the serialized data into the passed |
| 139 // |dictionary| -- which will typically then be automatically translated to |
| 140 // JSON for rendering the collected profiler data -- and |
| 141 // (4) the serialized data. |
| 142 // |
132 // For a given birth location, information about births is spread across data | 143 // For a given birth location, information about births is spread across data |
133 // structures that are asynchronously changing on various threads. For display | 144 // structures that are asynchronously changing on various threads. For |
134 // purposes, we need to construct Snapshot instances for each combination of | 145 // serialization and display purposes, we need to construct SerializedSnapshot |
135 // birth thread, death thread, and location, along with the count of such | 146 // instances for each combination of birth thread, death thread, and location, |
136 // lifetimes. We gather such data into a Snapshot instances, so that such | 147 // along with the count of such lifetimes. We gather such data into a |
137 // instances can be sorted and aggregated (and remain frozen during our | 148 // SerializedSnapshot instances, so that such instances can be sorted and |
138 // processing). Snapshot instances use pointers to constant portions of the | 149 // aggregated (and remain frozen during our processing). |
139 // birth and death datastructures, but have local (frozen) copies of the actual | |
140 // statistics (birth count, durations, etc. etc.). | |
141 // | 150 // |
142 // A DataCollector is a container object that holds a set of Snapshots. The | 151 // The SerializedProcessData struct is a serialized representation of the list |
143 // statistics in a snapshot are gathered asynhcronously relative to their | 152 // of ThreadData objects for this process. It holds a set of |
144 // ongoing updates. It is possible, though highly unlikely, that stats could be | 153 // SerializedSnapshots and tracks parent/child relationships for the executed |
145 // incorrectly recorded by this process (all data is held in 32 bit ints, but we | 154 // tasks. The statistics in a snapshot are gathered asynhcronously relative to |
146 // are not atomically collecting all data, so we could have count that does not, | 155 // their ongoing updates. It is possible, though highly unlikely, that stats |
147 // for example, match with the number of durations we accumulated). The | 156 // could be incorrectly recorded by this process (all data is held in 32 bit |
148 // advantage to having fast (non-atomic) updates of the data outweighs the | 157 // ints, but we are not atomically collecting all data, so we could have count |
149 // minimal risk of a singular corrupt statistic snapshot (only the snapshot | 158 // that does not, for example, match with the number of durations we |
150 // could be corrupt, not the underlying and ongoing statistic). In constrast, | 159 // accumulated). The advantage to having fast (non-atomic) updates of the data |
151 // pointer data that is accessed during snapshotting is completely invariant, | 160 // outweighs the minimal risk of a singular corrupt statistic snapshot (only the |
152 // and hence is perfectly acquired (i.e., no potential corruption, and no risk | 161 // snapshot could be corrupt, not the underlying and ongoing statistic). In |
153 // of a bad memory reference). | 162 // constrast, pointer data that is accessed during snapshotting is completely |
154 // | 163 // invariant, and hence is perfectly acquired (i.e., no potential corruption, |
155 // After an array of Snapshots instances are collected into a DataCollector, | 164 // and no risk of a bad memory reference). |
156 // they need to be prepared for displaying our output. We currently implement a | |
157 // serialization into a Value hierarchy, which is automatically translated to | |
158 // JSON when supplied to rendering Java Scirpt. | |
159 // | 165 // |
160 // TODO(jar): We can implement a Snapshot system that *tries* to grab the | 166 // TODO(jar): We can implement a Snapshot system that *tries* to grab the |
161 // snapshots on the source threads *when* they have MessageLoops available | 167 // snapshots on the source threads *when* they have MessageLoops available |
162 // (worker threads don't have message loops generally, and hence gathering from | 168 // (worker threads don't have message loops generally, and hence gathering from |
163 // them will continue to be asynchronous). We had an implementation of this in | 169 // them will continue to be asynchronous). We had an implementation of this in |
164 // the past, but the difficulty is dealing with message loops being terminated. | 170 // the past, but the difficulty is dealing with message loops being terminated. |
165 // We can *try* to spam the available threads via some message loop proxy to | 171 // We can *try* to spam the available threads via some message loop proxy to |
166 // achieve this feat, and it *might* be valuable when we are colecting data for | 172 // achieve this feat, and it *might* be valuable when we are colecting data for |
167 // upload via UMA (where correctness of data may be more significant than for a | 173 // upload via UMA (where correctness of data may be more significant than for a |
168 // single screen of about:profiler). | 174 // single screen of about:profiler). |
(...skipping 20 matching lines...) Expand all Loading... |
189 namespace tracked_objects { | 195 namespace tracked_objects { |
190 | 196 |
191 //------------------------------------------------------------------------------ | 197 //------------------------------------------------------------------------------ |
192 // For a specific thread, and a specific birth place, the collection of all | 198 // For a specific thread, and a specific birth place, the collection of all |
193 // death info (with tallies for each death thread, to prevent access conflicts). | 199 // death info (with tallies for each death thread, to prevent access conflicts). |
194 class ThreadData; | 200 class ThreadData; |
195 class BASE_EXPORT BirthOnThread { | 201 class BASE_EXPORT BirthOnThread { |
196 public: | 202 public: |
197 BirthOnThread(const Location& location, const ThreadData& current); | 203 BirthOnThread(const Location& location, const ThreadData& current); |
198 | 204 |
199 const Location location() const; | 205 const Location location() const { return location_; } |
200 const ThreadData* birth_thread() const; | 206 const ThreadData* birth_thread() const { return birth_thread_; } |
201 | |
202 // Insert our state (location, and thread name) into the dictionary. | |
203 // Use the supplied |prefix| in front of "thread_name" and "location" | |
204 // respectively when defining keys. | |
205 void ToValue(const std::string& prefix, | |
206 base::DictionaryValue* dictionary) const; | |
207 | 207 |
208 private: | 208 private: |
209 // File/lineno of birth. This defines the essence of the task, as the context | 209 // File/lineno of birth. This defines the essence of the task, as the context |
210 // of the birth (construction) often tell what the item is for. This field | 210 // of the birth (construction) often tell what the item is for. This field |
211 // is const, and hence safe to access from any thread. | 211 // is const, and hence safe to access from any thread. |
212 const Location location_; | 212 const Location location_; |
213 | 213 |
214 // The thread that records births into this object. Only this thread is | 214 // The thread that records births into this object. Only this thread is |
215 // allowed to update birth_count_ (which changes over time). | 215 // allowed to update birth_count_ (which changes over time). |
216 const ThreadData* const birth_thread_; | 216 const ThreadData* const birth_thread_; |
217 | 217 |
218 DISALLOW_COPY_AND_ASSIGN(BirthOnThread); | 218 DISALLOW_COPY_AND_ASSIGN(BirthOnThread); |
219 }; | 219 }; |
220 | 220 |
221 //------------------------------------------------------------------------------ | 221 //------------------------------------------------------------------------------ |
| 222 // A serialized representation of the BirthOnThread class. |
| 223 |
| 224 struct BASE_EXPORT SerializedBirthOnThread { |
| 225 SerializedBirthOnThread(); |
| 226 SerializedBirthOnThread(const BirthOnThread& birth); |
| 227 ~SerializedBirthOnThread(); |
| 228 |
| 229 void ToValue(const std::string& prefix, |
| 230 base::DictionaryValue* dictionary) const; |
| 231 |
| 232 SerializedLocation location; |
| 233 std::string thread_name; |
| 234 }; |
| 235 |
| 236 //------------------------------------------------------------------------------ |
222 // A class for accumulating counts of births (without bothering with a map<>). | 237 // A class for accumulating counts of births (without bothering with a map<>). |
223 | 238 |
224 class BASE_EXPORT Births: public BirthOnThread { | 239 class BASE_EXPORT Births: public BirthOnThread { |
225 public: | 240 public: |
226 Births(const Location& location, const ThreadData& current); | 241 Births(const Location& location, const ThreadData& current); |
227 | 242 |
228 int birth_count() const; | 243 int birth_count() const; |
229 | 244 |
230 // When we have a birth we update the count for this BirhPLace. | 245 // When we have a birth we update the count for this birthplace. |
231 void RecordBirth(); | 246 void RecordBirth(); |
232 | 247 |
233 // When a birthplace is changed (updated), we need to decrement the counter | 248 // When a birthplace is changed (updated), we need to decrement the counter |
234 // for the old instance. | 249 // for the old instance. |
235 void ForgetBirth(); | 250 void ForgetBirth(); |
236 | 251 |
237 // Hack to quickly reset all counts to zero. | 252 // Hack to quickly reset all counts to zero. |
238 void Clear(); | 253 void Clear(); |
239 | 254 |
240 private: | 255 private: |
(...skipping 17 matching lines...) Expand all Loading... |
258 // threads, we create DeathData stats that tally the number of births without | 273 // threads, we create DeathData stats that tally the number of births without |
259 // a corresponding death. | 274 // a corresponding death. |
260 explicit DeathData(int count); | 275 explicit DeathData(int count); |
261 | 276 |
262 // Update stats for a task destruction (death) that had a Run() time of | 277 // Update stats for a task destruction (death) that had a Run() time of |
263 // |duration|, and has had a queueing delay of |queue_duration|. | 278 // |duration|, and has had a queueing delay of |queue_duration|. |
264 void RecordDeath(const DurationInt queue_duration, | 279 void RecordDeath(const DurationInt queue_duration, |
265 const DurationInt run_duration, | 280 const DurationInt run_duration, |
266 int random_number); | 281 int random_number); |
267 | 282 |
268 // Metrics accessors, used only in tests. | 283 // Metrics accessors, used only for serialization and in tests. |
269 int count() const; | 284 int count() const; |
270 DurationInt run_duration_sum() const; | 285 DurationInt run_duration_sum() const; |
271 DurationInt run_duration_max() const; | 286 DurationInt run_duration_max() const; |
272 DurationInt run_duration_sample() const; | 287 DurationInt run_duration_sample() const; |
273 DurationInt queue_duration_sum() const; | 288 DurationInt queue_duration_sum() const; |
274 DurationInt queue_duration_max() const; | 289 DurationInt queue_duration_max() const; |
275 DurationInt queue_duration_sample() const; | 290 DurationInt queue_duration_sample() const; |
276 | 291 |
277 // Construct a DictionaryValue instance containing all our stats. The caller | |
278 // assumes ownership of the returned instance. | |
279 base::DictionaryValue* ToValue() const; | |
280 | |
281 // Reset the max values to zero. | 292 // Reset the max values to zero. |
282 void ResetMax(); | 293 void ResetMax(); |
283 | 294 |
284 // Reset all tallies to zero. This is used as a hack on realtime data. | 295 // Reset all tallies to zero. This is used as a hack on realtime data. |
285 void Clear(); | 296 void Clear(); |
286 | 297 |
287 private: | 298 private: |
288 // Members are ordered from most regularly read and updated, to least | 299 // Members are ordered from most regularly read and updated, to least |
289 // frequently used. This might help a bit with cache lines. | 300 // frequently used. This might help a bit with cache lines. |
290 // Number of runs seen (divisor for calculating averages). | 301 // Number of runs seen (divisor for calculating averages). |
291 int count_; | 302 int count_; |
292 // Basic tallies, used to compute averages. | 303 // Basic tallies, used to compute averages. |
293 DurationInt run_duration_sum_; | 304 DurationInt run_duration_sum_; |
294 DurationInt queue_duration_sum_; | 305 DurationInt queue_duration_sum_; |
295 // Max values, used by local visualization routines. These are often read, | 306 // Max values, used by local visualization routines. These are often read, |
296 // but rarely updated. | 307 // but rarely updated. |
297 DurationInt run_duration_max_; | 308 DurationInt run_duration_max_; |
298 DurationInt queue_duration_max_; | 309 DurationInt queue_duration_max_; |
299 // Samples, used by by crowd sourcing gatherers. These are almost never read, | 310 // Samples, used by by crowd sourcing gatherers. These are almost never read, |
300 // and rarely updated. | 311 // and rarely updated. |
301 DurationInt run_duration_sample_; | 312 DurationInt run_duration_sample_; |
302 DurationInt queue_duration_sample_; | 313 DurationInt queue_duration_sample_; |
303 }; | 314 }; |
304 | 315 |
305 //------------------------------------------------------------------------------ | 316 //------------------------------------------------------------------------------ |
| 317 // A serialized representation of the DeathData class. |
| 318 |
| 319 struct BASE_EXPORT SerializedDeathData { |
| 320 SerializedDeathData(); |
| 321 SerializedDeathData(const DeathData& death_data); |
| 322 ~SerializedDeathData(); |
| 323 |
| 324 void ToValue(base::DictionaryValue* dictionary) const; |
| 325 |
| 326 int count; |
| 327 int run_duration_sum; |
| 328 int run_duration_max; |
| 329 int run_duration_sample; |
| 330 int queue_duration_sum; |
| 331 int queue_duration_max; |
| 332 int queue_duration_sample; |
| 333 }; |
| 334 |
| 335 //------------------------------------------------------------------------------ |
306 // A temporary collection of data that can be sorted and summarized. It is | 336 // A temporary collection of data that can be sorted and summarized. It is |
307 // gathered (carefully) from many threads. Instances are held in arrays and | 337 // gathered (carefully) from many threads. Instances are held in arrays and |
308 // processed, filtered, and rendered. | 338 // processed, filtered, and rendered. |
309 // The source of this data was collected on many threads, and is asynchronously | 339 // The source of this data was collected on many threads, and is asynchronously |
310 // changing. The data in this instance is not asynchronously changing. | 340 // changing. The data in this instance is not asynchronously changing. |
311 | 341 |
312 class BASE_EXPORT Snapshot { | 342 struct BASE_EXPORT SerializedSnapshot { |
313 public: | 343 SerializedSnapshot(); |
314 // When snapshotting a full life cycle set (birth-to-death), use this: | 344 SerializedSnapshot(const BirthOnThread& birth, |
315 Snapshot(const BirthOnThread& birth_on_thread, | 345 const DeathData& death_data, |
316 const ThreadData& death_thread, | 346 const std::string& death_thread_name); |
317 const DeathData& death_data); | 347 ~SerializedSnapshot(); |
318 | 348 |
319 // When snapshotting a birth, with no death yet, use this: | 349 void ToValue(base::DictionaryValue* dictionary) const; |
320 Snapshot(const BirthOnThread& birth_on_thread, int count); | |
321 | 350 |
322 // Accessor, that provides default value when there is no death thread. | 351 SerializedBirthOnThread birth; |
323 const std::string DeathThreadName() const; | 352 SerializedDeathData death_data; |
324 | 353 std::string death_thread_name; |
325 // Construct a DictionaryValue instance containing all our data recursively. | |
326 // The caller assumes ownership of the memory in the returned instance. | |
327 base::DictionaryValue* ToValue() const; | |
328 | |
329 private: | |
330 const BirthOnThread* birth_; // Includes Location and birth_thread. | |
331 const ThreadData* death_thread_; | |
332 DeathData death_data_; | |
333 }; | 354 }; |
334 | 355 |
335 //------------------------------------------------------------------------------ | 356 //------------------------------------------------------------------------------ |
336 // For each thread, we have a ThreadData that stores all tracking info generated | 357 // For each thread, we have a ThreadData that stores all tracking info generated |
337 // on this thread. This prevents the need for locking as data accumulates. | 358 // on this thread. This prevents the need for locking as data accumulates. |
338 // We use ThreadLocalStorage to quickly identfy the current ThreadData context. | 359 // We use ThreadLocalStorage to quickly identfy the current ThreadData context. |
339 // We also have a linked list of ThreadData instances, and that list is used to | 360 // We also have a linked list of ThreadData instances, and that list is used to |
340 // harvest data from all existing instances. | 361 // harvest data from all existing instances. |
341 | 362 |
| 363 struct SerializedProcessData; |
342 class BASE_EXPORT ThreadData { | 364 class BASE_EXPORT ThreadData { |
343 public: | 365 public: |
344 // Current allowable states of the tracking system. The states can vary | 366 // Current allowable states of the tracking system. The states can vary |
345 // between ACTIVE and DEACTIVATED, but can never go back to UNINITIALIZED. | 367 // between ACTIVE and DEACTIVATED, but can never go back to UNINITIALIZED. |
346 enum Status { | 368 enum Status { |
347 UNINITIALIZED, // PRistine, link-time state before running. | 369 UNINITIALIZED, // PRistine, link-time state before running. |
348 DORMANT_DURING_TESTS, // Only used during testing. | 370 DORMANT_DURING_TESTS, // Only used during testing. |
349 DEACTIVATED, // No longer recording profling. | 371 DEACTIVATED, // No longer recording profling. |
350 PROFILING_ACTIVE, // Recording profiles (no parent-child links). | 372 PROFILING_ACTIVE, // Recording profiles (no parent-child links). |
351 PROFILING_CHILDREN_ACTIVE, // Fully active, recording parent-child links. | 373 PROFILING_CHILDREN_ACTIVE, // Fully active, recording parent-child links. |
(...skipping 10 matching lines...) Expand all Loading... |
362 // set *before* any births on the threads have taken place. It is generally | 384 // set *before* any births on the threads have taken place. It is generally |
363 // only used by the message loop, which has a well defined thread name. | 385 // only used by the message loop, which has a well defined thread name. |
364 static void InitializeThreadContext(const std::string& suggested_name); | 386 static void InitializeThreadContext(const std::string& suggested_name); |
365 | 387 |
366 // Using Thread Local Store, find the current instance for collecting data. | 388 // Using Thread Local Store, find the current instance for collecting data. |
367 // If an instance does not exist, construct one (and remember it for use on | 389 // If an instance does not exist, construct one (and remember it for use on |
368 // this thread. | 390 // this thread. |
369 // This may return NULL if the system is disabled for any reason. | 391 // This may return NULL if the system is disabled for any reason. |
370 static ThreadData* Get(); | 392 static ThreadData* Get(); |
371 | 393 |
372 // Constructs a DictionaryValue instance containing all recursive results in | 394 // Fills |process_data| with all the recursive results in our process. |
373 // our process. The caller assumes ownership of the memory in the returned | 395 // During the scavenging, if |reset_max| is true, then the DeathData instances |
374 // instance. During the scavenging, if |reset_max| is true, then the | 396 // max-values are reset to zero during this scan. |
375 // DeathData instances max-values are reset to zero during this scan. | 397 static void ToSerializedProcessData(bool reset_max, |
376 static base::DictionaryValue* ToValue(bool reset_max); | 398 SerializedProcessData* process_data); |
377 | 399 |
378 // Finds (or creates) a place to count births from the given location in this | 400 // Finds (or creates) a place to count births from the given location in this |
379 // thread, and increment that tally. | 401 // thread, and increment that tally. |
380 // TallyABirthIfActive will returns NULL if the birth cannot be tallied. | 402 // TallyABirthIfActive will returns NULL if the birth cannot be tallied. |
381 static Births* TallyABirthIfActive(const Location& location); | 403 static Births* TallyABirthIfActive(const Location& location); |
382 | 404 |
383 // Records the end of a timed run of an object. The |completed_task| contains | 405 // Records the end of a timed run of an object. The |completed_task| contains |
384 // a pointer to a Births, the time_posted, and a delayed_start_time if any. | 406 // a pointer to a Births, the time_posted, and a delayed_start_time if any. |
385 // The |start_of_run| indicates when we started to perform the run of the | 407 // The |start_of_run| indicates when we started to perform the run of the |
386 // task. The delayed_start_time is non-null for tasks that were posted as | 408 // task. The delayed_start_time is non-null for tasks that were posted as |
(...skipping 21 matching lines...) Expand all Loading... |
408 | 430 |
409 // Record the end of execution in region, generally corresponding to a scope | 431 // Record the end of execution in region, generally corresponding to a scope |
410 // being exited. | 432 // being exited. |
411 static void TallyRunInAScopedRegionIfTracking( | 433 static void TallyRunInAScopedRegionIfTracking( |
412 const Births* birth, | 434 const Births* birth, |
413 const TrackedTime& start_of_run, | 435 const TrackedTime& start_of_run, |
414 const TrackedTime& end_of_run); | 436 const TrackedTime& end_of_run); |
415 | 437 |
416 const std::string thread_name() const; | 438 const std::string thread_name() const; |
417 | 439 |
418 // Snapshot (under a lock) copies of the maps in each ThreadData instance. For | |
419 // each set of maps (BirthMap, DeathMap, and ParentChildSet) call the Append() | |
420 // method of the |target| DataCollector. If |reset_max| is true, then the max | |
421 // values in each DeathData instance should be reset during the scan. | |
422 static void SendAllMaps(bool reset_max, class DataCollector* target); | |
423 | |
424 // Hack: asynchronously clear all birth counts and death tallies data values | 440 // Hack: asynchronously clear all birth counts and death tallies data values |
425 // in all ThreadData instances. The numerical (zeroing) part is done without | 441 // in all ThreadData instances. The numerical (zeroing) part is done without |
426 // use of a locks or atomics exchanges, and may (for int64 values) produce | 442 // use of a locks or atomics exchanges, and may (for int64 values) produce |
427 // bogus counts VERY rarely. | 443 // bogus counts VERY rarely. |
428 static void ResetAllThreadData(); | 444 static void ResetAllThreadData(); |
429 | 445 |
430 // Initializes all statics if needed (this initialization call should be made | 446 // Initializes all statics if needed (this initialization call should be made |
431 // while we are single threaded). Returns false if unable to initialize. | 447 // while we are single threaded). Returns false if unable to initialize. |
432 static bool Initialize(); | 448 static bool Initialize(); |
433 | 449 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 | 527 |
512 | 528 |
513 // In this thread's data, record a new birth. | 529 // In this thread's data, record a new birth. |
514 Births* TallyABirth(const Location& location); | 530 Births* TallyABirth(const Location& location); |
515 | 531 |
516 // Find a place to record a death on this thread. | 532 // Find a place to record a death on this thread. |
517 void TallyADeath(const Births& birth, | 533 void TallyADeath(const Births& birth, |
518 DurationInt queue_duration, | 534 DurationInt queue_duration, |
519 DurationInt duration); | 535 DurationInt duration); |
520 | 536 |
| 537 // Snapshot (under a lock) the profiled data for the tasks in each ThreadData |
| 538 // instance. Also updates the |birth_counts| tally for each task to keep |
| 539 // track of the number of living instances of the task. If |reset_max| is |
| 540 // true, then the max values in each DeathData instance should be reset during |
| 541 // the scan. |
| 542 static void SerializeAllExecutedTasks( |
| 543 bool reset_max, |
| 544 SerializedProcessData* process_data, |
| 545 std::map<const BirthOnThread*, int>* birth_counts); |
| 546 |
| 547 // Snapshots (under a lock) the profiled data for the tasks for this thread |
| 548 // and serializes all of the executed tasks' data -- i.e. the data for the |
| 549 // tasks with with entries in the death_map_ -- into |process_data|. Also |
| 550 // updates the |birth_counts| tally for each task to keep track of the number |
| 551 // of living instances of the task. If |reset_max| is true, then the max |
| 552 // values in each DeathData instance should be reset during the scan. |
| 553 void SerializeExecutedTasks( |
| 554 bool reset_max, |
| 555 SerializedProcessData* process_data, |
| 556 std::map<const BirthOnThread*, int>* birth_counts); |
| 557 |
521 // Using our lock, make a copy of the specified maps. This call may be made | 558 // Using our lock, make a copy of the specified maps. This call may be made |
522 // on non-local threads, which necessitate the use of the lock to prevent | 559 // on non-local threads, which necessitate the use of the lock to prevent |
523 // the map(s) from being reallocaed while they are copied. If |reset_max| is | 560 // the map(s) from being reallocaed while they are copied. If |reset_max| is |
524 // true, then, just after we copy the DeathMap, we will set the max values to | 561 // true, then, just after we copy the DeathMap, we will set the max values to |
525 // zero in the active DeathMap (not the snapshot). | 562 // zero in the active DeathMap (not the snapshot). |
526 void SnapshotMaps(bool reset_max, | 563 void SnapshotMaps(bool reset_max, |
527 BirthMap* birth_map, | 564 BirthMap* birth_map, |
528 DeathMap* death_map, | 565 DeathMap* death_map, |
529 ParentChildSet* parent_child_set); | 566 ParentChildSet* parent_child_set); |
530 | 567 |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
655 // Record of what the incarnation_counter_ was when this instance was created. | 692 // Record of what the incarnation_counter_ was when this instance was created. |
656 // If the incarnation_counter_ has changed, then we avoid pushing into the | 693 // If the incarnation_counter_ has changed, then we avoid pushing into the |
657 // pool (this is only critical in tests which go through multiple | 694 // pool (this is only critical in tests which go through multiple |
658 // incarnations). | 695 // incarnations). |
659 int incarnation_count_for_pool_; | 696 int incarnation_count_for_pool_; |
660 | 697 |
661 DISALLOW_COPY_AND_ASSIGN(ThreadData); | 698 DISALLOW_COPY_AND_ASSIGN(ThreadData); |
662 }; | 699 }; |
663 | 700 |
664 //------------------------------------------------------------------------------ | 701 //------------------------------------------------------------------------------ |
665 // DataCollector is a container class for Snapshot and BirthOnThread count | 702 // A serialized representation of a (parent, child) task pair, for tracking |
666 // items. | 703 // hierarchical profiles. |
667 | 704 |
668 class BASE_EXPORT DataCollector { | 705 struct BASE_EXPORT SerializedParentChildPair { |
669 public: | 706 public: |
670 typedef std::vector<Snapshot> Collection; | 707 SerializedParentChildPair(); |
| 708 SerializedParentChildPair(const ThreadData::ParentChildPair& parent_child); |
| 709 ~SerializedParentChildPair(); |
671 | 710 |
672 // Construct with a list of how many threads should contribute. This helps us | |
673 // determine (in the async case) when we are done with all contributions. | |
674 DataCollector(); | |
675 ~DataCollector(); | |
676 | |
677 // Adds all stats from the indicated thread into our arrays. Accepts copies | |
678 // of the birth_map and death_map, so that the data will not change during the | |
679 // iterations and processing. | |
680 void Append(const ThreadData &thread_data, | |
681 const ThreadData::BirthMap& birth_map, | |
682 const ThreadData::DeathMap& death_map, | |
683 const ThreadData::ParentChildSet& parent_child_set); | |
684 | |
685 // After the accumulation phase, the following accessor is used to process the | |
686 // data (i.e., sort it, filter it, etc.). | |
687 Collection* collection(); | |
688 | |
689 // Adds entries for all the remaining living objects (objects that have | |
690 // tallied a birth, but have not yet tallied a matching death, and hence must | |
691 // be either running, queued up, or being held in limbo for future posting). | |
692 // This should be called after all known ThreadData instances have been | |
693 // processed using Append(). | |
694 void AddListOfLivingObjects(); | |
695 | |
696 // Generates a ListValue representation of the vector of snapshots, and | |
697 // inserts the results into |dictionary|. | |
698 void ToValue(base::DictionaryValue* dictionary) const; | 711 void ToValue(base::DictionaryValue* dictionary) const; |
699 | 712 |
700 private: | 713 SerializedBirthOnThread parent; |
701 typedef std::map<const BirthOnThread*, int> BirthCount; | 714 SerializedBirthOnThread child; |
| 715 }; |
702 | 716 |
703 // The array that we collect data into. | 717 // |
704 Collection collection_; | 718 // A serialized representation of the list of ThreadData objects for a process. |
705 | 719 |
706 // The total number of births recorded at each location for which we have not | 720 struct BASE_EXPORT SerializedProcessData { |
707 // seen a death count. This map changes as we do Append() calls, and is later | 721 public: |
708 // used by AddListOfLivingObjects() to gather up unaccounted for births. | 722 SerializedProcessData(); |
709 BirthCount global_birth_count_; | 723 ~SerializedProcessData(); |
710 | 724 |
711 // The complete list of parent-child relationships among tasks. | 725 void ToValue(base::DictionaryValue* dictionary) const; |
712 ThreadData::ParentChildSet parent_child_set_; | |
713 | 726 |
714 DISALLOW_COPY_AND_ASSIGN(DataCollector); | 727 std::vector<SerializedSnapshot> snapshots; |
| 728 std::vector<SerializedParentChildPair> descendants; |
| 729 int process_id; |
715 }; | 730 }; |
716 | 731 |
717 } // namespace tracked_objects | 732 } // namespace tracked_objects |
718 | 733 |
719 #endif // BASE_TRACKED_OBJECTS_H_ | 734 #endif // BASE_TRACKED_OBJECTS_H_ |
OLD | NEW |