Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(328)

Side by Side Diff: base/tracked_objects.h

Issue 985773002: Introducing phased profiling framework (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@write_to_file
Patch Set: Fixing Android compile errors. Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | base/tracked_objects.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/profiler/alternate_timer.h" 22 #include "base/profiler/alternate_timer.h"
22 #include "base/profiler/tracked_time.h" 23 #include "base/profiler/tracked_time.h"
23 #include "base/synchronization/lock.h" 24 #include "base/synchronization/lock.h"
24 #include "base/threading/thread_local_storage.h" 25 #include "base/threading/thread_local_storage.h"
25 26
26 namespace base { 27 namespace base {
27 struct TrackingInfo; 28 struct TrackingInfo;
28 } 29 }
29 30
30 // TrackedObjects provides a database of stats about objects (generally Tasks) 31 // TrackedObjects provides a database of stats about objects (generally Tasks)
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 // (3) the snapshotted data. 141 // (3) the snapshotted data.
141 // 142 //
142 // For a given birth location, information about births is spread across data 143 // For a given birth location, information about births is spread across data
143 // structures that are asynchronously changing on various threads. For 144 // structures that are asynchronously changing on various threads. For
144 // serialization and display purposes, we need to construct TaskSnapshot 145 // serialization and display purposes, we need to construct TaskSnapshot
145 // instances for each combination of birth thread, death thread, and location, 146 // instances for each combination of birth thread, death thread, and location,
146 // along with the count of such lifetimes. We gather such data into a 147 // along with the count of such lifetimes. We gather such data into a
147 // TaskSnapshot instances, so that such instances can be sorted and 148 // TaskSnapshot instances, so that such instances can be sorted and
148 // aggregated (and remain frozen during our processing). 149 // aggregated (and remain frozen during our processing).
149 // 150 //
150 // The ProcessDataSnapshot struct is a serialized representation of the list 151 // Profiling consists of phases. The concrete phase in the sequence of phases is
151 // of ThreadData objects for a process. It holds a set of TaskSnapshots 152 // identified by its 0-based index.
152 // and tracks parent/child relationships for the executed tasks. The statistics 153 //
153 // in a snapshot are gathered asynhcronously relative to their ongoing updates. 154 // The ProcessDataPhaseSnapshot struct is a serialized representation of the
155 // list of ThreadData objects for a process for a concrete profiling phase. It
156 // holds a set of TaskSnapshots and tracks parent/child relationships for the
157 // executed tasks. The statistics in a snapshot are gathered asynhcronously
158 // relative to their ongoing updates.
154 // It is possible, though highly unlikely, that stats could be incorrectly 159 // It is possible, though highly unlikely, that stats could be incorrectly
155 // recorded by this process (all data is held in 32 bit ints, but we are not 160 // recorded by this process (all data is held in 32 bit ints, but we are not
156 // atomically collecting all data, so we could have count that does not, for 161 // atomically collecting all data, so we could have count that does not, for
157 // example, match with the number of durations we accumulated). The advantage 162 // example, match with the number of durations we accumulated). The advantage
158 // to having fast (non-atomic) updates of the data outweighs the minimal risk of 163 // to having fast (non-atomic) updates of the data outweighs the minimal risk of
159 // a singular corrupt statistic snapshot (only the snapshot could be corrupt, 164 // a singular corrupt statistic snapshot (only the snapshot could be corrupt,
160 // not the underlying and ongoing statistic). In contrast, pointer data that 165 // not the underlying and ongoing statistic). In contrast, pointer data that
161 // is accessed during snapshotting is completely invariant, and hence is 166 // is accessed during snapshotting is completely invariant, and hence is
162 // perfectly acquired (i.e., no potential corruption, and no risk of a bad 167 // perfectly acquired (i.e., no potential corruption, and no risk of a bad
163 // memory reference). 168 // memory reference).
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 std::string death_thread_name; 340 std::string death_thread_name;
336 }; 341 };
337 342
338 //------------------------------------------------------------------------------ 343 //------------------------------------------------------------------------------
339 // For each thread, we have a ThreadData that stores all tracking info generated 344 // For each thread, we have a ThreadData that stores all tracking info generated
340 // on this thread. This prevents the need for locking as data accumulates. 345 // on this thread. This prevents the need for locking as data accumulates.
341 // We use ThreadLocalStorage to quickly identfy the current ThreadData context. 346 // We use ThreadLocalStorage to quickly identfy the current ThreadData context.
342 // We also have a linked list of ThreadData instances, and that list is used to 347 // We also have a linked list of ThreadData instances, and that list is used to
343 // harvest data from all existing instances. 348 // harvest data from all existing instances.
344 349
350 struct ProcessDataPhaseSnapshot;
345 struct ProcessDataSnapshot; 351 struct ProcessDataSnapshot;
346 class BASE_EXPORT TaskStopwatch; 352 class BASE_EXPORT TaskStopwatch;
347 353
354 // Map from profiling phase number to the process-wide snapshotted
355 // representation of the list of ThreadData objects that died during the given
356 // phase.
357 typedef std::map<int, ProcessDataPhaseSnapshot> PhasedProcessDataSnapshotMap;
358
348 class BASE_EXPORT ThreadData { 359 class BASE_EXPORT ThreadData {
349 public: 360 public:
350 // Current allowable states of the tracking system. The states can vary 361 // Current allowable states of the tracking system. The states can vary
351 // between ACTIVE and DEACTIVATED, but can never go back to UNINITIALIZED. 362 // between ACTIVE and DEACTIVATED, but can never go back to UNINITIALIZED.
352 enum Status { 363 enum Status {
353 UNINITIALIZED, // PRistine, link-time state before running. 364 UNINITIALIZED, // PRistine, link-time state before running.
354 DORMANT_DURING_TESTS, // Only used during testing. 365 DORMANT_DURING_TESTS, // Only used during testing.
355 DEACTIVATED, // No longer recording profiling. 366 DEACTIVATED, // No longer recording profiling.
356 PROFILING_ACTIVE, // Recording profiles (no parent-child links). 367 PROFILING_ACTIVE, // Recording profiles (no parent-child links).
357 PROFILING_CHILDREN_ACTIVE, // Fully active, recording parent-child links. 368 PROFILING_CHILDREN_ACTIVE, // Fully active, recording parent-child links.
(...skipping 11 matching lines...) Expand all
369 // set *before* any births on the threads have taken place. It is generally 380 // set *before* any births on the threads have taken place. It is generally
370 // only used by the message loop, which has a well defined thread name. 381 // only used by the message loop, which has a well defined thread name.
371 static void InitializeThreadContext(const std::string& suggested_name); 382 static void InitializeThreadContext(const std::string& suggested_name);
372 383
373 // Using Thread Local Store, find the current instance for collecting data. 384 // Using Thread Local Store, find the current instance for collecting data.
374 // If an instance does not exist, construct one (and remember it for use on 385 // If an instance does not exist, construct one (and remember it for use on
375 // this thread. 386 // this thread.
376 // This may return NULL if the system is disabled for any reason. 387 // This may return NULL if the system is disabled for any reason.
377 static ThreadData* Get(); 388 static ThreadData* Get();
378 389
379 // Fills |process_data| with all the recursive results in our process. 390 // Fills |process_data_snapshot| with phased snapshots of all profiling
380 static void Snapshot(ProcessDataSnapshot* process_data); 391 // phases, including the current one.
392 static void Snapshot(ProcessDataSnapshot* process_data_snapshot);
381 393
382 // Finds (or creates) a place to count births from the given location in this 394 // Finds (or creates) a place to count births from the given location in this
383 // thread, and increment that tally. 395 // thread, and increment that tally.
384 // TallyABirthIfActive will returns NULL if the birth cannot be tallied. 396 // TallyABirthIfActive will returns NULL if the birth cannot be tallied.
385 static Births* TallyABirthIfActive(const Location& location); 397 static Births* TallyABirthIfActive(const Location& location);
386 398
387 // Records the end of a timed run of an object. The |completed_task| contains 399 // Records the end of a timed run of an object. The |completed_task| contains
388 // a pointer to a Births, the time_posted, and a delayed_start_time if any. 400 // a pointer to a Births, the time_posted, and a delayed_start_time if any.
389 // The |start_of_run| indicates when we started to perform the run of the 401 // The |start_of_run| indicates when we started to perform the run of the
390 // task. The delayed_start_time is non-null for tasks that were posted as 402 // task. The delayed_start_time is non-null for tasks that were posted as
391 // delayed tasks, and it indicates when the task should have run (i.e., when 403 // delayed tasks, and it indicates when the task should have run (i.e., when
392 // it should have posted out of the timer queue, and into the work queue. 404 // it should have posted out of the timer queue, and into the work queue.
393 // The |end_of_run| was just obtained by a call to Now() (just after the task 405 // The |end_of_run| was just obtained by a call to Now() (just after the task
394 // finished). It is provided as an argument to help with testing. 406 // finished). It is provided as an argument to help with testing.
395 static void TallyRunOnNamedThreadIfTracking( 407 static void TallyRunOnNamedThreadIfTracking(
396 const base::TrackingInfo& completed_task, 408 const base::TrackingInfo& completed_task,
397 const TaskStopwatch& stopwatch); 409 const TaskStopwatch& stopwatch);
398 410
399 // Record the end of a timed run of an object. The |birth| is the record for 411 // Record the end of a timed run of an object. The |birth| is the record for
400 // the instance, the |time_posted| records that instant, which is presumed to 412 // the instance, the |time_posted| records that instant, which is presumed to
401 // be when the task was posted into a queue to run on a worker thread. 413 // be when the task was posted into a queue to run on a worker thread.
402 // The |start_of_run| is when the worker thread started to perform the run of 414 // The |start_of_run| is when the worker thread started to perform the run of
403 // the task. 415 // the task.
404 // The |end_of_run| was just obtained by a call to Now() (just after the task 416 // The |end_of_run| was just obtained by a call to Now() (just after the task
405 // finished). 417 // finished).
406 static void TallyRunOnWorkerThreadIfTracking( 418 static void TallyRunOnWorkerThreadIfTracking(const Births* birth,
407 const Births* birth, 419 const TrackedTime& time_posted,
408 const TrackedTime& time_posted, 420 const TaskStopwatch& stopwatch);
409 const TaskStopwatch& stopwatch);
410 421
411 // Record the end of execution in region, generally corresponding to a scope 422 // Record the end of execution in region, generally corresponding to a scope
412 // being exited. 423 // being exited.
413 static void TallyRunInAScopedRegionIfTracking( 424 static void TallyRunInAScopedRegionIfTracking(const Births* birth,
414 const Births* birth, 425 const TaskStopwatch& stopwatch);
415 const TaskStopwatch& stopwatch);
416 426
417 const std::string& thread_name() const { return thread_name_; } 427 const std::string& thread_name() const { return thread_name_; }
418 428
419 // Initializes all statics if needed (this initialization call should be made 429 // Initializes all statics if needed (this initialization call should be made
420 // while we are single threaded). Returns false if unable to initialize. 430 // while we are single threaded). Returns false if unable to initialize.
421 static bool Initialize(); 431 static bool Initialize();
422 432
423 // Sets internal status_. 433 // Sets internal status_.
424 // If |status| is false, then status_ is set to DEACTIVATED. 434 // If |status| is false, then status_ is set to DEACTIVATED.
425 // If |status| is true, then status_ is set to, PROFILING_ACTIVE, or 435 // If |status| is true, then status_ is set to, PROFILING_ACTIVE, or
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 Births* TallyABirth(const Location& location); 517 Births* TallyABirth(const Location& location);
508 518
509 // Find a place to record a death on this thread. 519 // Find a place to record a death on this thread.
510 void TallyADeath(const Births& birth, 520 void TallyADeath(const Births& birth,
511 int32 queue_duration, 521 int32 queue_duration,
512 const TaskStopwatch& stopwatch); 522 const TaskStopwatch& stopwatch);
513 523
514 // Snapshot (under a lock) the profiled data for the tasks in each ThreadData 524 // Snapshot (under a lock) the profiled data for the tasks in each ThreadData
515 // instance. Also updates the |birth_counts| tally for each task to keep 525 // instance. Also updates the |birth_counts| tally for each task to keep
516 // track of the number of living instances of the task. 526 // track of the number of living instances of the task.
517 static void SnapshotAllExecutedTasks(ProcessDataSnapshot* process_data, 527 static void SnapshotAllExecutedTasks(
518 BirthCountMap* birth_counts); 528 ProcessDataPhaseSnapshot* process_data_phase,
529 BirthCountMap* birth_counts);
530
531 // Fills |process_data_phase| with all the recursive results in our process.
532 static void SnapshotCurrentPhase(
533 ProcessDataPhaseSnapshot* process_data_phase);
519 534
520 // Snapshots (under a lock) the profiled data for the tasks for this thread 535 // Snapshots (under a lock) the profiled data for the tasks for this thread
521 // and writes all of the executed tasks' data -- i.e. the data for the tasks 536 // and writes all of the executed tasks' data -- i.e. the data for the tasks
522 // with with entries in the death_map_ -- into |process_data|. Also updates 537 // with with entries in the death_map_ -- into |process_data_phase|. Also
523 // the |birth_counts| tally for each task to keep track of the number of 538 // updates the |birth_counts| tally for each task to keep track of the number
524 // living instances of the task -- that is, each task maps to the number of 539 // of living instances of the task -- that is, each task maps to the number of
525 // births for the task that have not yet been balanced by a death. 540 // births for the task that have not yet been balanced by a death.
526 void SnapshotExecutedTasks(ProcessDataSnapshot* process_data, 541 void SnapshotExecutedTasks(ProcessDataPhaseSnapshot* process_data_phase,
527 BirthCountMap* birth_counts); 542 BirthCountMap* birth_counts);
528 543
529 // Using our lock, make a copy of the specified maps. This call may be made 544 // Using our lock, make a copy of the specified maps. This call may be made
530 // on non-local threads, which necessitate the use of the lock to prevent 545 // on non-local threads, which necessitate the use of the lock to prevent
531 // the map(s) from being reallocated while they are copied. 546 // the map(s) from being reallocated while they are copied.
532 void SnapshotMaps(BirthMap* birth_map, 547 void SnapshotMaps(BirthMap* birth_map,
533 DeathMap* death_map, 548 DeathMap* death_map,
534 ParentChildSet* parent_child_set); 549 ParentChildSet* parent_child_set);
535 550
536 // This method is called by the TLS system when a thread terminates. 551 // This method is called by the TLS system when a thread terminates.
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 ParentChildPairSnapshot(); 755 ParentChildPairSnapshot();
741 explicit ParentChildPairSnapshot( 756 explicit ParentChildPairSnapshot(
742 const ThreadData::ParentChildPair& parent_child); 757 const ThreadData::ParentChildPair& parent_child);
743 ~ParentChildPairSnapshot(); 758 ~ParentChildPairSnapshot();
744 759
745 BirthOnThreadSnapshot parent; 760 BirthOnThreadSnapshot parent;
746 BirthOnThreadSnapshot child; 761 BirthOnThreadSnapshot child;
747 }; 762 };
748 763
749 //------------------------------------------------------------------------------ 764 //------------------------------------------------------------------------------
750 // A snapshotted representation of the list of ThreadData objects for a process. 765 // A snapshotted representation of the list of ThreadData objects for a process,
766 // for a single profiling phase.
767
768 struct BASE_EXPORT ProcessDataPhaseSnapshot {
769 public:
770 ProcessDataPhaseSnapshot();
771 ~ProcessDataPhaseSnapshot();
772
773 std::vector<TaskSnapshot> tasks;
774 std::vector<ParentChildPairSnapshot> descendants;
775 };
776
777 //------------------------------------------------------------------------------
778 // A snapshotted representation of the list of ThreadData objects for a process,
779 // for all profiling phases, including the current one.
751 780
752 struct BASE_EXPORT ProcessDataSnapshot { 781 struct BASE_EXPORT ProcessDataSnapshot {
753 public: 782 public:
754 ProcessDataSnapshot(); 783 ProcessDataSnapshot();
755 ~ProcessDataSnapshot(); 784 ~ProcessDataSnapshot();
756 785
757 std::vector<TaskSnapshot> tasks; 786 PhasedProcessDataSnapshotMap phased_process_data_snapshots;
758 std::vector<ParentChildPairSnapshot> descendants; 787 base::ProcessId process_id;
759 int process_id;
760 }; 788 };
761 789
762 } // namespace tracked_objects 790 } // namespace tracked_objects
763 791
764 #endif // BASE_TRACKED_OBJECTS_H_ 792 #endif // BASE_TRACKED_OBJECTS_H_
OLDNEW
« no previous file with comments | « no previous file | base/tracked_objects.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698