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 <map> | 8 #include <map> |
9 #include <set> | 9 #include <set> |
10 #include <stack> | 10 #include <stack> |
11 #include <string> | 11 #include <string> |
12 #include <utility> | 12 #include <utility> |
13 #include <vector> | 13 #include <vector> |
14 | 14 |
15 #include "base/base_export.h" | 15 #include "base/base_export.h" |
16 #include "base/basictypes.h" | 16 #include "base/basictypes.h" |
17 #include "base/containers/hash_tables.h" | 17 #include "base/containers/hash_tables.h" |
18 #include "base/gtest_prod_util.h" | 18 #include "base/gtest_prod_util.h" |
19 #include "base/lazy_instance.h" | 19 #include "base/lazy_instance.h" |
20 #include "base/location.h" | 20 #include "base/location.h" |
21 #include "base/process/process_handle.h" | 21 #include "base/process/process_handle.h" |
22 #include "base/profiler/alternate_timer.h" | 22 #include "base/profiler/alternate_timer.h" |
23 #include "base/profiler/tracked_time.h" | 23 #include "base/profiler/tracked_time.h" |
24 #include "base/synchronization/lock.h" | 24 #include "base/synchronization/lock.h" |
25 #include "base/threading/thread_checker.h" | |
25 #include "base/threading/thread_local_storage.h" | 26 #include "base/threading/thread_local_storage.h" |
26 | 27 |
27 namespace base { | 28 namespace base { |
28 struct TrackingInfo; | 29 struct TrackingInfo; |
29 } | 30 } |
30 | 31 |
31 // TrackedObjects provides a database of stats about objects (generally Tasks) | 32 // TrackedObjects provides a database of stats about objects (generally Tasks) |
32 // that are tracked. Tracking means their birth, death, duration, birth thread, | 33 // that are tracked. Tracking means their birth, death, duration, birth thread, |
33 // death thread, and birth place are recorded. This data is carefully spread | 34 // death thread, and birth place are recorded. This data is carefully spread |
34 // across a series of objects so that the counts and times can be rapidly | 35 // across a series of objects so that the counts and times can be rapidly |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
247 void RecordBirth(); | 248 void RecordBirth(); |
248 | 249 |
249 private: | 250 private: |
250 // The number of births on this thread for our location_. | 251 // The number of births on this thread for our location_. |
251 int birth_count_; | 252 int birth_count_; |
252 | 253 |
253 DISALLOW_COPY_AND_ASSIGN(Births); | 254 DISALLOW_COPY_AND_ASSIGN(Births); |
254 }; | 255 }; |
255 | 256 |
256 //------------------------------------------------------------------------------ | 257 //------------------------------------------------------------------------------ |
257 // Basic info summarizing multiple destructions of a tracked object with a | 258 // A "snapshotted" representation of the DeathData class. |
258 // single birthplace (fixed Location). Used both on specific threads, and also | 259 |
259 // in snapshots when integrating assembled data. | 260 struct BASE_EXPORT DeathDataSnapshot { |
261 DeathDataSnapshot(); | |
262 | |
263 // Constructs the snapshot from individual values. | |
264 // The alternative would be taking a DeathData parameter, but this would | |
265 // create a loop since DeathData indirectly refers DeathDataSnapshot. Passing | |
266 // a wrapper structure as a param or using an empty constructor for | |
267 // snapshotting DeathData would be less efficient. | |
268 DeathDataSnapshot(int count, | |
269 int32 run_duration_sum, | |
270 int32 run_duration_max, | |
271 int32 run_duration_sample, | |
272 int32 queue_duration_sum, | |
273 int32 queue_duration_max, | |
274 int32 queue_duration_sample); | |
275 ~DeathDataSnapshot(); | |
276 | |
277 // Calculates and returns the delta between this snapshot and an earlier | |
278 // snapshot of the same task |older|. | |
279 DeathDataSnapshot Delta(const DeathDataSnapshot& older) const; | |
280 | |
281 int count; | |
282 int32 run_duration_sum; | |
283 int32 run_duration_max; | |
284 int32 run_duration_sample; | |
285 int32 queue_duration_sum; | |
286 int32 queue_duration_max; | |
287 int32 queue_duration_sample; | |
288 }; | |
289 | |
290 //------------------------------------------------------------------------------ | |
291 // A "snapshotted" representation of the DeathData for a particular profiling | |
292 // phase. Used as an element of the list of phase snapshots owned by DeathData. | |
293 | |
294 struct DeathDataPhaseSnapshot { | |
295 DeathDataPhaseSnapshot(int profiling_phase, | |
296 int count, | |
297 int32 run_duration_sum, | |
298 int32 run_duration_max, | |
299 int32 run_duration_sample, | |
300 int32 queue_duration_sum, | |
301 int32 queue_duration_max, | |
302 int32 queue_duration_sample, | |
303 DeathDataPhaseSnapshot* prev); | |
304 | |
305 // Profiling phase at which completion this snapshot was taken. | |
306 int profiling_phase; | |
307 | |
308 // Death data snapshot. | |
309 DeathDataSnapshot death_data; | |
310 | |
311 // Pointer to a snapshot from the previous phase. | |
312 DeathDataPhaseSnapshot* prev; | |
313 }; | |
314 | |
315 //------------------------------------------------------------------------------ | |
316 // Information about deaths of a task on a given thread, called "death thread". | |
317 // Access to members of this class is never protected by the lock. The fields | |
Ilya Sherman
2015/04/17 02:14:27
nit: s/the lock/a lock
vadimt
2015/04/17 16:15:51
Done.
| |
318 // are accessed in such a way that corruptions resulting from race conditions | |
319 // are not significant, and don't accumulate as a result of multiple accesses. | |
320 // All snapshots and phase change notifications must be called from the same | |
321 // thread. It doesn't matter what thread it is, but it's important the same | |
Ilya Sherman
2015/04/17 02:14:26
I find the sentence "All snapshot and phase change
vadimt
2015/04/17 16:15:51
Done.
| |
322 // thread is used as a snapshot thread during the whole process lifetime. | |
323 // All fields except sample_probability_count_ can be snapshotted. | |
260 | 324 |
261 class BASE_EXPORT DeathData { | 325 class BASE_EXPORT DeathData { |
262 public: | 326 public: |
263 // Default initializer. | |
264 DeathData(); | 327 DeathData(); |
265 | 328 DeathData(const DeathData& other); |
266 // When deaths have not yet taken place, and we gather data from all the | 329 ~DeathData(); |
267 // threads, we create DeathData stats that tally the number of births without | |
268 // a corresponding death. | |
269 explicit DeathData(int count); | |
270 | 330 |
271 // Update stats for a task destruction (death) that had a Run() time of | 331 // Update stats for a task destruction (death) that had a Run() time of |
272 // |duration|, and has had a queueing delay of |queue_duration|. | 332 // |duration|, and has had a queueing delay of |queue_duration|. |
273 void RecordDeath(const int32 queue_duration, | 333 void RecordDeath(const int32 queue_duration, |
274 const int32 run_duration, | 334 const int32 run_duration, |
275 const uint32 random_number); | 335 const uint32 random_number); |
276 | 336 |
277 // Metrics accessors, used only for serialization and in tests. | 337 // Metrics and past snapshots accessors, used only for serialization and in |
338 // tests. | |
278 int count() const; | 339 int count() const; |
279 int32 run_duration_sum() const; | 340 int32 run_duration_sum() const; |
280 int32 run_duration_max() const; | 341 int32 run_duration_max() const; |
281 int32 run_duration_sample() const; | 342 int32 run_duration_sample() const; |
282 int32 queue_duration_sum() const; | 343 int32 queue_duration_sum() const; |
283 int32 queue_duration_max() const; | 344 int32 queue_duration_max() const; |
284 int32 queue_duration_sample() const; | 345 int32 queue_duration_sample() const; |
346 DeathDataPhaseSnapshot* last_phase_snapshot() const; | |
Ilya Sherman
2015/04/17 02:14:27
nit: Const methods should never return non-const p
vadimt
2015/04/17 16:15:51
Done.
| |
285 | 347 |
286 // Reset all tallies to zero. This is used as a hack on realtime data. | 348 // Called when the current profiling phase, identified by |profiling_phase|, |
287 void Clear(); | 349 // ends. |
350 // Must be called only on the snapshot thread. | |
351 void OnProfilingPhaseCompleted(int profiling_phase); | |
288 | 352 |
289 private: | 353 private: |
290 // Members are ordered from most regularly read and updated, to least | 354 // Members are ordered from most regularly read and updated, to least |
291 // frequently used. This might help a bit with cache lines. | 355 // frequently used. This might help a bit with cache lines. |
292 // Number of runs seen (divisor for calculating averages). | 356 // Number of runs seen (divisor for calculating averages). |
357 // Can be incremented only on the death thread. | |
293 int count_; | 358 int count_; |
294 // Basic tallies, used to compute averages. | 359 |
360 // Count used in determining probability of selecting exec/queue times from a | |
361 // recorded death as samples. | |
362 // Gets incremented only on the death thread, but can be set to 0 by | |
363 // OnProfilingPhaseCompleted() on the snapshot thread. | |
364 int sample_probability_count_; | |
365 | |
366 // Basic tallies, used to compute averages. Can be incremented only on the | |
367 // death thread. | |
295 int32 run_duration_sum_; | 368 int32 run_duration_sum_; |
296 int32 queue_duration_sum_; | 369 int32 queue_duration_sum_; |
297 // Max values, used by local visualization routines. These are often read, | 370 // Max values, used by local visualization routines. These are often read, |
298 // but rarely updated. | 371 // but rarely updated. The max values get assigned only on the death thread, |
372 // but these fields can be set to 0 by OnProfilingPhaseCompleted() on the | |
373 // snapshot thread. | |
299 int32 run_duration_max_; | 374 int32 run_duration_max_; |
300 int32 queue_duration_max_; | 375 int32 queue_duration_max_; |
301 // Samples, used by crowd sourcing gatherers. These are almost never read, | 376 // Samples, used by crowd sourcing gatherers. These are almost never read, |
302 // and rarely updated. | 377 // and rarely updated. They can be modified only on the death thread. |
Ilya Sherman
2015/04/17 02:14:27
nit: The existing comments in this file seem to us
vadimt
2015/04/17 16:15:51
Done.
| |
303 int32 run_duration_sample_; | 378 int32 run_duration_sample_; |
304 int32 queue_duration_sample_; | 379 int32 queue_duration_sample_; |
380 | |
381 // Snapshot of this death data made at the last profiling phase completion, if | |
382 // any. DeathData owns the whole list starting with this pointer. | |
383 // Can be accessed only on the snapshot thread. | |
384 DeathDataPhaseSnapshot* last_phase_snapshot_; | |
385 | |
386 // Private assignment operator to disallow assignments. | |
387 void operator=(DeathData const&); | |
Ilya Sherman
2015/04/17 02:14:26
nit: Please use DISALLOW_ASSIGN.
| |
305 }; | 388 }; |
306 | 389 |
307 //------------------------------------------------------------------------------ | 390 //------------------------------------------------------------------------------ |
308 // A "snapshotted" representation of the DeathData class. | |
309 | |
310 struct BASE_EXPORT DeathDataSnapshot { | |
311 DeathDataSnapshot(); | |
312 explicit DeathDataSnapshot(const DeathData& death_data); | |
313 ~DeathDataSnapshot(); | |
314 | |
315 int count; | |
316 int32 run_duration_sum; | |
317 int32 run_duration_max; | |
318 int32 run_duration_sample; | |
319 int32 queue_duration_sum; | |
320 int32 queue_duration_max; | |
321 int32 queue_duration_sample; | |
322 }; | |
323 | |
324 //------------------------------------------------------------------------------ | |
325 // A temporary collection of data that can be sorted and summarized. It is | 391 // A temporary collection of data that can be sorted and summarized. It is |
326 // gathered (carefully) from many threads. Instances are held in arrays and | 392 // gathered (carefully) from many threads. Instances are held in arrays and |
327 // processed, filtered, and rendered. | 393 // processed, filtered, and rendered. |
328 // The source of this data was collected on many threads, and is asynchronously | 394 // The source of this data was collected on many threads, and is asynchronously |
329 // changing. The data in this instance is not asynchronously changing. | 395 // changing. The data in this instance is not asynchronously changing. |
330 | 396 |
331 struct BASE_EXPORT TaskSnapshot { | 397 struct BASE_EXPORT TaskSnapshot { |
332 TaskSnapshot(); | 398 TaskSnapshot(); |
333 TaskSnapshot(const BirthOnThread& birth, | 399 TaskSnapshot(const BirthOnThreadSnapshot& birth, |
334 const DeathData& death_data, | 400 const DeathDataSnapshot& death_data, |
335 const std::string& death_thread_name); | 401 const std::string& death_thread_name); |
336 ~TaskSnapshot(); | 402 ~TaskSnapshot(); |
337 | 403 |
338 BirthOnThreadSnapshot birth; | 404 BirthOnThreadSnapshot birth; |
405 // Delta between death data for a thread for a certain profiling phase and the | |
406 // snapshot for the pervious phase, if any. Otherwise, just a snapshot. | |
339 DeathDataSnapshot death_data; | 407 DeathDataSnapshot death_data; |
340 std::string death_thread_name; | 408 std::string death_thread_name; |
341 }; | 409 }; |
342 | 410 |
343 //------------------------------------------------------------------------------ | 411 //------------------------------------------------------------------------------ |
344 // For each thread, we have a ThreadData that stores all tracking info generated | 412 // For each thread, we have a ThreadData that stores all tracking info generated |
345 // on this thread. This prevents the need for locking as data accumulates. | 413 // on this thread. This prevents the need for locking as data accumulates. |
346 // We use ThreadLocalStorage to quickly identfy the current ThreadData context. | 414 // We use ThreadLocalStorage to quickly identfy the current ThreadData context. |
347 // We also have a linked list of ThreadData instances, and that list is used to | 415 // We also have a linked list of ThreadData instances, and that list is used to |
348 // harvest data from all existing instances. | 416 // harvest data from all existing instances. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
381 // only used by the message loop, which has a well defined thread name. | 449 // only used by the message loop, which has a well defined thread name. |
382 static void InitializeThreadContext(const std::string& suggested_name); | 450 static void InitializeThreadContext(const std::string& suggested_name); |
383 | 451 |
384 // Using Thread Local Store, find the current instance for collecting data. | 452 // Using Thread Local Store, find the current instance for collecting data. |
385 // If an instance does not exist, construct one (and remember it for use on | 453 // If an instance does not exist, construct one (and remember it for use on |
386 // this thread. | 454 // this thread. |
387 // This may return NULL if the system is disabled for any reason. | 455 // This may return NULL if the system is disabled for any reason. |
388 static ThreadData* Get(); | 456 static ThreadData* Get(); |
389 | 457 |
390 // Fills |process_data_snapshot| with phased snapshots of all profiling | 458 // Fills |process_data_snapshot| with phased snapshots of all profiling |
391 // phases, including the current one. | 459 // phases, including the current one, identified by |current_profiling_phase|. |
392 static void Snapshot(ProcessDataSnapshot* process_data_snapshot); | 460 // |current_profiling_phase| is necessary because a child process can start |
461 // after several phase-changing events, so it needs to receive the current | |
462 // phase number from the browser process to fill the correct entry for the | |
463 // current phase in the |process_data_snapshot| map. | |
464 static void Snapshot(int current_profiling_phase, | |
465 ProcessDataSnapshot* process_data_snapshot); | |
466 | |
467 // Called when the current profiling phase, identified by |profiling_phase|, | |
468 // ends. | |
469 // |profiling_phase| is necessary because a child process can start after | |
470 // several phase-changing events, so it needs to receive the phase number from | |
471 // the browser process to fill the correct entry in the | |
472 // completed_phases_snapshots_ map. | |
473 static void OnProfilingPhaseCompleted(int profiling_phase); | |
393 | 474 |
394 // Finds (or creates) a place to count births from the given location in this | 475 // Finds (or creates) a place to count births from the given location in this |
395 // thread, and increment that tally. | 476 // thread, and increment that tally. |
396 // TallyABirthIfActive will returns NULL if the birth cannot be tallied. | 477 // TallyABirthIfActive will returns NULL if the birth cannot be tallied. |
397 static Births* TallyABirthIfActive(const Location& location); | 478 static Births* TallyABirthIfActive(const Location& location); |
398 | 479 |
399 // Records the end of a timed run of an object. The |completed_task| contains | 480 // Records the end of a timed run of an object. The |completed_task| contains |
400 // a pointer to a Births, the time_posted, and a delayed_start_time if any. | 481 // a pointer to a Births, the time_posted, and a delayed_start_time if any. |
401 // The |start_of_run| indicates when we started to perform the run of the | 482 // The |start_of_run| indicates when we started to perform the run of the |
402 // task. The delayed_start_time is non-null for tasks that were posted as | 483 // task. The delayed_start_time is non-null for tasks that were posted as |
403 // delayed tasks, and it indicates when the task should have run (i.e., when | 484 // delayed tasks, and it indicates when the task should have run (i.e., when |
404 // it should have posted out of the timer queue, and into the work queue. | 485 // it should have posted out of the timer queue, and into the work queue. |
405 // The |end_of_run| was just obtained by a call to Now() (just after the task | 486 // The |end_of_run| was just obtained by a call to Now() (just after the task |
406 // finished). It is provided as an argument to help with testing. | 487 // finished). It is provided as an argument to help with testing. |
407 static void TallyRunOnNamedThreadIfTracking( | 488 static void TallyRunOnNamedThreadIfTracking( |
408 const base::TrackingInfo& completed_task, | 489 const base::TrackingInfo& completed_task, |
409 const TaskStopwatch& stopwatch); | 490 const TaskStopwatch& stopwatch); |
410 | 491 |
411 // Record the end of a timed run of an object. The |birth| is the record for | 492 // Record the end of a timed run of an object. The |birth| is the record for |
412 // the instance, the |time_posted| records that instant, which is presumed to | 493 // the instance, the |time_posted| records that instant, which is presumed to |
413 // be when the task was posted into a queue to run on a worker thread. | 494 // be when the task was posted into a queue to run on a worker thread. |
414 // The |start_of_run| is when the worker thread started to perform the run of | 495 // The |start_of_run| is when the worker thread started to perform the run of |
415 // the task. | 496 // the task. |
416 // The |end_of_run| was just obtained by a call to Now() (just after the task | 497 // The |end_of_run| was just obtained by a call to Now() (just after the task |
417 // finished). | 498 // finished). |
418 static void TallyRunOnWorkerThreadIfTracking(const Births* birth, | 499 static void TallyRunOnWorkerThreadIfTracking(const Births* births, |
419 const TrackedTime& time_posted, | 500 const TrackedTime& time_posted, |
420 const TaskStopwatch& stopwatch); | 501 const TaskStopwatch& stopwatch); |
421 | 502 |
422 // Record the end of execution in region, generally corresponding to a scope | 503 // Record the end of execution in region, generally corresponding to a scope |
423 // being exited. | 504 // being exited. |
424 static void TallyRunInAScopedRegionIfTracking(const Births* birth, | 505 static void TallyRunInAScopedRegionIfTracking(const Births* births, |
425 const TaskStopwatch& stopwatch); | 506 const TaskStopwatch& stopwatch); |
426 | 507 |
427 const std::string& thread_name() const { return thread_name_; } | 508 const std::string& thread_name() const { return thread_name_; } |
428 | 509 |
429 // Initializes all statics if needed (this initialization call should be made | 510 // Initializes all statics if needed (this initialization call should be made |
430 // while we are single threaded). Returns false if unable to initialize. | 511 // while we are single threaded). Returns false if unable to initialize. |
431 static bool Initialize(); | 512 static bool Initialize(); |
432 | 513 |
433 // Sets internal status_. | 514 // Sets internal status_. |
434 // If |status| is false, then status_ is set to DEACTIVATED. | 515 // If |status| is false, then status_ is set to DEACTIVATED. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
486 // TODO(jar): Make this a friend in DEBUG only, so that the optimizer has a | 567 // TODO(jar): Make this a friend in DEBUG only, so that the optimizer has a |
487 // better change of optimizing (inlining? etc.) private methods (knowing that | 568 // better change of optimizing (inlining? etc.) private methods (knowing that |
488 // there will be no need for an external entry point). | 569 // there will be no need for an external entry point). |
489 friend class TrackedObjectsTest; | 570 friend class TrackedObjectsTest; |
490 FRIEND_TEST_ALL_PREFIXES(TrackedObjectsTest, MinimalStartupShutdown); | 571 FRIEND_TEST_ALL_PREFIXES(TrackedObjectsTest, MinimalStartupShutdown); |
491 FRIEND_TEST_ALL_PREFIXES(TrackedObjectsTest, TinyStartupShutdown); | 572 FRIEND_TEST_ALL_PREFIXES(TrackedObjectsTest, TinyStartupShutdown); |
492 FRIEND_TEST_ALL_PREFIXES(TrackedObjectsTest, ParentChildTest); | 573 FRIEND_TEST_ALL_PREFIXES(TrackedObjectsTest, ParentChildTest); |
493 | 574 |
494 typedef std::map<const BirthOnThread*, int> BirthCountMap; | 575 typedef std::map<const BirthOnThread*, int> BirthCountMap; |
495 | 576 |
577 typedef std::vector<std::pair<const Births*, DeathDataPhaseSnapshot>> | |
578 DeathsSnapshot; | |
579 | |
496 // Worker thread construction creates a name since there is none. | 580 // Worker thread construction creates a name since there is none. |
497 explicit ThreadData(int thread_number); | 581 explicit ThreadData(int thread_number); |
498 | 582 |
499 // Message loop based construction should provide a name. | 583 // Message loop based construction should provide a name. |
500 explicit ThreadData(const std::string& suggested_name); | 584 explicit ThreadData(const std::string& suggested_name); |
501 | 585 |
502 ~ThreadData(); | 586 ~ThreadData(); |
503 | 587 |
504 // Push this instance to the head of all_thread_data_list_head_, linking it to | 588 // Push this instance to the head of all_thread_data_list_head_, linking it to |
505 // the previous head. This is performed after each construction, and leaves | 589 // the previous head. This is performed after each construction, and leaves |
506 // the instance permanently on that list. | 590 // the instance permanently on that list. |
507 void PushToHeadOfList(); | 591 void PushToHeadOfList(); |
508 | 592 |
509 // (Thread safe) Get start of list of all ThreadData instances using the lock. | 593 // (Thread safe) Get start of list of all ThreadData instances using the lock. |
510 static ThreadData* first(); | 594 static ThreadData* first(); |
511 | 595 |
512 // Iterate through the null terminated list of ThreadData instances. | 596 // Iterate through the null terminated list of ThreadData instances. |
513 ThreadData* next() const; | 597 ThreadData* next() const; |
514 | 598 |
515 | 599 |
516 // In this thread's data, record a new birth. | 600 // In this thread's data, record a new birth. |
517 Births* TallyABirth(const Location& location); | 601 Births* TallyABirth(const Location& location); |
518 | 602 |
519 // Find a place to record a death on this thread. | 603 // Find a place to record a death on this thread. |
520 void TallyADeath(const Births& birth, | 604 void TallyADeath(const Births& births, |
521 int32 queue_duration, | 605 int32 queue_duration, |
522 const TaskStopwatch& stopwatch); | 606 const TaskStopwatch& stopwatch); |
523 | 607 |
524 // Snapshot (under a lock) the profiled data for the tasks in each ThreadData | |
525 // instance. Also updates the |birth_counts| tally for each task to keep | |
526 // track of the number of living instances of the task. | |
527 static void SnapshotAllExecutedTasks( | |
528 ProcessDataPhaseSnapshot* process_data_phase, | |
529 BirthCountMap* birth_counts); | |
530 | |
531 // Fills |process_data_phase| with all the recursive results in our process. | |
532 static void SnapshotCurrentPhase( | |
533 ProcessDataPhaseSnapshot* process_data_phase); | |
534 | |
535 // Snapshots (under a lock) the profiled data for the tasks for this thread | 608 // Snapshots (under a lock) the profiled data for the tasks for this thread |
536 // and writes all of the executed tasks' data -- i.e. the data for the tasks | 609 // and writes all of the executed tasks' data -- i.e. the data for all |
537 // with with entries in the death_map_ -- into |process_data_phase|. Also | 610 // profiling phases (including the current one: |current_profiling_phase|) for |
538 // updates the |birth_counts| tally for each task to keep track of the number | 611 // the tasks with with entries in the death_map_ -- into |phased_snapshots|. |
539 // of living instances of the task -- that is, each task maps to the number of | 612 // Also updates the |birth_counts| tally for each task to keep track of the |
540 // births for the task that have not yet been balanced by a death. | 613 // number of living instances of the task -- that is, each task maps to the |
541 void SnapshotExecutedTasks(ProcessDataPhaseSnapshot* process_data_phase, | 614 // number of births for the task that have not yet been balanced by a death. |
615 void SnapshotExecutedTasks(int current_profiling_phase, | |
616 PhasedProcessDataSnapshotMap* phased_snapshots, | |
542 BirthCountMap* birth_counts); | 617 BirthCountMap* birth_counts); |
543 | 618 |
544 // Using our lock, make a copy of the specified maps. This call may be made | 619 // Using our lock, make a copy of the specified maps. This call may be made |
545 // on non-local threads, which necessitate the use of the lock to prevent | 620 // on non-local threads, which necessitate the use of the lock to prevent |
546 // the map(s) from being reallocated while they are copied. | 621 // the map(s) from being reallocated while they are copied. |
547 void SnapshotMaps(BirthMap* birth_map, | 622 void SnapshotMaps(int profiling_phase, |
548 DeathMap* death_map, | 623 BirthMap* birth_map, |
624 DeathsSnapshot* deaths, | |
549 ParentChildSet* parent_child_set); | 625 ParentChildSet* parent_child_set); |
550 | 626 |
627 // Called for this thread when the current profiling phase, identified by | |
628 // |profiling_phase|, ends. | |
629 void OnProfilingPhaseCompletedOnThread(int profiling_phase); | |
630 | |
551 // This method is called by the TLS system when a thread terminates. | 631 // This method is called by the TLS system when a thread terminates. |
552 // The argument may be NULL if this thread has never tracked a birth or death. | 632 // The argument may be NULL if this thread has never tracked a birth or death. |
553 static void OnThreadTermination(void* thread_data); | 633 static void OnThreadTermination(void* thread_data); |
554 | 634 |
555 // This method should be called when a worker thread terminates, so that we | 635 // This method should be called when a worker thread terminates, so that we |
556 // can save all the thread data into a cache of reusable ThreadData instances. | 636 // can save all the thread data into a cache of reusable ThreadData instances. |
557 void OnThreadTerminationCleanup(); | 637 void OnThreadTerminationCleanup(); |
558 | 638 |
559 // Cleans up data structures, and returns statics to near pristine (mostly | 639 // Cleans up data structures, and returns statics to near pristine (mostly |
560 // uninitialized) state. If there is any chance that other threads are still | 640 // uninitialized) state. If there is any chance that other threads are still |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
602 // we've either transitioned out of UNINITIALIZED, or into that state. This | 682 // we've either transitioned out of UNINITIALIZED, or into that state. This |
603 // value is only accessed while the list_lock_ is held. | 683 // value is only accessed while the list_lock_ is held. |
604 static int incarnation_counter_; | 684 static int incarnation_counter_; |
605 | 685 |
606 // Protection for access to all_thread_data_list_head_, and to | 686 // Protection for access to all_thread_data_list_head_, and to |
607 // unregistered_thread_data_pool_. This lock is leaked at shutdown. | 687 // unregistered_thread_data_pool_. This lock is leaked at shutdown. |
608 // The lock is very infrequently used, so we can afford to just make a lazy | 688 // The lock is very infrequently used, so we can afford to just make a lazy |
609 // instance and be safe. | 689 // instance and be safe. |
610 static base::LazyInstance<base::Lock>::Leaky list_lock_; | 690 static base::LazyInstance<base::Lock>::Leaky list_lock_; |
611 | 691 |
692 // Checker that all snapshots and phase change notifications happen in the | |
693 // same thread. | |
694 static base::LazyInstance<base::ThreadChecker>::Leaky | |
695 snapshot_thread_checker_; | |
696 | |
612 // We set status_ to SHUTDOWN when we shut down the tracking service. | 697 // We set status_ to SHUTDOWN when we shut down the tracking service. |
613 static Status status_; | 698 static Status status_; |
614 | 699 |
615 // Link to next instance (null terminated list). Used to globally track all | 700 // Link to next instance (null terminated list). Used to globally track all |
616 // registered instances (corresponds to all registered threads where we keep | 701 // registered instances (corresponds to all registered threads where we keep |
617 // data). | 702 // data). |
618 ThreadData* next_; | 703 ThreadData* next_; |
619 | 704 |
620 // Pointer to another ThreadData instance for a Worker-Thread that has been | 705 // Pointer to another ThreadData instance for a Worker-Thread that has been |
621 // retired (its thread was terminated). This value is non-NULL only for a | 706 // retired (its thread was terminated). This value is non-NULL only for a |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
776 | 861 |
777 //------------------------------------------------------------------------------ | 862 //------------------------------------------------------------------------------ |
778 // A snapshotted representation of the list of ThreadData objects for a process, | 863 // A snapshotted representation of the list of ThreadData objects for a process, |
779 // for all profiling phases, including the current one. | 864 // for all profiling phases, including the current one. |
780 | 865 |
781 struct BASE_EXPORT ProcessDataSnapshot { | 866 struct BASE_EXPORT ProcessDataSnapshot { |
782 public: | 867 public: |
783 ProcessDataSnapshot(); | 868 ProcessDataSnapshot(); |
784 ~ProcessDataSnapshot(); | 869 ~ProcessDataSnapshot(); |
785 | 870 |
786 PhasedProcessDataSnapshotMap phased_process_data_snapshots; | 871 PhasedProcessDataSnapshotMap phased_snapshots; |
787 base::ProcessId process_id; | 872 base::ProcessId process_id; |
788 }; | 873 }; |
789 | 874 |
790 } // namespace tracked_objects | 875 } // namespace tracked_objects |
791 | 876 |
792 #endif // BASE_TRACKED_OBJECTS_H_ | 877 #endif // BASE_TRACKED_OBJECTS_H_ |
OLD | NEW |