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 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 |