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

Side by Side Diff: base/tracked_objects.h

Issue 2488073002: Reuse ThreadData instances associated with terminated named threads. (Closed)
Patch Set: remove dcheck Created 4 years, 1 month 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 <stdint.h> 8 #include <stdint.h>
9 9
10 #include <map> 10 #include <map>
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 // 52 //
53 // First off, when the instance is created, the FROM_HERE macro is expanded 53 // First off, when the instance is created, the FROM_HERE macro is expanded
54 // to specify the birth place (file, line, function) where the instance was 54 // to specify the birth place (file, line, function) where the instance was
55 // created. That data is used to create a transient Location instance 55 // created. That data is used to create a transient Location instance
56 // encapsulating the above triple of information. The strings (like __FILE__) 56 // encapsulating the above triple of information. The strings (like __FILE__)
57 // are passed around by reference, with the assumption that they are static, and 57 // are passed around by reference, with the assumption that they are static, and
58 // will never go away. This ensures that the strings can be dealt with as atoms 58 // will never go away. This ensures that the strings can be dealt with as atoms
59 // with great efficiency (i.e., copying of strings is never needed, and 59 // with great efficiency (i.e., copying of strings is never needed, and
60 // comparisons for equality can be based on pointer comparisons). 60 // comparisons for equality can be based on pointer comparisons).
61 // 61 //
62 // Next, a Births instance is created for use ONLY on the thread where this 62 // Next, a Births instance is constructed or found. A Births instance records
63 // instance was created. That Births instance records (in a base class 63 // (in a base class BirthOnThread) references to the static data provided in a
64 // BirthOnThread) references to the static data provided in a Location instance, 64 // Location instance, as well as a pointer to the ThreadData bound to the thread
65 // as well as a pointer specifying the thread on which the birth takes place. 65 // on which the birth takes place (see discussion on ThreadData below). There is
66 // Hence there is at most one Births instance for each Location on each thread. 66 // at most one Births instance for each Location / ThreadData pair. The derived
67 // The derived Births class contains slots for recording statistics about all 67 // Births class contains slots for recording statistics about all instances born
68 // instances born at the same location. Statistics currently include only the 68 // at the same location. Statistics currently include only the count of
69 // count of instances constructed. 69 // instances constructed.
70 // 70 //
71 // Since the base class BirthOnThread contains only constant data, it can be 71 // Since the base class BirthOnThread contains only constant data, it can be
72 // freely accessed by any thread at any time (i.e., only the statistic needs to 72 // freely accessed by any thread at any time. The statistics must be handled
73 // be handled carefully, and stats are updated exclusively on the birth thread). 73 // more carefully; they are updated exclusively by the single thread to which
74 // the ThreadData is bound at a given time.
74 // 75 //
75 // For Tasks, having now either constructed or found the Births instance 76 // For Tasks, having now either constructed or found the Births instance
76 // described above, a pointer to the Births instance is then recorded into the 77 // described above, a pointer to the Births instance is then recorded into the
77 // PendingTask structure in MessageLoop. This fact alone is very useful in 78 // PendingTask structure. This fact alone is very useful in debugging, when
78 // debugging, when there is a question of where an instance came from. In 79 // there is a question of where an instance came from. In addition, the birth
79 // addition, the birth time is also recorded and used to later evaluate the 80 // time is also recorded and used to later evaluate the lifetime duration of the
80 // lifetime duration of the whole Task. As a result of the above embedding, we 81 // whole Task. As a result of the above embedding, we can find out a Task's
81 // can find out a Task's location of birth, and thread of birth, without using 82 // location of birth, and name of birth thread, without using any locks, as all
82 // any locks, as all that data is constant across the life of the process. 83 // that data is constant across the life of the process.
83 // 84 //
84 // The above work *could* also be done for any other object as well by calling 85 // The above work *could* also be done for any other object as well by calling
85 // TallyABirthIfActive() and TallyRunOnNamedThreadIfTracking() as appropriate. 86 // TallyABirthIfActive() and TallyRunOnNamedThreadIfTracking() as appropriate.
86 // 87 //
87 // The amount of memory used in the above data structures depends on how many 88 // The maxium amount of memory used in the above data structures is the product
88 // threads there are, and how many Locations of construction there are. 89 // of the number of ThreadData instances and the number of Locations.
89 // Fortunately, we don't use memory that is the product of those two counts, but 90 // Fortunately, Locations are often created on a single thread and the memory
90 // rather we only need one Births instance for each thread that constructs an 91 // utilization is actually fairly restrained.
91 // instance at a Location. In many cases, instances are only created on one
92 // thread, so the memory utilization is actually fairly restrained.
93 // 92 //
94 // Lastly, when an instance is deleted, the final tallies of statistics are 93 // Lastly, when an instance is deleted, the final tallies of statistics are
95 // carefully accumulated. That tallying writes into slots (members) in a 94 // carefully accumulated. That tallying writes into slots (members) in a
96 // collection of DeathData instances. For each birth place Location that is 95 // collection of DeathData instances. For each Births / death ThreadData pair,
97 // destroyed on a thread, there is a DeathData instance to record the additional 96 // there is a DeathData instance to record the additional death count, as well
98 // death count, as well as accumulate the run-time and queue-time durations for 97 // as accumulate the run-time and queue-time durations for the instance as it is
99 // the instance as it is destroyed (dies). By maintaining a single place to 98 // destroyed (dies). Since a ThreadData is bound to a most one thread at a time,
danakj 2016/11/17 02:26:36 at most
fdoray 2016/11/17 13:20:19 Done.
100 // aggregate this running sum *only* for the given thread, we avoid the need to 99 // there is no need to lock such DeathData instances. (i.e., these accumulated
101 // lock such DeathData instances. (i.e., these accumulated stats in a DeathData 100 // stats in a DeathData instance are exclusively updated by the singular owning
102 // instance are exclusively updated by the singular owning thread). 101 // thread).
103 // 102 //
104 // With the above life cycle description complete, the major remaining detail 103 // With the above life cycle description complete, the major remaining detail is
105 // is explaining how each thread maintains a list of DeathData instances, and 104 // explaining how existing Births and DeathData instances are found to avoid
106 // of Births instances, and is able to avoid additional (redundant/unnecessary) 105 // redundant allocations.
107 // allocations.
108 // 106 //
109 // Each thread maintains a list of data items specific to that thread in a 107 // A ThreadData instance maintains maps of Births and DeathData instances. The
110 // ThreadData instance (for that specific thread only). The two critical items 108 // Births map is index by Location and the DeathData map is indexed by Births*.
danakj 2016/11/17 02:26:36 indexed
fdoray 2016/11/17 13:20:19 Done.
111 // are lists of DeathData and Births instances. These lists are maintained in 109 // As noted earlier, we can compare Locations very efficiently as we consider
112 // STL maps, which are indexed by Location. As noted earlier, we can compare 110 // the underlying data (file, function, line) to be atoms, and hence pointer
113 // locations very efficiently as we consider the underlying data (file, 111 // comparison is used rather than (slow) string comparisons.
114 // function, line) to be atoms, and hence pointer comparison is used rather than
115 // (slow) string comparisons.
116 // 112 //
117 // To provide a mechanism for iterating over all "known threads," which means 113 // The first time that a thread calls ThreadData::InitializeThreadContext() or
118 // threads that have recorded a birth or a death, we create a singly linked list 114 // ThreadData::Get(), a ThreadData instance is bound to it and stored in TLS. If
119 // of ThreadData instances. Each such instance maintains a pointer to the next 115 // a ThreadData bound to a terminated thread with the same sanitized name (i.e.
120 // one. A static member of ThreadData provides a pointer to the first item on 116 // name without trailing digits) as the current thread is available, it is
121 // this global list, and access via that all_thread_data_list_head_ item 117 // reused. Otherwise, a new ThreadData instance is instantiated. Since a
122 // requires the use of the list_lock_. 118 // ThreadData is bound to at most one thread at a time, there is no need to
119 // acquire a lock to access its maps. Over time, a ThreadData may be bound to
120 // different threads that share the same sanitized name.
121 //
122 // We maintain a list of all ThreadData instances for the current process. Each
123 // ThreadData instance has a pointer to the next one. A static member of
124 // ThreadData provides a pointer to the first item on this global list, and
125 // access via that all_thread_data_list_head_ item requires the use of the
126 // list_lock_.
127 //
123 // When new ThreadData instances is added to the global list, it is pre-pended, 128 // When new ThreadData instances is added to the global list, it is pre-pended,
124 // which ensures that any prior acquisition of the list is valid (i.e., the 129 // which ensures that any prior acquisition of the list is valid (i.e., the
125 // holder can iterate over it without fear of it changing, or the necessity of 130 // holder can iterate over it without fear of it changing, or the necessity of
126 // using an additional lock. Iterations are actually pretty rare (used 131 // using an additional lock. Iterations are actually pretty rare (used
127 // primarily for cleanup, or snapshotting data for display), so this lock has 132 // primarily for cleanup, or snapshotting data for display), so this lock has
128 // very little global performance impact. 133 // very little global performance impact.
129 // 134 //
130 // The above description tries to define the high performance (run time) 135 // The above description tries to define the high performance (run time)
131 // portions of these classes. After gathering statistics, calls instigated 136 // portions of these classes. After gathering statistics, calls instigated
132 // by visiting about:profiler will assemble and aggregate data for display. The 137 // by visiting about:profiler will assemble and aggregate data for display. The
(...skipping 30 matching lines...) Expand all
163 // atomically collecting all data, so we could have count that does not, for 168 // atomically collecting all data, so we could have count that does not, for
164 // example, match with the number of durations we accumulated). The advantage 169 // example, match with the number of durations we accumulated). The advantage
165 // to having fast (non-atomic) updates of the data outweighs the minimal risk of 170 // to having fast (non-atomic) updates of the data outweighs the minimal risk of
166 // a singular corrupt statistic snapshot (only the snapshot could be corrupt, 171 // a singular corrupt statistic snapshot (only the snapshot could be corrupt,
167 // not the underlying and ongoing statistic). In contrast, pointer data that 172 // not the underlying and ongoing statistic). In contrast, pointer data that
168 // is accessed during snapshotting is completely invariant, and hence is 173 // is accessed during snapshotting is completely invariant, and hence is
169 // perfectly acquired (i.e., no potential corruption, and no risk of a bad 174 // perfectly acquired (i.e., no potential corruption, and no risk of a bad
170 // memory reference). 175 // memory reference).
171 // 176 //
172 // TODO(jar): We can implement a Snapshot system that *tries* to grab the 177 // TODO(jar): We can implement a Snapshot system that *tries* to grab the
173 // snapshots on the source threads *when* they have MessageLoops available 178 // snapshots on the source threads *when* they have SingleThreadTaskRunners
174 // (worker threads don't have message loops generally, and hence gathering from 179 // available (worker threads don't have SingleThreadTaskRunners, and hence
175 // them will continue to be asynchronous). We had an implementation of this in 180 // gathering from them will continue to be asynchronous). We had an
176 // the past, but the difficulty is dealing with message loops being terminated. 181 // implementation of this in the past, but the difficulty is dealing with
177 // We can *try* to spam the available threads via some task runner to 182 // threads being terminated. We can *try* to post a task to threads that have a
178 // achieve this feat, and it *might* be valuable when we are collecting data 183 // SingleThreadTaskRunner and check if that succeeds (will fail if the thread
184 // has been terminated). This *might* be valuable when we are collecting data
179 // for upload via UMA (where correctness of data may be more significant than 185 // for upload via UMA (where correctness of data may be more significant than
180 // for a single screen of about:profiler). 186 // for a single screen of about:profiler).
181 // 187 //
182 // TODO(jar): We need to store DataCollections, and provide facilities for 188 // TODO(jar): We need to store DataCollections, and provide facilities for
183 // taking the difference between two gathered DataCollections. For now, we're 189 // taking the difference between two gathered DataCollections. For now, we're
184 // just adding a hack that Reset()s to zero all counts and stats. This is also 190 // just adding a hack that Reset()s to zero all counts and stats. This is also
185 // done in a slightly thread-unsafe fashion, as the resetting is done 191 // done in a slightly thread-unsafe fashion, as the resetting is done
186 // asynchronously relative to ongoing updates (but all data is 32 bit in size). 192 // asynchronously relative to ongoing updates (but all data is 32 bit in size).
187 // For basic profiling, this will work "most of the time," and should be 193 // For basic profiling, this will work "most of the time," and should be
188 // sufficient... but storing away DataCollections is the "right way" to do this. 194 // sufficient... but storing away DataCollections is the "right way" to do this.
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 DEACTIVATED, // No longer recording profiling. 449 DEACTIVATED, // No longer recording profiling.
444 PROFILING_ACTIVE, // Recording profiles. 450 PROFILING_ACTIVE, // Recording profiles.
445 STATUS_LAST = PROFILING_ACTIVE 451 STATUS_LAST = PROFILING_ACTIVE
446 }; 452 };
447 453
448 typedef base::hash_map<Location, Births*, Location::Hash> BirthMap; 454 typedef base::hash_map<Location, Births*, Location::Hash> BirthMap;
449 typedef std::map<const Births*, DeathData> DeathMap; 455 typedef std::map<const Births*, DeathData> DeathMap;
450 456
451 // Initialize the current thread context with a new instance of ThreadData. 457 // Initialize the current thread context with a new instance of ThreadData.
452 // This is used by all threads that have names, and should be explicitly 458 // This is used by all threads that have names, and should be explicitly
453 // set *before* any births on the threads have taken place. It is generally 459 // set *before* any births on the threads have taken place.
454 // only used by the message loop, which has a well defined thread name. 460 static void InitializeThreadContext(const std::string& thread_name);
455 static void InitializeThreadContext(const std::string& suggested_name);
456 461
457 // Using Thread Local Store, find the current instance for collecting data. 462 // Using Thread Local Store, find the current instance for collecting data.
458 // If an instance does not exist, construct one (and remember it for use on 463 // If an instance does not exist, construct one (and remember it for use on
459 // this thread. 464 // this thread.
460 // This may return NULL if the system is disabled for any reason. 465 // This may return NULL if the system is disabled for any reason.
461 static ThreadData* Get(); 466 static ThreadData* Get();
462 467
463 // Fills |process_data_snapshot| with phased snapshots of all profiling 468 // Fills |process_data_snapshot| with phased snapshots of all profiling
464 // phases, including the current one, identified by |current_profiling_phase|. 469 // phases, including the current one, identified by |current_profiling_phase|.
465 // |current_profiling_phase| is necessary because a child process can start 470 // |current_profiling_phase| is necessary because a child process can start
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 // finished). 508 // finished).
504 static void TallyRunOnWorkerThreadIfTracking(const Births* births, 509 static void TallyRunOnWorkerThreadIfTracking(const Births* births,
505 const TrackedTime& time_posted, 510 const TrackedTime& time_posted,
506 const TaskStopwatch& stopwatch); 511 const TaskStopwatch& stopwatch);
507 512
508 // Record the end of execution in region, generally corresponding to a scope 513 // Record the end of execution in region, generally corresponding to a scope
509 // being exited. 514 // being exited.
510 static void TallyRunInAScopedRegionIfTracking(const Births* births, 515 static void TallyRunInAScopedRegionIfTracking(const Births* births,
511 const TaskStopwatch& stopwatch); 516 const TaskStopwatch& stopwatch);
512 517
513 const std::string& thread_name() const { return thread_name_; } 518 const std::string& sanitized_thread_name() const {
519 return sanitized_thread_name_;
520 }
514 521
515 // Initializes all statics if needed (this initialization call should be made 522 // Initializes all statics if needed (this initialization call should be made
516 // while we are single threaded). 523 // while we are single threaded).
517 static void EnsureTlsInitialization(); 524 static void EnsureTlsInitialization();
518 525
519 // Sets internal status_. 526 // Sets internal status_.
520 // If |status| is false, then status_ is set to DEACTIVATED. 527 // If |status| is false, then status_ is set to DEACTIVATED.
521 // If |status| is true, then status_ is set to PROFILING_ACTIVE. 528 // If |status| is true, then status_ is set to PROFILING_ACTIVE.
522 static void InitializeAndSetTrackingStatus(Status status); 529 static void InitializeAndSetTrackingStatus(Status status);
523 530
(...skipping 28 matching lines...) Expand all
552 FRIEND_TEST_ALL_PREFIXES(TrackedObjectsTest, MinimalStartupShutdown); 559 FRIEND_TEST_ALL_PREFIXES(TrackedObjectsTest, MinimalStartupShutdown);
553 FRIEND_TEST_ALL_PREFIXES(TrackedObjectsTest, TinyStartupShutdown); 560 FRIEND_TEST_ALL_PREFIXES(TrackedObjectsTest, TinyStartupShutdown);
554 561
555 // Type for an alternate timer function (testing only). 562 // Type for an alternate timer function (testing only).
556 typedef unsigned int NowFunction(); 563 typedef unsigned int NowFunction();
557 564
558 typedef std::map<const BirthOnThread*, int> BirthCountMap; 565 typedef std::map<const BirthOnThread*, int> BirthCountMap;
559 typedef std::vector<std::pair<const Births*, DeathDataPhaseSnapshot>> 566 typedef std::vector<std::pair<const Births*, DeathDataPhaseSnapshot>>
560 DeathsSnapshot; 567 DeathsSnapshot;
561 568
562 // Worker thread construction creates a name since there is none. 569 explicit ThreadData(const std::string& sanitized_thread_name);
563 explicit ThreadData(int thread_number);
564
565 // Message loop based construction should provide a name.
566 explicit ThreadData(const std::string& suggested_name);
567
568 ~ThreadData(); 570 ~ThreadData();
569 571
570 // Push this instance to the head of all_thread_data_list_head_, linking it to 572 // Push this instance to the head of all_thread_data_list_head_, linking it to
571 // the previous head. This is performed after each construction, and leaves 573 // the previous head. This is performed after each construction, and leaves
572 // the instance permanently on that list. 574 // the instance permanently on that list.
573 void PushToHeadOfList(); 575 void PushToHeadOfList();
574 576
575 // (Thread safe) Get start of list of all ThreadData instances using the lock. 577 // (Thread safe) Get start of list of all ThreadData instances using the lock.
576 static ThreadData* first(); 578 static ThreadData* first();
577 579
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 // uninitialized) state. If there is any chance that other threads are still 623 // uninitialized) state. If there is any chance that other threads are still
622 // using the data structures, then the |leak| argument should be passed in as 624 // using the data structures, then the |leak| argument should be passed in as
623 // true, and the data structures (birth maps, death maps, ThreadData 625 // true, and the data structures (birth maps, death maps, ThreadData
624 // insntances, etc.) will be leaked and not deleted. If you have joined all 626 // insntances, etc.) will be leaked and not deleted. If you have joined all
625 // threads since the time that InitializeAndSetTrackingStatus() was called, 627 // threads since the time that InitializeAndSetTrackingStatus() was called,
626 // then you can pass in a |leak| value of false, and this function will 628 // then you can pass in a |leak| value of false, and this function will
627 // delete recursively all data structures, starting with the list of 629 // delete recursively all data structures, starting with the list of
628 // ThreadData instances. 630 // ThreadData instances.
629 static void ShutdownSingleThreadedCleanup(bool leak); 631 static void ShutdownSingleThreadedCleanup(bool leak);
630 632
633 // Returns a ThreadData instance for a thread whose sanitized name is
634 // |sanitized_thread_name|. The returned instance may have been extracted from
635 // the list of retired ThreadData instances or newly allocated.
636 static ThreadData* GetRetiredOrCreateThreadData(
637 const std::string& sanitized_thread_name);
638
631 // When non-null, this specifies an external function that supplies monotone 639 // When non-null, this specifies an external function that supplies monotone
632 // increasing time functcion. 640 // increasing time functcion.
633 static NowFunction* now_function_for_testing_; 641 static NowFunction* now_function_for_testing_;
634 642
635 // We use thread local store to identify which ThreadData to interact with. 643 // We use thread local store to identify which ThreadData to interact with.
636 static base::ThreadLocalStorage::StaticSlot tls_index_; 644 static base::ThreadLocalStorage::StaticSlot tls_index_;
637 645
638 // List of ThreadData instances for use with worker threads. When a worker 646 // Linked list of ThreadData instances that were associated with threads that
639 // thread is done (terminated), we push it onto this list. When a new worker 647 // have been terminated and that have not been associated with a new thread
640 // thread is created, we first try to re-use a ThreadData instance from the 648 // since then. This is only accessed while |list_lock_| is held.
641 // list, and if none are available, construct a new one. 649 static ThreadData* first_retired_thread_data_;
642 // This is only accessed while list_lock_ is held.
643 static ThreadData* first_retired_worker_;
644 650
645 // Link to the most recently created instance (starts a null terminated list). 651 // Link to the most recently created instance (starts a null terminated list).
646 // The list is traversed by about:profiler when it needs to snapshot data. 652 // The list is traversed by about:profiler when it needs to snapshot data.
647 // This is only accessed while list_lock_ is held. 653 // This is only accessed while list_lock_ is held.
648 static ThreadData* all_thread_data_list_head_; 654 static ThreadData* all_thread_data_list_head_;
649 655
650 // The next available worker thread number. This should only be accessed when
651 // the list_lock_ is held.
652 static int worker_thread_data_creation_count_;
653
654 // The number of times TLS has called us back to cleanup a ThreadData 656 // The number of times TLS has called us back to cleanup a ThreadData
655 // instance. This is only accessed while list_lock_ is held. 657 // instance. This is only accessed while list_lock_ is held.
656 static int cleanup_count_; 658 static int cleanup_count_;
657 659
658 // Incarnation sequence number, indicating how many times (during unittests) 660 // Incarnation sequence number, indicating how many times (during unittests)
659 // we've either transitioned out of UNINITIALIZED, or into that state. This 661 // we've either transitioned out of UNINITIALIZED, or into that state. This
660 // value is only accessed while the list_lock_ is held. 662 // value is only accessed while the list_lock_ is held.
661 static int incarnation_counter_; 663 static int incarnation_counter_;
662 664
663 // Protection for access to all_thread_data_list_head_, and to 665 // Protection for access to all_thread_data_list_head_, and to
664 // unregistered_thread_data_pool_. This lock is leaked at shutdown. 666 // unregistered_thread_data_pool_. This lock is leaked at shutdown.
665 // The lock is very infrequently used, so we can afford to just make a lazy 667 // The lock is very infrequently used, so we can afford to just make a lazy
666 // instance and be safe. 668 // instance and be safe.
667 static base::LazyInstance<base::Lock>::Leaky list_lock_; 669 static base::LazyInstance<base::Lock>::Leaky list_lock_;
668 670
669 // We set status_ to SHUTDOWN when we shut down the tracking service. 671 // We set status_ to SHUTDOWN when we shut down the tracking service.
670 static base::subtle::Atomic32 status_; 672 static base::subtle::Atomic32 status_;
671 673
672 // Link to next instance (null terminated list). Used to globally track all 674 // Link to next instance (null terminated list). Used to globally track all
673 // registered instances (corresponds to all registered threads where we keep 675 // registered instances (corresponds to all registered threads where we keep
674 // data). 676 // data).
675 ThreadData* next_; 677 ThreadData* next_;
676 678
677 // Pointer to another ThreadData instance for a Worker-Thread that has been 679 // Pointer to another retired ThreadData instance. This value is nullptr if
678 // retired (its thread was terminated). This value is non-NULL only for a 680 // this is associated with an active thread.
679 // retired ThreadData associated with a Worker-Thread. 681 ThreadData* next_retired_;
danakj 2016/11/17 02:26:36 nit: next_retired_thread_data_
fdoray 2016/11/17 13:20:19 Done.
680 ThreadData* next_retired_worker_;
681 682
682 // The name of the thread that is being recorded. If this thread has no 683 // The name of the thread that is being recorded, with trailing digits
683 // message_loop, then this is a worker thread, with a sequence number postfix. 684 // replaced with "*".
danakj 2016/11/17 02:26:36 Are the number of digits always the same?
fdoray 2016/11/17 13:20:19 Clarified comment. All trailing digits are replace
684 std::string thread_name_; 685 const std::string sanitized_thread_name_;
685
686 // Indicate if this is a worker thread, and the ThreadData contexts should be
687 // stored in the unregistered_thread_data_pool_ when not in use.
688 // Value is zero when it is not a worker thread. Value is a positive integer
689 // corresponding to the created thread name if it is a worker thread.
690 int worker_thread_number_;
691 686
692 // A map used on each thread to keep track of Births on this thread. 687 // A map used on each thread to keep track of Births on this thread.
693 // This map should only be accessed on the thread it was constructed on. 688 // This map should only be accessed on the thread it was constructed on.
694 // When a snapshot is needed, this structure can be locked in place for the 689 // When a snapshot is needed, this structure can be locked in place for the
695 // duration of the snapshotting activity. 690 // duration of the snapshotting activity.
696 BirthMap birth_map_; 691 BirthMap birth_map_;
697 692
698 // Similar to birth_map_, this records informations about death of tracked 693 // Similar to birth_map_, this records informations about death of tracked
699 // instances (i.e., when a tracked instance was destroyed on this thread). 694 // instances (i.e., when a tracked instance was destroyed on this thread).
700 // It is locked before changing, and hence other threads may access it by 695 // It is locked before changing, and hence other threads may access it by
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
811 ProcessDataSnapshot(const ProcessDataSnapshot& other); 806 ProcessDataSnapshot(const ProcessDataSnapshot& other);
812 ~ProcessDataSnapshot(); 807 ~ProcessDataSnapshot();
813 808
814 PhasedProcessDataSnapshotMap phased_snapshots; 809 PhasedProcessDataSnapshotMap phased_snapshots;
815 base::ProcessId process_id; 810 base::ProcessId process_id;
816 }; 811 };
817 812
818 } // namespace tracked_objects 813 } // namespace tracked_objects
819 814
820 #endif // BASE_TRACKED_OBJECTS_H_ 815 #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