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

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

Powered by Google App Engine
This is Rietveld 408576698