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

Side by Side Diff: base/tracked_objects.h

Issue 9702014: [UMA] Use proper C++ objects to serialize tracked_objects across process boundaries. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 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 | Annotate | Revision Log
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 #pragma once 7 #pragma once
8 8
9 #include <map> 9 #include <map>
10 #include <set> 10 #include <set>
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 // very little global performance impact. 122 // very little global performance impact.
123 // 123 //
124 // The above description tries to define the high performance (run time) 124 // The above description tries to define the high performance (run time)
125 // portions of these classes. After gathering statistics, calls instigated 125 // portions of these classes. After gathering statistics, calls instigated
126 // by visiting about:profiler will assemble and aggregate data for display. The 126 // by visiting about:profiler will assemble and aggregate data for display. The
127 // following data structures are used for producing such displays. They are 127 // following data structures are used for producing such displays. They are
128 // not performance critical, and their only major constraint is that they should 128 // not performance critical, and their only major constraint is that they should
129 // be able to run concurrently with ongoing augmentation of the birth and death 129 // be able to run concurrently with ongoing augmentation of the birth and death
130 // data. 130 // data.
131 // 131 //
132 // This header also exports collection of classes that provide serialized
133 // representations of the core classes tracked_objects:: classes. These
134 // serialized representations are designed for safe transmission of the
135 // tracked_objects:: data across process boundaries. Each consists of:
136 // (1) a default constructor, to support the IPC serialization macros,
137 // (2) a simple constructor that extracts data from the type being serialized,
138 // (3) a ToValue() function that writes the serialized data into the passed
139 // |dictionary| -- which will typically then be automatically translated to
140 // JSON for rendering the collected profiler data -- and
141 // (4) the serialized data.
142 //
132 // 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
133 // structures that are asynchronously changing on various threads. For display 144 // structures that are asynchronously changing on various threads. For
134 // purposes, we need to construct Snapshot instances for each combination of 145 // serialization and display purposes, we need to construct SerializedSnapshot
135 // birth thread, death thread, and location, along with the count of such 146 // instances for each combination of birth thread, death thread, and location,
136 // lifetimes. We gather such data into a Snapshot instances, so that such 147 // along with the count of such lifetimes. We gather such data into a
137 // instances can be sorted and aggregated (and remain frozen during our 148 // SerializedSnapshot instances, so that such instances can be sorted and
138 // processing). Snapshot instances use pointers to constant portions of the 149 // aggregated (and remain frozen during our processing).
139 // birth and death datastructures, but have local (frozen) copies of the actual
140 // statistics (birth count, durations, etc. etc.).
141 // 150 //
142 // A DataCollector is a container object that holds a set of Snapshots. The 151 // The SerializedProcessData struct is a serialized representation of the list
143 // statistics in a snapshot are gathered asynhcronously relative to their 152 // of ThreadData objects for this process. It holds a set of
144 // ongoing updates. It is possible, though highly unlikely, that stats could be 153 // SerializedSnapshots and tracks parent/child relationships for the executed
145 // incorrectly recorded by this process (all data is held in 32 bit ints, but we 154 // tasks. The statistics in a snapshot are gathered asynhcronously relative to
146 // are not atomically collecting all data, so we could have count that does not, 155 // their ongoing updates. It is possible, though highly unlikely, that stats
147 // for example, match with the number of durations we accumulated). The 156 // could be incorrectly recorded by this process (all data is held in 32 bit
148 // advantage to having fast (non-atomic) updates of the data outweighs the 157 // ints, but we are not atomically collecting all data, so we could have count
149 // minimal risk of a singular corrupt statistic snapshot (only the snapshot 158 // that does not, for example, match with the number of durations we
150 // could be corrupt, not the underlying and ongoing statistic). In constrast, 159 // accumulated). The advantage to having fast (non-atomic) updates of the data
151 // pointer data that is accessed during snapshotting is completely invariant, 160 // outweighs the minimal risk of a singular corrupt statistic snapshot (only the
152 // and hence is perfectly acquired (i.e., no potential corruption, and no risk 161 // snapshot could be corrupt, not the underlying and ongoing statistic). In
153 // of a bad memory reference). 162 // constrast, pointer data that is accessed during snapshotting is completely
154 // 163 // invariant, and hence is perfectly acquired (i.e., no potential corruption,
155 // After an array of Snapshots instances are collected into a DataCollector, 164 // and no risk of a bad memory reference).
156 // they need to be prepared for displaying our output. We currently implement a
157 // serialization into a Value hierarchy, which is automatically translated to
158 // JSON when supplied to rendering Java Scirpt.
159 // 165 //
160 // TODO(jar): We can implement a Snapshot system that *tries* to grab the 166 // TODO(jar): We can implement a Snapshot system that *tries* to grab the
161 // snapshots on the source threads *when* they have MessageLoops available 167 // snapshots on the source threads *when* they have MessageLoops available
162 // (worker threads don't have message loops generally, and hence gathering from 168 // (worker threads don't have message loops generally, and hence gathering from
163 // them will continue to be asynchronous). We had an implementation of this in 169 // them will continue to be asynchronous). We had an implementation of this in
164 // the past, but the difficulty is dealing with message loops being terminated. 170 // the past, but the difficulty is dealing with message loops being terminated.
165 // We can *try* to spam the available threads via some message loop proxy to 171 // We can *try* to spam the available threads via some message loop proxy to
166 // achieve this feat, and it *might* be valuable when we are colecting data for 172 // achieve this feat, and it *might* be valuable when we are colecting data for
167 // upload via UMA (where correctness of data may be more significant than for a 173 // upload via UMA (where correctness of data may be more significant than for a
168 // single screen of about:profiler). 174 // single screen of about:profiler).
(...skipping 20 matching lines...) Expand all
189 namespace tracked_objects { 195 namespace tracked_objects {
190 196
191 //------------------------------------------------------------------------------ 197 //------------------------------------------------------------------------------
192 // For a specific thread, and a specific birth place, the collection of all 198 // For a specific thread, and a specific birth place, the collection of all
193 // death info (with tallies for each death thread, to prevent access conflicts). 199 // death info (with tallies for each death thread, to prevent access conflicts).
194 class ThreadData; 200 class ThreadData;
195 class BASE_EXPORT BirthOnThread { 201 class BASE_EXPORT BirthOnThread {
196 public: 202 public:
197 BirthOnThread(const Location& location, const ThreadData& current); 203 BirthOnThread(const Location& location, const ThreadData& current);
198 204
199 const Location location() const; 205 const Location location() const { return location_; }
200 const ThreadData* birth_thread() const; 206 const ThreadData* birth_thread() const { return birth_thread_; }
201
202 // Insert our state (location, and thread name) into the dictionary.
203 // Use the supplied |prefix| in front of "thread_name" and "location"
204 // respectively when defining keys.
205 void ToValue(const std::string& prefix,
206 base::DictionaryValue* dictionary) const;
207 207
208 private: 208 private:
209 // File/lineno of birth. This defines the essence of the task, as the context 209 // File/lineno of birth. This defines the essence of the task, as the context
210 // of the birth (construction) often tell what the item is for. This field 210 // of the birth (construction) often tell what the item is for. This field
211 // is const, and hence safe to access from any thread. 211 // is const, and hence safe to access from any thread.
212 const Location location_; 212 const Location location_;
213 213
214 // The thread that records births into this object. Only this thread is 214 // The thread that records births into this object. Only this thread is
215 // allowed to update birth_count_ (which changes over time). 215 // allowed to update birth_count_ (which changes over time).
216 const ThreadData* const birth_thread_; 216 const ThreadData* const birth_thread_;
217 217
218 DISALLOW_COPY_AND_ASSIGN(BirthOnThread); 218 DISALLOW_COPY_AND_ASSIGN(BirthOnThread);
219 }; 219 };
220 220
221 //------------------------------------------------------------------------------ 221 //------------------------------------------------------------------------------
222 // A serialized representation of the BirthOnThread class.
223
224 struct BASE_EXPORT SerializedBirthOnThread {
225 SerializedBirthOnThread();
226 SerializedBirthOnThread(const BirthOnThread& birth);
227 ~SerializedBirthOnThread();
228
229 void ToValue(const std::string& prefix,
230 base::DictionaryValue* dictionary) const;
231
232 SerializedLocation location;
233 std::string thread_name;
234 };
235
236 //------------------------------------------------------------------------------
222 // A class for accumulating counts of births (without bothering with a map<>). 237 // A class for accumulating counts of births (without bothering with a map<>).
223 238
224 class BASE_EXPORT Births: public BirthOnThread { 239 class BASE_EXPORT Births: public BirthOnThread {
225 public: 240 public:
226 Births(const Location& location, const ThreadData& current); 241 Births(const Location& location, const ThreadData& current);
227 242
228 int birth_count() const; 243 int birth_count() const;
229 244
230 // When we have a birth we update the count for this BirhPLace. 245 // When we have a birth we update the count for this birthplace.
231 void RecordBirth(); 246 void RecordBirth();
232 247
233 // When a birthplace is changed (updated), we need to decrement the counter 248 // When a birthplace is changed (updated), we need to decrement the counter
234 // for the old instance. 249 // for the old instance.
235 void ForgetBirth(); 250 void ForgetBirth();
236 251
237 // Hack to quickly reset all counts to zero. 252 // Hack to quickly reset all counts to zero.
238 void Clear(); 253 void Clear();
239 254
240 private: 255 private:
(...skipping 17 matching lines...) Expand all
258 // threads, we create DeathData stats that tally the number of births without 273 // threads, we create DeathData stats that tally the number of births without
259 // a corresponding death. 274 // a corresponding death.
260 explicit DeathData(int count); 275 explicit DeathData(int count);
261 276
262 // Update stats for a task destruction (death) that had a Run() time of 277 // Update stats for a task destruction (death) that had a Run() time of
263 // |duration|, and has had a queueing delay of |queue_duration|. 278 // |duration|, and has had a queueing delay of |queue_duration|.
264 void RecordDeath(const DurationInt queue_duration, 279 void RecordDeath(const DurationInt queue_duration,
265 const DurationInt run_duration, 280 const DurationInt run_duration,
266 int random_number); 281 int random_number);
267 282
268 // Metrics accessors, used only in tests. 283 // Metrics accessors, used only for serialization and in tests.
269 int count() const; 284 int count() const;
270 DurationInt run_duration_sum() const; 285 DurationInt run_duration_sum() const;
271 DurationInt run_duration_max() const; 286 DurationInt run_duration_max() const;
272 DurationInt run_duration_sample() const; 287 DurationInt run_duration_sample() const;
273 DurationInt queue_duration_sum() const; 288 DurationInt queue_duration_sum() const;
274 DurationInt queue_duration_max() const; 289 DurationInt queue_duration_max() const;
275 DurationInt queue_duration_sample() const; 290 DurationInt queue_duration_sample() const;
276 291
277 // Construct a DictionaryValue instance containing all our stats. The caller
278 // assumes ownership of the returned instance.
279 base::DictionaryValue* ToValue() const;
280
281 // Reset the max values to zero. 292 // Reset the max values to zero.
282 void ResetMax(); 293 void ResetMax();
283 294
284 // Reset all tallies to zero. This is used as a hack on realtime data. 295 // Reset all tallies to zero. This is used as a hack on realtime data.
285 void Clear(); 296 void Clear();
286 297
287 private: 298 private:
288 // Members are ordered from most regularly read and updated, to least 299 // Members are ordered from most regularly read and updated, to least
289 // frequently used. This might help a bit with cache lines. 300 // frequently used. This might help a bit with cache lines.
290 // Number of runs seen (divisor for calculating averages). 301 // Number of runs seen (divisor for calculating averages).
291 int count_; 302 int count_;
292 // Basic tallies, used to compute averages. 303 // Basic tallies, used to compute averages.
293 DurationInt run_duration_sum_; 304 DurationInt run_duration_sum_;
294 DurationInt queue_duration_sum_; 305 DurationInt queue_duration_sum_;
295 // Max values, used by local visualization routines. These are often read, 306 // Max values, used by local visualization routines. These are often read,
296 // but rarely updated. 307 // but rarely updated.
297 DurationInt run_duration_max_; 308 DurationInt run_duration_max_;
298 DurationInt queue_duration_max_; 309 DurationInt queue_duration_max_;
299 // Samples, used by by crowd sourcing gatherers. These are almost never read, 310 // Samples, used by by crowd sourcing gatherers. These are almost never read,
300 // and rarely updated. 311 // and rarely updated.
301 DurationInt run_duration_sample_; 312 DurationInt run_duration_sample_;
302 DurationInt queue_duration_sample_; 313 DurationInt queue_duration_sample_;
303 }; 314 };
304 315
305 //------------------------------------------------------------------------------ 316 //------------------------------------------------------------------------------
317 // A serialized representation of the DeathData class.
318
319 struct BASE_EXPORT SerializedDeathData {
320 SerializedDeathData();
321 SerializedDeathData(const DeathData& death_data);
322 ~SerializedDeathData();
323
324 void ToValue(base::DictionaryValue* dictionary) const;
325
326 int count;
327 int run_duration_sum;
328 int run_duration_max;
329 int run_duration_sample;
330 int queue_duration_sum;
331 int queue_duration_max;
332 int queue_duration_sample;
333 };
334
335 //------------------------------------------------------------------------------
306 // A temporary collection of data that can be sorted and summarized. It is 336 // A temporary collection of data that can be sorted and summarized. It is
307 // gathered (carefully) from many threads. Instances are held in arrays and 337 // gathered (carefully) from many threads. Instances are held in arrays and
308 // processed, filtered, and rendered. 338 // processed, filtered, and rendered.
309 // The source of this data was collected on many threads, and is asynchronously 339 // The source of this data was collected on many threads, and is asynchronously
310 // changing. The data in this instance is not asynchronously changing. 340 // changing. The data in this instance is not asynchronously changing.
311 341
312 class BASE_EXPORT Snapshot { 342 struct BASE_EXPORT SerializedSnapshot {
313 public: 343 SerializedSnapshot();
314 // When snapshotting a full life cycle set (birth-to-death), use this: 344 SerializedSnapshot(const BirthOnThread& birth,
315 Snapshot(const BirthOnThread& birth_on_thread, 345 const DeathData& death_data,
316 const ThreadData& death_thread, 346 const std::string& death_thread_name);
317 const DeathData& death_data); 347 ~SerializedSnapshot();
318 348
319 // When snapshotting a birth, with no death yet, use this: 349 void ToValue(base::DictionaryValue* dictionary) const;
320 Snapshot(const BirthOnThread& birth_on_thread, int count);
321 350
322 // Accessor, that provides default value when there is no death thread. 351 SerializedBirthOnThread birth;
323 const std::string DeathThreadName() const; 352 SerializedDeathData death_data;
324 353 std::string death_thread_name;
325 // Construct a DictionaryValue instance containing all our data recursively.
326 // The caller assumes ownership of the memory in the returned instance.
327 base::DictionaryValue* ToValue() const;
328
329 private:
330 const BirthOnThread* birth_; // Includes Location and birth_thread.
331 const ThreadData* death_thread_;
332 DeathData death_data_;
333 }; 354 };
334 355
335 //------------------------------------------------------------------------------ 356 //------------------------------------------------------------------------------
336 // For each thread, we have a ThreadData that stores all tracking info generated 357 // For each thread, we have a ThreadData that stores all tracking info generated
337 // on this thread. This prevents the need for locking as data accumulates. 358 // on this thread. This prevents the need for locking as data accumulates.
338 // We use ThreadLocalStorage to quickly identfy the current ThreadData context. 359 // We use ThreadLocalStorage to quickly identfy the current ThreadData context.
339 // We also have a linked list of ThreadData instances, and that list is used to 360 // We also have a linked list of ThreadData instances, and that list is used to
340 // harvest data from all existing instances. 361 // harvest data from all existing instances.
341 362
363 struct SerializedProcessData;
342 class BASE_EXPORT ThreadData { 364 class BASE_EXPORT ThreadData {
343 public: 365 public:
344 // Current allowable states of the tracking system. The states can vary 366 // Current allowable states of the tracking system. The states can vary
345 // between ACTIVE and DEACTIVATED, but can never go back to UNINITIALIZED. 367 // between ACTIVE and DEACTIVATED, but can never go back to UNINITIALIZED.
346 enum Status { 368 enum Status {
347 UNINITIALIZED, // PRistine, link-time state before running. 369 UNINITIALIZED, // PRistine, link-time state before running.
348 DORMANT_DURING_TESTS, // Only used during testing. 370 DORMANT_DURING_TESTS, // Only used during testing.
349 DEACTIVATED, // No longer recording profling. 371 DEACTIVATED, // No longer recording profling.
350 PROFILING_ACTIVE, // Recording profiles (no parent-child links). 372 PROFILING_ACTIVE, // Recording profiles (no parent-child links).
351 PROFILING_CHILDREN_ACTIVE, // Fully active, recording parent-child links. 373 PROFILING_CHILDREN_ACTIVE, // Fully active, recording parent-child links.
(...skipping 10 matching lines...) Expand all
362 // set *before* any births on the threads have taken place. It is generally 384 // set *before* any births on the threads have taken place. It is generally
363 // only used by the message loop, which has a well defined thread name. 385 // only used by the message loop, which has a well defined thread name.
364 static void InitializeThreadContext(const std::string& suggested_name); 386 static void InitializeThreadContext(const std::string& suggested_name);
365 387
366 // Using Thread Local Store, find the current instance for collecting data. 388 // Using Thread Local Store, find the current instance for collecting data.
367 // If an instance does not exist, construct one (and remember it for use on 389 // If an instance does not exist, construct one (and remember it for use on
368 // this thread. 390 // this thread.
369 // This may return NULL if the system is disabled for any reason. 391 // This may return NULL if the system is disabled for any reason.
370 static ThreadData* Get(); 392 static ThreadData* Get();
371 393
372 // Constructs a DictionaryValue instance containing all recursive results in 394 // Fills |process_data| with all the recursive results in our process.
373 // our process. The caller assumes ownership of the memory in the returned 395 // During the scavenging, if |reset_max| is true, then the DeathData instances
374 // instance. During the scavenging, if |reset_max| is true, then the 396 // max-values are reset to zero during this scan.
375 // DeathData instances max-values are reset to zero during this scan. 397 static void ToSerializedProcessData(bool reset_max,
376 static base::DictionaryValue* ToValue(bool reset_max); 398 SerializedProcessData* process_data);
377 399
378 // Finds (or creates) a place to count births from the given location in this 400 // Finds (or creates) a place to count births from the given location in this
379 // thread, and increment that tally. 401 // thread, and increment that tally.
380 // TallyABirthIfActive will returns NULL if the birth cannot be tallied. 402 // TallyABirthIfActive will returns NULL if the birth cannot be tallied.
381 static Births* TallyABirthIfActive(const Location& location); 403 static Births* TallyABirthIfActive(const Location& location);
382 404
383 // Records the end of a timed run of an object. The |completed_task| contains 405 // Records the end of a timed run of an object. The |completed_task| contains
384 // a pointer to a Births, the time_posted, and a delayed_start_time if any. 406 // a pointer to a Births, the time_posted, and a delayed_start_time if any.
385 // The |start_of_run| indicates when we started to perform the run of the 407 // The |start_of_run| indicates when we started to perform the run of the
386 // task. The delayed_start_time is non-null for tasks that were posted as 408 // task. The delayed_start_time is non-null for tasks that were posted as
(...skipping 21 matching lines...) Expand all
408 430
409 // Record the end of execution in region, generally corresponding to a scope 431 // Record the end of execution in region, generally corresponding to a scope
410 // being exited. 432 // being exited.
411 static void TallyRunInAScopedRegionIfTracking( 433 static void TallyRunInAScopedRegionIfTracking(
412 const Births* birth, 434 const Births* birth,
413 const TrackedTime& start_of_run, 435 const TrackedTime& start_of_run,
414 const TrackedTime& end_of_run); 436 const TrackedTime& end_of_run);
415 437
416 const std::string thread_name() const; 438 const std::string thread_name() const;
417 439
418 // Snapshot (under a lock) copies of the maps in each ThreadData instance. For
419 // each set of maps (BirthMap, DeathMap, and ParentChildSet) call the Append()
420 // method of the |target| DataCollector. If |reset_max| is true, then the max
421 // values in each DeathData instance should be reset during the scan.
422 static void SendAllMaps(bool reset_max, class DataCollector* target);
423
424 // Hack: asynchronously clear all birth counts and death tallies data values 440 // Hack: asynchronously clear all birth counts and death tallies data values
425 // in all ThreadData instances. The numerical (zeroing) part is done without 441 // in all ThreadData instances. The numerical (zeroing) part is done without
426 // use of a locks or atomics exchanges, and may (for int64 values) produce 442 // use of a locks or atomics exchanges, and may (for int64 values) produce
427 // bogus counts VERY rarely. 443 // bogus counts VERY rarely.
428 static void ResetAllThreadData(); 444 static void ResetAllThreadData();
429 445
430 // Initializes all statics if needed (this initialization call should be made 446 // Initializes all statics if needed (this initialization call should be made
431 // while we are single threaded). Returns false if unable to initialize. 447 // while we are single threaded). Returns false if unable to initialize.
432 static bool Initialize(); 448 static bool Initialize();
433 449
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 527
512 528
513 // In this thread's data, record a new birth. 529 // In this thread's data, record a new birth.
514 Births* TallyABirth(const Location& location); 530 Births* TallyABirth(const Location& location);
515 531
516 // Find a place to record a death on this thread. 532 // Find a place to record a death on this thread.
517 void TallyADeath(const Births& birth, 533 void TallyADeath(const Births& birth,
518 DurationInt queue_duration, 534 DurationInt queue_duration,
519 DurationInt duration); 535 DurationInt duration);
520 536
537 // Snapshot (under a lock) the profiled data for the tasks in each ThreadData
538 // instance. Also updates the |birth_counts| tally for each task to keep
539 // track of the number of living instances of the task. If |reset_max| is
540 // true, then the max values in each DeathData instance should be reset during
541 // the scan.
542 static void SerializeAllExecutedTasks(
543 bool reset_max,
544 SerializedProcessData* process_data,
545 std::map<const BirthOnThread*, int>* birth_counts);
546
547 // Snapshots (under a lock) the profiled data for the tasks for this thread
548 // and serializes all of the executed tasks' data -- i.e. the data for the
549 // tasks with with entries in the death_map_ -- into |process_data|. Also
550 // updates the |birth_counts| tally for each task to keep track of the number
551 // of living instances of the task. If |reset_max| is true, then the max
552 // values in each DeathData instance should be reset during the scan.
553 void SerializeExecutedTasks(
554 bool reset_max,
555 SerializedProcessData* process_data,
556 std::map<const BirthOnThread*, int>* birth_counts);
557
521 // Using our lock, make a copy of the specified maps. This call may be made 558 // Using our lock, make a copy of the specified maps. This call may be made
522 // on non-local threads, which necessitate the use of the lock to prevent 559 // on non-local threads, which necessitate the use of the lock to prevent
523 // the map(s) from being reallocaed while they are copied. If |reset_max| is 560 // the map(s) from being reallocaed while they are copied. If |reset_max| is
524 // true, then, just after we copy the DeathMap, we will set the max values to 561 // true, then, just after we copy the DeathMap, we will set the max values to
525 // zero in the active DeathMap (not the snapshot). 562 // zero in the active DeathMap (not the snapshot).
526 void SnapshotMaps(bool reset_max, 563 void SnapshotMaps(bool reset_max,
527 BirthMap* birth_map, 564 BirthMap* birth_map,
528 DeathMap* death_map, 565 DeathMap* death_map,
529 ParentChildSet* parent_child_set); 566 ParentChildSet* parent_child_set);
530 567
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
655 // Record of what the incarnation_counter_ was when this instance was created. 692 // Record of what the incarnation_counter_ was when this instance was created.
656 // If the incarnation_counter_ has changed, then we avoid pushing into the 693 // If the incarnation_counter_ has changed, then we avoid pushing into the
657 // pool (this is only critical in tests which go through multiple 694 // pool (this is only critical in tests which go through multiple
658 // incarnations). 695 // incarnations).
659 int incarnation_count_for_pool_; 696 int incarnation_count_for_pool_;
660 697
661 DISALLOW_COPY_AND_ASSIGN(ThreadData); 698 DISALLOW_COPY_AND_ASSIGN(ThreadData);
662 }; 699 };
663 700
664 //------------------------------------------------------------------------------ 701 //------------------------------------------------------------------------------
665 // DataCollector is a container class for Snapshot and BirthOnThread count 702 // A serialized representation of a (parent, child) task pair, for tracking
666 // items. 703 // hierarchical profiles.
667 704
668 class BASE_EXPORT DataCollector { 705 struct BASE_EXPORT SerializedParentChildPair {
669 public: 706 public:
670 typedef std::vector<Snapshot> Collection; 707 SerializedParentChildPair();
708 SerializedParentChildPair(const ThreadData::ParentChildPair& parent_child);
709 ~SerializedParentChildPair();
671 710
672 // Construct with a list of how many threads should contribute. This helps us
673 // determine (in the async case) when we are done with all contributions.
674 DataCollector();
675 ~DataCollector();
676
677 // Adds all stats from the indicated thread into our arrays. Accepts copies
678 // of the birth_map and death_map, so that the data will not change during the
679 // iterations and processing.
680 void Append(const ThreadData &thread_data,
681 const ThreadData::BirthMap& birth_map,
682 const ThreadData::DeathMap& death_map,
683 const ThreadData::ParentChildSet& parent_child_set);
684
685 // After the accumulation phase, the following accessor is used to process the
686 // data (i.e., sort it, filter it, etc.).
687 Collection* collection();
688
689 // Adds entries for all the remaining living objects (objects that have
690 // tallied a birth, but have not yet tallied a matching death, and hence must
691 // be either running, queued up, or being held in limbo for future posting).
692 // This should be called after all known ThreadData instances have been
693 // processed using Append().
694 void AddListOfLivingObjects();
695
696 // Generates a ListValue representation of the vector of snapshots, and
697 // inserts the results into |dictionary|.
698 void ToValue(base::DictionaryValue* dictionary) const; 711 void ToValue(base::DictionaryValue* dictionary) const;
699 712
700 private: 713 SerializedBirthOnThread parent;
701 typedef std::map<const BirthOnThread*, int> BirthCount; 714 SerializedBirthOnThread child;
715 };
702 716
703 // The array that we collect data into. 717 //
704 Collection collection_; 718 // A serialized representation of the list of ThreadData objects for a process.
705 719
706 // The total number of births recorded at each location for which we have not 720 struct BASE_EXPORT SerializedProcessData {
707 // seen a death count. This map changes as we do Append() calls, and is later 721 public:
708 // used by AddListOfLivingObjects() to gather up unaccounted for births. 722 SerializedProcessData();
709 BirthCount global_birth_count_; 723 ~SerializedProcessData();
710 724
711 // The complete list of parent-child relationships among tasks. 725 void ToValue(base::DictionaryValue* dictionary) const;
712 ThreadData::ParentChildSet parent_child_set_;
713 726
714 DISALLOW_COPY_AND_ASSIGN(DataCollector); 727 std::vector<SerializedSnapshot> snapshots;
728 std::vector<SerializedParentChildPair> descendants;
729 int process_id;
715 }; 730 };
716 731
717 } // namespace tracked_objects 732 } // namespace tracked_objects
718 733
719 #endif // BASE_TRACKED_OBJECTS_H_ 734 #endif // BASE_TRACKED_OBJECTS_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698