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

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: isherman@ 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
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;
350 // Map from profiling phase number to the process-wide snapshotted
351 // representation of the list of ThreadData objects that died during the given
352 // phase.
353 typedef std::map<int, ProcessDataPhaseSnapshot> PhasedProcessDataSnapshotMap;
Alexei Svitkine (slow) 2015/03/16 22:00:15 Nit: This shouldn't be in the middle of a bunch of
vadimt 2015/03/16 23:09:13 Done.
344 struct ProcessDataSnapshot; 354 struct ProcessDataSnapshot;
345 class BASE_EXPORT TaskStopwatch; 355 class BASE_EXPORT TaskStopwatch;
346 356
347 class BASE_EXPORT ThreadData { 357 class BASE_EXPORT ThreadData {
348 public: 358 public:
349 // Current allowable states of the tracking system. The states can vary 359 // Current allowable states of the tracking system. The states can vary
350 // between ACTIVE and DEACTIVATED, but can never go back to UNINITIALIZED. 360 // between ACTIVE and DEACTIVATED, but can never go back to UNINITIALIZED.
351 enum Status { 361 enum Status {
352 UNINITIALIZED, // PRistine, link-time state before running. 362 UNINITIALIZED, // PRistine, link-time state before running.
353 DORMANT_DURING_TESTS, // Only used during testing. 363 DORMANT_DURING_TESTS, // Only used during testing.
(...skipping 14 matching lines...) Expand all
368 // set *before* any births on the threads have taken place. It is generally 378 // 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. 379 // only used by the message loop, which has a well defined thread name.
370 static void InitializeThreadContext(const std::string& suggested_name); 380 static void InitializeThreadContext(const std::string& suggested_name);
371 381
372 // Using Thread Local Store, find the current instance for collecting data. 382 // 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 383 // If an instance does not exist, construct one (and remember it for use on
374 // this thread. 384 // this thread.
375 // This may return NULL if the system is disabled for any reason. 385 // This may return NULL if the system is disabled for any reason.
376 static ThreadData* Get(); 386 static ThreadData* Get();
377 387
378 // Fills |process_data| with all the recursive results in our process. 388 // Fills |process_data_snapshot| with phased snapshots of all profiling
379 static void Snapshot(ProcessDataSnapshot* process_data); 389 // phases, including the current one.
390 static void Snapshot(ProcessDataSnapshot* process_data_snapshot);
380 391
381 // Finds (or creates) a place to count births from the given location in this 392 // Finds (or creates) a place to count births from the given location in this
382 // thread, and increment that tally. 393 // thread, and increment that tally.
383 // TallyABirthIfActive will returns NULL if the birth cannot be tallied. 394 // TallyABirthIfActive will returns NULL if the birth cannot be tallied.
384 static Births* TallyABirthIfActive(const Location& location); 395 static Births* TallyABirthIfActive(const Location& location);
385 396
386 // Records the end of a timed run of an object. The |completed_task| contains 397 // 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. 398 // 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 399 // 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 400 // 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 401 // 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. 402 // 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 403 // 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. 404 // finished). It is provided as an argument to help with testing.
394 static void TallyRunOnNamedThreadIfTracking( 405 static void TallyRunOnNamedThreadIfTracking(
395 const base::TrackingInfo& completed_task, 406 const base::TrackingInfo& completed_task,
396 const TaskStopwatch& stopwatch); 407 const TaskStopwatch& stopwatch);
397 408
398 // Record the end of a timed run of an object. The |birth| is the record for 409 // 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 410 // 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. 411 // 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 412 // The |start_of_run| is when the worker thread started to perform the run of
402 // the task. 413 // the task.
403 // The |end_of_run| was just obtained by a call to Now() (just after the task 414 // The |end_of_run| was just obtained by a call to Now() (just after the task
404 // finished). 415 // finished).
405 static void TallyRunOnWorkerThreadIfTracking( 416 static void TallyRunOnWorkerThreadIfTracking(const Births* birth,
406 const Births* birth, 417 const TrackedTime& time_posted,
407 const TrackedTime& time_posted, 418 const TaskStopwatch& stopwatch);
408 const TaskStopwatch& stopwatch);
409 419
410 // Record the end of execution in region, generally corresponding to a scope 420 // Record the end of execution in region, generally corresponding to a scope
411 // being exited. 421 // being exited.
412 static void TallyRunInAScopedRegionIfTracking( 422 static void TallyRunInAScopedRegionIfTracking(const Births* birth,
413 const Births* birth, 423 const TaskStopwatch& stopwatch);
414 const TaskStopwatch& stopwatch);
415 424
416 const std::string& thread_name() const { return thread_name_; } 425 const std::string& thread_name() const { return thread_name_; }
417 426
418 // Initializes all statics if needed (this initialization call should be made 427 // Initializes all statics if needed (this initialization call should be made
419 // while we are single threaded). Returns false if unable to initialize. 428 // while we are single threaded). Returns false if unable to initialize.
420 static bool Initialize(); 429 static bool Initialize();
421 430
422 // Sets internal status_. 431 // Sets internal status_.
423 // If |status| is false, then status_ is set to DEACTIVATED. 432 // If |status| is false, then status_ is set to DEACTIVATED.
424 // If |status| is true, then status_ is set to, PROFILING_ACTIVE, or 433 // 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); 515 Births* TallyABirth(const Location& location);
507 516
508 // Find a place to record a death on this thread. 517 // Find a place to record a death on this thread.
509 void TallyADeath(const Births& birth, 518 void TallyADeath(const Births& birth,
510 int32 queue_duration, 519 int32 queue_duration,
511 const TaskStopwatch& stopwatch); 520 const TaskStopwatch& stopwatch);
512 521
513 // Snapshot (under a lock) the profiled data for the tasks in each ThreadData 522 // 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 523 // instance. Also updates the |birth_counts| tally for each task to keep
515 // track of the number of living instances of the task. 524 // track of the number of living instances of the task.
516 static void SnapshotAllExecutedTasks(ProcessDataSnapshot* process_data, 525 static void SnapshotAllExecutedTasks(
517 BirthCountMap* birth_counts); 526 ProcessDataPhaseSnapshot* process_data_phase,
527 BirthCountMap* birth_counts);
528
529 // Fills |process_data_phase| with all the recursive results in our process.
530 static void SnapshotCurrentPhase(
531 ProcessDataPhaseSnapshot* process_data_phase);
518 532
519 // Snapshots (under a lock) the profiled data for the tasks for this thread 533 // 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 534 // 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 535 // 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 536 // 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 537 // 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. 538 // births for the task that have not yet been balanced by a death.
525 void SnapshotExecutedTasks(ProcessDataSnapshot* process_data, 539 void SnapshotExecutedTasks(ProcessDataPhaseSnapshot* process_data_phase,
526 BirthCountMap* birth_counts); 540 BirthCountMap* birth_counts);
527 541
528 // Using our lock, make a copy of the specified maps. This call may be made 542 // 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 543 // on non-local threads, which necessitate the use of the lock to prevent
530 // the map(s) from being reallocated while they are copied. 544 // the map(s) from being reallocated while they are copied.
531 void SnapshotMaps(BirthMap* birth_map, 545 void SnapshotMaps(BirthMap* birth_map,
532 DeathMap* death_map, 546 DeathMap* death_map,
533 ParentChildSet* parent_child_set); 547 ParentChildSet* parent_child_set);
534 548
535 // This method is called by the TLS system when a thread terminates. 549 // 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(); 753 ParentChildPairSnapshot();
740 explicit ParentChildPairSnapshot( 754 explicit ParentChildPairSnapshot(
741 const ThreadData::ParentChildPair& parent_child); 755 const ThreadData::ParentChildPair& parent_child);
742 ~ParentChildPairSnapshot(); 756 ~ParentChildPairSnapshot();
743 757
744 BirthOnThreadSnapshot parent; 758 BirthOnThreadSnapshot parent;
745 BirthOnThreadSnapshot child; 759 BirthOnThreadSnapshot child;
746 }; 760 };
747 761
748 //------------------------------------------------------------------------------ 762 //------------------------------------------------------------------------------
749 // A snapshotted representation of the list of ThreadData objects for a process. 763 // A snapshotted representation of the list of ThreadData objects for a process,
764 // for a single profiling phase.
765
766 struct BASE_EXPORT ProcessDataPhaseSnapshot {
767 public:
768 ProcessDataPhaseSnapshot();
769 ~ProcessDataPhaseSnapshot();
770
771 std::vector<TaskSnapshot> tasks;
772 std::vector<ParentChildPairSnapshot> descendants;
773 };
774
775 //------------------------------------------------------------------------------
776 // A snapshotted representation of the list of ThreadData objects for a process,
777 // for all profiling phases, including the current one.
750 778
751 struct BASE_EXPORT ProcessDataSnapshot { 779 struct BASE_EXPORT ProcessDataSnapshot {
752 public: 780 public:
753 ProcessDataSnapshot(); 781 ProcessDataSnapshot();
754 ~ProcessDataSnapshot(); 782 ~ProcessDataSnapshot();
755 783
756 std::vector<TaskSnapshot> tasks; 784 PhasedProcessDataSnapshotMap phased_process_data_snapshots;
757 std::vector<ParentChildPairSnapshot> descendants; 785 base::ProcessId process_id;
758 int process_id;
759 }; 786 };
760 787
761 } // namespace tracked_objects 788 } // namespace tracked_objects
762 789
763 #endif // BASE_TRACKED_OBJECTS_H_ 790 #endif // BASE_TRACKED_OBJECTS_H_
OLDNEW
« no previous file with comments | « no previous file | base/tracked_objects.cc » ('j') | chrome/browser/metrics/chrome_metrics_service_client.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698