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