Chromium Code Reviews| 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 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 238 | 238 |
| 239 class BASE_EXPORT Births: public BirthOnThread { | 239 class BASE_EXPORT Births: public BirthOnThread { |
| 240 public: | 240 public: |
| 241 Births(const Location& location, const ThreadData& current); | 241 Births(const Location& location, const ThreadData& current); |
| 242 | 242 |
| 243 int birth_count() const; | 243 int birth_count() const; |
| 244 | 244 |
| 245 // When we have a birth we update the count for this birthplace. | 245 // When we have a birth we update the count for this birthplace. |
| 246 void RecordBirth(); | 246 void RecordBirth(); |
| 247 | 247 |
| 248 // Subtracts a value from the birth count. | |
| 249 void SubtractBirths(int count); | |
| 250 | |
| 248 private: | 251 private: |
| 249 // The number of births on this thread for our location_. | 252 // The number of births on this thread for our location_. |
| 250 int birth_count_; | 253 int birth_count_; |
| 251 | 254 |
| 252 DISALLOW_COPY_AND_ASSIGN(Births); | 255 DISALLOW_COPY_AND_ASSIGN(Births); |
| 253 }; | 256 }; |
| 254 | 257 |
| 255 //------------------------------------------------------------------------------ | 258 //------------------------------------------------------------------------------ |
| 256 // Basic info summarizing multiple destructions of a tracked object with a | 259 // Basic info summarizing multiple destructions of a tracked object with a |
| 257 // single birthplace (fixed Location). Used both on specific threads, and also | 260 // single birthplace (fixed Location). Used both on specific threads, and also |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 275 | 278 |
| 276 // Metrics accessors, used only for serialization and in tests. | 279 // Metrics accessors, used only for serialization and in tests. |
| 277 int count() const; | 280 int count() const; |
| 278 int32 run_duration_sum() const; | 281 int32 run_duration_sum() const; |
| 279 int32 run_duration_max() const; | 282 int32 run_duration_max() const; |
| 280 int32 run_duration_sample() const; | 283 int32 run_duration_sample() const; |
| 281 int32 queue_duration_sum() const; | 284 int32 queue_duration_sum() const; |
| 282 int32 queue_duration_max() const; | 285 int32 queue_duration_max() const; |
| 283 int32 queue_duration_sample() const; | 286 int32 queue_duration_sample() const; |
| 284 | 287 |
| 285 // Reset all tallies to zero. This is used as a hack on realtime data. | 288 // Reset all tallies to zero. |
| 286 void Clear(); | 289 void Clear(); |
| 287 | 290 |
| 288 private: | 291 private: |
| 289 // Members are ordered from most regularly read and updated, to least | 292 // Members are ordered from most regularly read and updated, to least |
| 290 // frequently used. This might help a bit with cache lines. | 293 // frequently used. This might help a bit with cache lines. |
| 291 // Number of runs seen (divisor for calculating averages). | 294 // Number of runs seen (divisor for calculating averages). |
| 292 int count_; | 295 int count_; |
| 293 // Basic tallies, used to compute averages. | 296 // Basic tallies, used to compute averages. |
| 294 int32 run_duration_sum_; | 297 int32 run_duration_sum_; |
| 295 int32 queue_duration_sum_; | 298 int32 queue_duration_sum_; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 362 enum Status { | 365 enum Status { |
| 363 UNINITIALIZED, // PRistine, link-time state before running. | 366 UNINITIALIZED, // PRistine, link-time state before running. |
| 364 DORMANT_DURING_TESTS, // Only used during testing. | 367 DORMANT_DURING_TESTS, // Only used during testing. |
| 365 DEACTIVATED, // No longer recording profiling. | 368 DEACTIVATED, // No longer recording profiling. |
| 366 PROFILING_ACTIVE, // Recording profiles (no parent-child links). | 369 PROFILING_ACTIVE, // Recording profiles (no parent-child links). |
| 367 PROFILING_CHILDREN_ACTIVE, // Fully active, recording parent-child links. | 370 PROFILING_CHILDREN_ACTIVE, // Fully active, recording parent-child links. |
| 368 STATUS_LAST = PROFILING_CHILDREN_ACTIVE | 371 STATUS_LAST = PROFILING_CHILDREN_ACTIVE |
| 369 }; | 372 }; |
| 370 | 373 |
| 371 typedef std::map<Location, Births*> BirthMap; | 374 typedef std::map<Location, Births*> BirthMap; |
| 372 typedef std::map<const Births*, DeathData> DeathMap; | 375 typedef std::map<Births*, DeathData> DeathMap; |
| 373 typedef std::pair<const Births*, const Births*> ParentChildPair; | 376 typedef std::pair<const Births*, const Births*> ParentChildPair; |
| 374 typedef std::set<ParentChildPair> ParentChildSet; | 377 typedef std::set<ParentChildPair> ParentChildSet; |
| 375 typedef std::stack<const Births*> ParentStack; | 378 typedef std::stack<const Births*> ParentStack; |
| 376 | 379 |
| 377 // Initialize the current thread context with a new instance of ThreadData. | 380 // Initialize the current thread context with a new instance of ThreadData. |
| 378 // This is used by all threads that have names, and should be explicitly | 381 // This is used by all threads that have names, and should be explicitly |
| 379 // set *before* any births on the threads have taken place. It is generally | 382 // set *before* any births on the threads have taken place. It is generally |
| 380 // only used by the message loop, which has a well defined thread name. | 383 // only used by the message loop, which has a well defined thread name. |
| 381 static void InitializeThreadContext(const std::string& suggested_name); | 384 static void InitializeThreadContext(const std::string& suggested_name); |
| 382 | 385 |
| 383 // Using Thread Local Store, find the current instance for collecting data. | 386 // Using Thread Local Store, find the current instance for collecting data. |
| 384 // If an instance does not exist, construct one (and remember it for use on | 387 // If an instance does not exist, construct one (and remember it for use on |
| 385 // this thread. | 388 // this thread. |
| 386 // This may return NULL if the system is disabled for any reason. | 389 // This may return NULL if the system is disabled for any reason. |
| 387 static ThreadData* Get(); | 390 static ThreadData* Get(); |
| 388 | 391 |
| 389 // Fills |process_data_snapshot| with phased snapshots of all profiling | 392 // Fills |process_data_snapshot| with phased snapshots of all profiling |
| 390 // phases, including the current one. | 393 // phases, including the current one, identified by |current_profiling_phase|. |
| 391 static void Snapshot(ProcessDataSnapshot* process_data_snapshot); | 394 // |current_profiling_phase| is necessary because a child process can start |
| 395 // after several phase-changing events, so it needs to receive the current | |
| 396 // phase number from the browser process to fill the correct entry for the | |
| 397 // current phase in the |process_data_snapshot| map. | |
| 398 static void Snapshot(int current_profiling_phase, | |
| 399 ProcessDataSnapshot* process_data_snapshot); | |
| 400 | |
| 401 // Called when the current profiling phase, identified by |profiling_phase|, | |
| 402 // ends. | |
| 403 // |profiling_phase| is necessary because a child process can start after | |
| 404 // several phase-changing events, so it needs to receive the phase number from | |
| 405 // the browser process to fill the correct entry in the | |
| 406 // completed_phases_snapshots_ map. | |
| 407 static void OnProfilingPhaseCompletion(int profiling_phase); | |
| 392 | 408 |
| 393 // Finds (or creates) a place to count births from the given location in this | 409 // Finds (or creates) a place to count births from the given location in this |
| 394 // thread, and increment that tally. | 410 // thread, and increment that tally. |
| 395 // TallyABirthIfActive will returns NULL if the birth cannot be tallied. | 411 // TallyABirthIfActive will returns NULL if the birth cannot be tallied. |
| 396 static Births* TallyABirthIfActive(const Location& location); | 412 static Births* TallyABirthIfActive(const Location& location); |
| 397 | 413 |
| 398 // Records the end of a timed run of an object. The |completed_task| contains | 414 // Records the end of a timed run of an object. The |completed_task| contains |
| 399 // a pointer to a Births, the time_posted, and a delayed_start_time if any. | 415 // a pointer to a Births, the time_posted, and a delayed_start_time if any. |
| 400 // The |start_of_run| indicates when we started to perform the run of the | 416 // The |start_of_run| indicates when we started to perform the run of the |
| 401 // task. The delayed_start_time is non-null for tasks that were posted as | 417 // task. The delayed_start_time is non-null for tasks that were posted as |
| 402 // delayed tasks, and it indicates when the task should have run (i.e., when | 418 // delayed tasks, and it indicates when the task should have run (i.e., when |
| 403 // it should have posted out of the timer queue, and into the work queue. | 419 // it should have posted out of the timer queue, and into the work queue. |
| 404 // The |end_of_run| was just obtained by a call to Now() (just after the task | 420 // The |end_of_run| was just obtained by a call to Now() (just after the task |
| 405 // finished). It is provided as an argument to help with testing. | 421 // finished). It is provided as an argument to help with testing. |
| 406 static void TallyRunOnNamedThreadIfTracking( | 422 static void TallyRunOnNamedThreadIfTracking( |
| 407 const base::TrackingInfo& completed_task, | 423 const base::TrackingInfo& completed_task, |
| 408 const TaskStopwatch& stopwatch); | 424 const TaskStopwatch& stopwatch); |
| 409 | 425 |
| 410 // Record the end of a timed run of an object. The |birth| is the record for | 426 // Record the end of a timed run of an object. The |birth| is the record for |
| 411 // the instance, the |time_posted| records that instant, which is presumed to | 427 // the instance, the |time_posted| records that instant, which is presumed to |
| 412 // be when the task was posted into a queue to run on a worker thread. | 428 // be when the task was posted into a queue to run on a worker thread. |
| 413 // The |start_of_run| is when the worker thread started to perform the run of | 429 // The |start_of_run| is when the worker thread started to perform the run of |
| 414 // the task. | 430 // the task. |
| 415 // The |end_of_run| was just obtained by a call to Now() (just after the task | 431 // The |end_of_run| was just obtained by a call to Now() (just after the task |
| 416 // finished). | 432 // finished). |
| 417 static void TallyRunOnWorkerThreadIfTracking(const Births* birth, | 433 // We don't modify anything in |birth| in this method. We store the pointer as |
|
Alexei Svitkine (slow)
2015/03/30 22:05:21
Nit: Rephrase without "we". Same below.
vadimt
2015/04/01 00:45:40
N/A anymore.
| |
| 418 const TrackedTime& time_posted, | 434 // a key in death_map_, and later, on a phase change event, will call |
| 419 const TaskStopwatch& stopwatch); | 435 // SubtractBirths() on it. |
|
Alexei Svitkine (slow)
2015/03/30 22:05:21
I think this comment needs to discuss the ownershi
vadimt
2015/04/01 00:45:40
Renamed |birth| to |births|.
On "the ownership gu
| |
| 436 static void TallyRunOnWorkerThreadIfTracking(const TrackedTime& time_posted, | |
| 437 const TaskStopwatch& stopwatch, | |
| 438 Births* birth); | |
| 420 | 439 |
| 421 // Record the end of execution in region, generally corresponding to a scope | 440 // Record the end of execution in region, generally corresponding to a scope |
| 422 // being exited. | 441 // being exited. |
| 423 static void TallyRunInAScopedRegionIfTracking(const Births* birth, | 442 // We don't modify anything in |birth| in this method. We store the pointer as |
| 424 const TaskStopwatch& stopwatch); | 443 // a key in death_map_, and later, on a phase change event, will call |
| 444 // SubtractBirths() on it. | |
| 445 static void TallyRunInAScopedRegionIfTracking(const TaskStopwatch& stopwatch, | |
| 446 Births* birth); | |
| 425 | 447 |
| 426 const std::string& thread_name() const { return thread_name_; } | 448 const std::string& thread_name() const { return thread_name_; } |
| 427 | 449 |
| 428 // Initializes all statics if needed (this initialization call should be made | 450 // Initializes all statics if needed (this initialization call should be made |
| 429 // while we are single threaded). Returns false if unable to initialize. | 451 // while we are single threaded). Returns false if unable to initialize. |
| 430 static bool Initialize(); | 452 static bool Initialize(); |
| 431 | 453 |
| 432 // Sets internal status_. | 454 // Sets internal status_. |
| 433 // If |status| is false, then status_ is set to DEACTIVATED. | 455 // If |status| is false, then status_ is set to DEACTIVATED. |
| 434 // If |status| is true, then status_ is set to, PROFILING_ACTIVE, or | 456 // If |status| is true, then status_ is set to, PROFILING_ACTIVE, or |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 509 static ThreadData* first(); | 531 static ThreadData* first(); |
| 510 | 532 |
| 511 // Iterate through the null terminated list of ThreadData instances. | 533 // Iterate through the null terminated list of ThreadData instances. |
| 512 ThreadData* next() const; | 534 ThreadData* next() const; |
| 513 | 535 |
| 514 | 536 |
| 515 // In this thread's data, record a new birth. | 537 // In this thread's data, record a new birth. |
| 516 Births* TallyABirth(const Location& location); | 538 Births* TallyABirth(const Location& location); |
| 517 | 539 |
| 518 // Find a place to record a death on this thread. | 540 // Find a place to record a death on this thread. |
| 519 void TallyADeath(const Births& birth, | 541 // We don't modify anything in |birth| in this method. We store the pointer as |
| 520 int32 queue_duration, | 542 // a key in death_map_, and later, on a phase change event, will call |
| 521 const TaskStopwatch& stopwatch); | 543 // SubtractBirths() on it. |
| 544 void TallyADeath(int32 queue_duration, | |
| 545 const TaskStopwatch& stopwatch, | |
| 546 Births* birth); | |
| 522 | 547 |
| 523 // Snapshot (under a lock) the profiled data for the tasks in each ThreadData | 548 // Snapshot (under a lock) the profiled data for the tasks in each ThreadData |
| 524 // instance. Also updates the |birth_counts| tally for each task to keep | 549 // instance. Also updates the |birth_counts| tally for each task to keep |
| 525 // track of the number of living instances of the task. | 550 // track of the number of living instances of the task. If |reset| is true, |
| 551 // remove all recorded deaths. | |
| 526 static void SnapshotAllExecutedTasks( | 552 static void SnapshotAllExecutedTasks( |
| 553 bool reset, | |
| 527 ProcessDataPhaseSnapshot* process_data_phase, | 554 ProcessDataPhaseSnapshot* process_data_phase, |
| 528 BirthCountMap* birth_counts); | 555 BirthCountMap* birth_counts); |
| 529 | 556 |
| 530 // Fills |process_data_phase| with all the recursive results in our process. | 557 // Fills |process_data_phase| with all the recursive results in our process. |
| 558 // If |reset| is true, remove all recorded deaths. | |
| 531 static void SnapshotCurrentPhase( | 559 static void SnapshotCurrentPhase( |
| 560 bool reset, | |
| 532 ProcessDataPhaseSnapshot* process_data_phase); | 561 ProcessDataPhaseSnapshot* process_data_phase); |
| 533 | 562 |
| 534 // Snapshots (under a lock) the profiled data for the tasks for this thread | 563 // Snapshots (under a lock) the profiled data for the tasks for this thread |
| 535 // and writes all of the executed tasks' data -- i.e. the data for the tasks | 564 // and writes all of the executed tasks' data -- i.e. the data for the tasks |
| 536 // with with entries in the death_map_ -- into |process_data_phase|. Also | 565 // with with entries in the death_map_ -- into |process_data_phase|. Also |
| 537 // updates the |birth_counts| tally for each task to keep track of the number | 566 // updates the |birth_counts| tally for each task to keep track of the number |
| 538 // of living instances of the task -- that is, each task maps to the number of | 567 // of living instances of the task -- that is, each task maps to the number of |
| 539 // births for the task that have not yet been balanced by a death. | 568 // births for the task that have not yet been balanced by a death. If |reset| |
| 540 void SnapshotExecutedTasks(ProcessDataPhaseSnapshot* process_data_phase, | 569 // is true, remove all recorded deaths. |
| 570 void SnapshotExecutedTasks(bool reset, | |
| 571 ProcessDataPhaseSnapshot* process_data_phase, | |
| 541 BirthCountMap* birth_counts); | 572 BirthCountMap* birth_counts); |
| 542 | 573 |
| 543 // Using our lock, make a copy of the specified maps. This call may be made | 574 // Using our lock, make a copy of the specified maps. This call may be made |
| 544 // on non-local threads, which necessitate the use of the lock to prevent | 575 // on non-local threads, which necessitate the use of the lock to prevent |
| 545 // the map(s) from being reallocated while they are copied. | 576 // the map(s) from being reallocated while they are copied. If |reset| is |
| 546 void SnapshotMaps(BirthMap* birth_map, | 577 // true, remove all recorded deaths. |
| 578 void SnapshotMaps(bool reset, | |
| 579 BirthMap* birth_map, | |
| 547 DeathMap* death_map, | 580 DeathMap* death_map, |
| 548 ParentChildSet* parent_child_set); | 581 ParentChildSet* parent_child_set); |
| 549 | 582 |
| 550 // This method is called by the TLS system when a thread terminates. | 583 // This method is called by the TLS system when a thread terminates. |
| 551 // The argument may be NULL if this thread has never tracked a birth or death. | 584 // The argument may be NULL if this thread has never tracked a birth or death. |
| 552 static void OnThreadTermination(void* thread_data); | 585 static void OnThreadTermination(void* thread_data); |
| 553 | 586 |
| 554 // This method should be called when a worker thread terminates, so that we | 587 // This method should be called when a worker thread terminates, so that we |
| 555 // can save all the thread data into a cache of reusable ThreadData instances. | 588 // can save all the thread data into a cache of reusable ThreadData instances. |
| 556 void OnThreadTerminationCleanup(); | 589 void OnThreadTerminationCleanup(); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 604 | 637 |
| 605 // Protection for access to all_thread_data_list_head_, and to | 638 // Protection for access to all_thread_data_list_head_, and to |
| 606 // unregistered_thread_data_pool_. This lock is leaked at shutdown. | 639 // unregistered_thread_data_pool_. This lock is leaked at shutdown. |
| 607 // The lock is very infrequently used, so we can afford to just make a lazy | 640 // The lock is very infrequently used, so we can afford to just make a lazy |
| 608 // instance and be safe. | 641 // instance and be safe. |
| 609 static base::LazyInstance<base::Lock>::Leaky list_lock_; | 642 static base::LazyInstance<base::Lock>::Leaky list_lock_; |
| 610 | 643 |
| 611 // We set status_ to SHUTDOWN when we shut down the tracking service. | 644 // We set status_ to SHUTDOWN when we shut down the tracking service. |
| 612 static Status status_; | 645 static Status status_; |
| 613 | 646 |
| 647 // Process data snapshots for completed profiling phases. | |
| 648 static base::LazyInstance<PhasedProcessDataSnapshotMap> | |
| 649 completed_phases_snapshots_; | |
| 650 | |
| 614 // Link to next instance (null terminated list). Used to globally track all | 651 // Link to next instance (null terminated list). Used to globally track all |
| 615 // registered instances (corresponds to all registered threads where we keep | 652 // registered instances (corresponds to all registered threads where we keep |
| 616 // data). | 653 // data). |
| 617 ThreadData* next_; | 654 ThreadData* next_; |
| 618 | 655 |
| 619 // Pointer to another ThreadData instance for a Worker-Thread that has been | 656 // Pointer to another ThreadData instance for a Worker-Thread that has been |
| 620 // retired (its thread was terminated). This value is non-NULL only for a | 657 // retired (its thread was terminated). This value is non-NULL only for a |
| 621 // retired ThreadData associated with a Worker-Thread. | 658 // retired ThreadData associated with a Worker-Thread. |
| 622 ThreadData* next_retired_worker_; | 659 ThreadData* next_retired_worker_; |
| 623 | 660 |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 782 ProcessDataSnapshot(); | 819 ProcessDataSnapshot(); |
| 783 ~ProcessDataSnapshot(); | 820 ~ProcessDataSnapshot(); |
| 784 | 821 |
| 785 PhasedProcessDataSnapshotMap phased_process_data_snapshots; | 822 PhasedProcessDataSnapshotMap phased_process_data_snapshots; |
| 786 base::ProcessId process_id; | 823 base::ProcessId process_id; |
| 787 }; | 824 }; |
| 788 | 825 |
| 789 } // namespace tracked_objects | 826 } // namespace tracked_objects |
| 790 | 827 |
| 791 #endif // BASE_TRACKED_OBJECTS_H_ | 828 #endif // BASE_TRACKED_OBJECTS_H_ |
| OLD | NEW |