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> |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
239 | 239 |
240 class BASE_EXPORT Births: public BirthOnThread { | 240 class BASE_EXPORT Births: public BirthOnThread { |
241 public: | 241 public: |
242 Births(const Location& location, const ThreadData& current); | 242 Births(const Location& location, const ThreadData& current); |
243 | 243 |
244 int birth_count() const; | 244 int birth_count() const; |
245 | 245 |
246 // When we have a birth we update the count for this birthplace. | 246 // When we have a birth we update the count for this birthplace. |
247 void RecordBirth(); | 247 void RecordBirth(); |
248 | 248 |
249 // Subtracts a value from the birth count. | |
250 void SubtractBirths(int count); | |
251 | |
249 private: | 252 private: |
250 // The number of births on this thread for our location_. | 253 // The number of births on this thread for our location_. |
251 int birth_count_; | 254 int birth_count_; |
252 | 255 |
253 DISALLOW_COPY_AND_ASSIGN(Births); | 256 DISALLOW_COPY_AND_ASSIGN(Births); |
254 }; | 257 }; |
255 | 258 |
256 //------------------------------------------------------------------------------ | 259 //------------------------------------------------------------------------------ |
257 // Basic info summarizing multiple destructions of a tracked object with a | 260 // Basic info summarizing multiple destructions of a tracked object with a |
258 // single birthplace (fixed Location). Used both on specific threads, and also | 261 // single birthplace (fixed Location). Used both on specific threads, and also |
(...skipping 17 matching lines...) Expand all Loading... | |
276 | 279 |
277 // Metrics accessors, used only for serialization and in tests. | 280 // Metrics accessors, used only for serialization and in tests. |
278 int count() const; | 281 int count() const; |
279 int32 run_duration_sum() const; | 282 int32 run_duration_sum() const; |
280 int32 run_duration_max() const; | 283 int32 run_duration_max() const; |
281 int32 run_duration_sample() const; | 284 int32 run_duration_sample() const; |
282 int32 queue_duration_sum() const; | 285 int32 queue_duration_sum() const; |
283 int32 queue_duration_max() const; | 286 int32 queue_duration_max() const; |
284 int32 queue_duration_sample() const; | 287 int32 queue_duration_sample() const; |
285 | 288 |
286 // Reset all tallies to zero. This is used as a hack on realtime data. | 289 // Reset all tallies to zero. |
287 void Clear(); | 290 void Clear(); |
288 | 291 |
289 private: | 292 private: |
290 // Members are ordered from most regularly read and updated, to least | 293 // Members are ordered from most regularly read and updated, to least |
291 // frequently used. This might help a bit with cache lines. | 294 // frequently used. This might help a bit with cache lines. |
292 // Number of runs seen (divisor for calculating averages). | 295 // Number of runs seen (divisor for calculating averages). |
293 int count_; | 296 int count_; |
294 // Basic tallies, used to compute averages. | 297 // Basic tallies, used to compute averages. |
295 int32 run_duration_sum_; | 298 int32 run_duration_sum_; |
296 int32 queue_duration_sum_; | 299 int32 queue_duration_sum_; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
349 | 352 |
350 struct ProcessDataPhaseSnapshot; | 353 struct ProcessDataPhaseSnapshot; |
351 struct ProcessDataSnapshot; | 354 struct ProcessDataSnapshot; |
352 class BASE_EXPORT TaskStopwatch; | 355 class BASE_EXPORT TaskStopwatch; |
353 | 356 |
354 // Map from profiling phase number to the process-wide snapshotted | 357 // Map from profiling phase number to the process-wide snapshotted |
355 // representation of the list of ThreadData objects that died during the given | 358 // representation of the list of ThreadData objects that died during the given |
356 // phase. | 359 // phase. |
357 typedef std::map<int, ProcessDataPhaseSnapshot> PhasedProcessDataSnapshotMap; | 360 typedef std::map<int, ProcessDataPhaseSnapshot> PhasedProcessDataSnapshotMap; |
358 | 361 |
362 // Results of resetting death counts to 0. This is a map from the Births pointer | |
363 // to the count of deaths (for tasks with this Births) that were set to 0 by | |
364 // resetting. | |
365 typedef std::map<const Births*, int> DeathResetResults; | |
366 | |
359 class BASE_EXPORT ThreadData { | 367 class BASE_EXPORT ThreadData { |
360 public: | 368 public: |
361 // Current allowable states of the tracking system. The states can vary | 369 // Current allowable states of the tracking system. The states can vary |
362 // between ACTIVE and DEACTIVATED, but can never go back to UNINITIALIZED. | 370 // between ACTIVE and DEACTIVATED, but can never go back to UNINITIALIZED. |
363 enum Status { | 371 enum Status { |
364 UNINITIALIZED, // PRistine, link-time state before running. | 372 UNINITIALIZED, // PRistine, link-time state before running. |
365 DORMANT_DURING_TESTS, // Only used during testing. | 373 DORMANT_DURING_TESTS, // Only used during testing. |
366 DEACTIVATED, // No longer recording profiling. | 374 DEACTIVATED, // No longer recording profiling. |
367 PROFILING_ACTIVE, // Recording profiles (no parent-child links). | 375 PROFILING_ACTIVE, // Recording profiles (no parent-child links). |
368 PROFILING_CHILDREN_ACTIVE, // Fully active, recording parent-child links. | 376 PROFILING_CHILDREN_ACTIVE, // Fully active, recording parent-child links. |
(...skipping 12 matching lines...) Expand all Loading... | |
381 // only used by the message loop, which has a well defined thread name. | 389 // only used by the message loop, which has a well defined thread name. |
382 static void InitializeThreadContext(const std::string& suggested_name); | 390 static void InitializeThreadContext(const std::string& suggested_name); |
383 | 391 |
384 // Using Thread Local Store, find the current instance for collecting data. | 392 // 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 | 393 // If an instance does not exist, construct one (and remember it for use on |
386 // this thread. | 394 // this thread. |
387 // This may return NULL if the system is disabled for any reason. | 395 // This may return NULL if the system is disabled for any reason. |
388 static ThreadData* Get(); | 396 static ThreadData* Get(); |
389 | 397 |
390 // Fills |process_data_snapshot| with phased snapshots of all profiling | 398 // Fills |process_data_snapshot| with phased snapshots of all profiling |
391 // phases, including the current one. | 399 // phases, including the current one, identified by |current_profiling_phase|. |
392 static void Snapshot(ProcessDataSnapshot* process_data_snapshot); | 400 // |current_profiling_phase| is necessary because a child process can start |
401 // after several phase-changing events, so it needs to receive the current | |
402 // phase number from the browser process to fill the correct entry for the | |
403 // current phase in the |process_data_snapshot| map. | |
404 static void Snapshot(int current_profiling_phase, | |
405 ProcessDataSnapshot* process_data_snapshot); | |
406 | |
407 // Called when the current profiling phase, identified by |profiling_phase|, | |
408 // ends. | |
409 // |profiling_phase| is necessary because a child process can start after | |
410 // several phase-changing events, so it needs to receive the phase number from | |
411 // the browser process to fill the correct entry in the | |
412 // completed_phases_snapshots_ map. | |
413 static void OnProfilingPhaseCompletion(int profiling_phase); | |
393 | 414 |
394 // Finds (or creates) a place to count births from the given location in this | 415 // Finds (or creates) a place to count births from the given location in this |
395 // thread, and increment that tally. | 416 // thread, and increment that tally. |
396 // TallyABirthIfActive will returns NULL if the birth cannot be tallied. | 417 // TallyABirthIfActive will returns NULL if the birth cannot be tallied. |
397 static Births* TallyABirthIfActive(const Location& location); | 418 static Births* TallyABirthIfActive(const Location& location); |
398 | 419 |
399 // Records the end of a timed run of an object. The |completed_task| contains | 420 // 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. | 421 // 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 | 422 // 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 | 423 // 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 | 424 // 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. | 425 // 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 | 426 // 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. | 427 // finished). It is provided as an argument to help with testing. |
407 static void TallyRunOnNamedThreadIfTracking( | 428 static void TallyRunOnNamedThreadIfTracking( |
408 const base::TrackingInfo& completed_task, | 429 const base::TrackingInfo& completed_task, |
409 const TaskStopwatch& stopwatch); | 430 const TaskStopwatch& stopwatch); |
410 | 431 |
411 // Record the end of a timed run of an object. The |birth| is the record for | 432 // 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 | 433 // 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. | 434 // 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 | 435 // The |start_of_run| is when the worker thread started to perform the run of |
415 // the task. | 436 // the task. |
416 // The |end_of_run| was just obtained by a call to Now() (just after the task | 437 // The |end_of_run| was just obtained by a call to Now() (just after the task |
417 // finished). | 438 // finished). |
418 static void TallyRunOnWorkerThreadIfTracking(const Births* birth, | 439 static void TallyRunOnWorkerThreadIfTracking(const Births* births, |
419 const TrackedTime& time_posted, | 440 const TrackedTime& time_posted, |
420 const TaskStopwatch& stopwatch); | 441 const TaskStopwatch& stopwatch); |
421 | 442 |
422 // Record the end of execution in region, generally corresponding to a scope | 443 // Record the end of execution in region, generally corresponding to a scope |
423 // being exited. | 444 // being exited. |
424 static void TallyRunInAScopedRegionIfTracking(const Births* birth, | 445 static void TallyRunInAScopedRegionIfTracking(const Births* births, |
425 const TaskStopwatch& stopwatch); | 446 const TaskStopwatch& stopwatch); |
426 | 447 |
427 const std::string& thread_name() const { return thread_name_; } | 448 const std::string& thread_name() const { return thread_name_; } |
428 | 449 |
429 // Initializes all statics if needed (this initialization call should be made | 450 // Initializes all statics if needed (this initialization call should be made |
430 // while we are single threaded). Returns false if unable to initialize. | 451 // while we are single threaded). Returns false if unable to initialize. |
431 static bool Initialize(); | 452 static bool Initialize(); |
432 | 453 |
433 // Sets internal status_. | 454 // Sets internal status_. |
434 // If |status| is false, then status_ is set to DEACTIVATED. | 455 // If |status| is false, then status_ is set to DEACTIVATED. |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
510 static ThreadData* first(); | 531 static ThreadData* first(); |
511 | 532 |
512 // Iterate through the null terminated list of ThreadData instances. | 533 // Iterate through the null terminated list of ThreadData instances. |
513 ThreadData* next() const; | 534 ThreadData* next() const; |
514 | 535 |
515 | 536 |
516 // In this thread's data, record a new birth. | 537 // In this thread's data, record a new birth. |
517 Births* TallyABirth(const Location& location); | 538 Births* TallyABirth(const Location& location); |
518 | 539 |
519 // Find a place to record a death on this thread. | 540 // Find a place to record a death on this thread. |
520 void TallyADeath(const Births& birth, | 541 void TallyADeath(const Births& births, |
521 int32 queue_duration, | 542 int32 queue_duration, |
522 const TaskStopwatch& stopwatch); | 543 const TaskStopwatch& stopwatch); |
523 | 544 |
524 // Snapshot (under a lock) the profiled data for the tasks in each ThreadData | 545 // 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 | 546 // instance. Also updates the |birth_counts| tally for each task to keep |
526 // track of the number of living instances of the task. | 547 // track of the number of living instances of the task. If |reset| is true, |
548 // remove all recorded deaths. | |
527 static void SnapshotAllExecutedTasks( | 549 static void SnapshotAllExecutedTasks( |
550 bool reset, | |
jar (doing other things)
2015/04/01 17:10:25
This is totally unsafe, and will instigate errors
vadimt
2015/04/06 23:25:12
Done.
| |
528 ProcessDataPhaseSnapshot* process_data_phase, | 551 ProcessDataPhaseSnapshot* process_data_phase, |
529 BirthCountMap* birth_counts); | 552 BirthCountMap* birth_counts); |
530 | 553 |
531 // Fills |process_data_phase| with all the recursive results in our process. | 554 // Fills |process_data_phase| with all the recursive results in our process. |
555 // If |reset| is true, remove all recorded deaths. | |
532 static void SnapshotCurrentPhase( | 556 static void SnapshotCurrentPhase( |
557 bool reset, | |
533 ProcessDataPhaseSnapshot* process_data_phase); | 558 ProcessDataPhaseSnapshot* process_data_phase); |
534 | 559 |
535 // Snapshots (under a lock) the profiled data for the tasks for this thread | 560 // 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 | 561 // and writes all of the executed tasks' data -- i.e. the data for the tasks |
537 // with with entries in the death_map_ -- into |process_data_phase|. Also | 562 // with with entries in the death_map_ -- into |process_data_phase|. Also |
538 // updates the |birth_counts| tally for each task to keep track of the number | 563 // updates the |birth_counts| tally for each task to keep track of the number |
539 // of living instances of the task -- that is, each task maps to the number of | 564 // of living instances of the task -- that is, each task maps to the number of |
540 // births for the task that have not yet been balanced by a death. | 565 // births for the task that have not yet been balanced by a death. If |
566 // |death_reset_results| is not null, store current death counts in it and | |
jar (doing other things)
2015/04/01 17:10:25
You can't get away with doing atomic operation so
vadimt
2015/04/06 23:25:12
Done.
| |
567 // remove all recorded deaths. | |
541 void SnapshotExecutedTasks(ProcessDataPhaseSnapshot* process_data_phase, | 568 void SnapshotExecutedTasks(ProcessDataPhaseSnapshot* process_data_phase, |
569 DeathResetResults* death_reset_results, | |
542 BirthCountMap* birth_counts); | 570 BirthCountMap* birth_counts); |
543 | 571 |
544 // Using our lock, make a copy of the specified maps. This call may be made | 572 // 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 | 573 // on non-local threads, which necessitate the use of the lock to prevent |
546 // the map(s) from being reallocated while they are copied. | 574 // the map(s) from being reallocated while they are copied. If |
575 // |death_reset_results| is not null, store current death counts in it and | |
576 // remove all recorded deaths. | |
547 void SnapshotMaps(BirthMap* birth_map, | 577 void SnapshotMaps(BirthMap* birth_map, |
548 DeathMap* death_map, | 578 DeathMap* death_map, |
579 DeathResetResults* death_reset_results, | |
549 ParentChildSet* parent_child_set); | 580 ParentChildSet* parent_child_set); |
550 | 581 |
582 // Using our lock, decrease births counts owned by this thread after a death | |
583 // data's reset. | |
584 // |death_reset_results| is the result of the cross-threads death count reset | |
585 // operation that took place before calling this method. For each Birth owned | |
586 // by this ThreadData, the method will subtract from its birth count the total | |
587 // number of deaths that were 'forgotten' by resetting death counts to 0. | |
588 void SubtractDeathResultsFromBirths( | |
589 const DeathResetResults& death_reset_results); | |
590 | |
551 // This method is called by the TLS system when a thread terminates. | 591 // 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. | 592 // The argument may be NULL if this thread has never tracked a birth or death. |
553 static void OnThreadTermination(void* thread_data); | 593 static void OnThreadTermination(void* thread_data); |
554 | 594 |
555 // This method should be called when a worker thread terminates, so that we | 595 // 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. | 596 // can save all the thread data into a cache of reusable ThreadData instances. |
557 void OnThreadTerminationCleanup(); | 597 void OnThreadTerminationCleanup(); |
558 | 598 |
559 // Cleans up data structures, and returns statics to near pristine (mostly | 599 // Cleans up data structures, and returns statics to near pristine (mostly |
560 // uninitialized) state. If there is any chance that other threads are still | 600 // uninitialized) state. If there is any chance that other threads are still |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
605 | 645 |
606 // Protection for access to all_thread_data_list_head_, and to | 646 // Protection for access to all_thread_data_list_head_, and to |
607 // unregistered_thread_data_pool_. This lock is leaked at shutdown. | 647 // 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 | 648 // The lock is very infrequently used, so we can afford to just make a lazy |
609 // instance and be safe. | 649 // instance and be safe. |
610 static base::LazyInstance<base::Lock>::Leaky list_lock_; | 650 static base::LazyInstance<base::Lock>::Leaky list_lock_; |
611 | 651 |
612 // We set status_ to SHUTDOWN when we shut down the tracking service. | 652 // We set status_ to SHUTDOWN when we shut down the tracking service. |
613 static Status status_; | 653 static Status status_; |
614 | 654 |
655 // Process data snapshots for completed profiling phases. | |
656 static base::LazyInstance<PhasedProcessDataSnapshotMap> | |
657 completed_phases_snapshots_; | |
658 | |
615 // Link to next instance (null terminated list). Used to globally track all | 659 // Link to next instance (null terminated list). Used to globally track all |
616 // registered instances (corresponds to all registered threads where we keep | 660 // registered instances (corresponds to all registered threads where we keep |
617 // data). | 661 // data). |
618 ThreadData* next_; | 662 ThreadData* next_; |
619 | 663 |
620 // Pointer to another ThreadData instance for a Worker-Thread that has been | 664 // 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 | 665 // retired (its thread was terminated). This value is non-NULL only for a |
622 // retired ThreadData associated with a Worker-Thread. | 666 // retired ThreadData associated with a Worker-Thread. |
623 ThreadData* next_retired_worker_; | 667 ThreadData* next_retired_worker_; |
624 | 668 |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
783 ProcessDataSnapshot(); | 827 ProcessDataSnapshot(); |
784 ~ProcessDataSnapshot(); | 828 ~ProcessDataSnapshot(); |
785 | 829 |
786 PhasedProcessDataSnapshotMap phased_process_data_snapshots; | 830 PhasedProcessDataSnapshotMap phased_process_data_snapshots; |
787 base::ProcessId process_id; | 831 base::ProcessId process_id; |
788 }; | 832 }; |
789 | 833 |
790 } // namespace tracked_objects | 834 } // namespace tracked_objects |
791 | 835 |
792 #endif // BASE_TRACKED_OBJECTS_H_ | 836 #endif // BASE_TRACKED_OBJECTS_H_ |
OLD | NEW |