OLD | NEW |
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 #include "base/tracked_objects.h" | 5 #include "base/tracked_objects.h" |
6 | 6 |
7 #include <math.h> | 7 #include <math.h> |
8 #include <stdlib.h> | 8 #include <stdlib.h> |
9 | 9 |
10 #include "base/format_macros.h" | 10 #include "base/format_macros.h" |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 } | 59 } |
60 | 60 |
61 // TODO(jar): I need to see if this macro to optimize branching is worth using. | 61 // TODO(jar): I need to see if this macro to optimize branching is worth using. |
62 // | 62 // |
63 // This macro has no branching, so it is surely fast, and is equivalent to: | 63 // This macro has no branching, so it is surely fast, and is equivalent to: |
64 // if (assign_it) | 64 // if (assign_it) |
65 // target = source; | 65 // target = source; |
66 // We use a macro rather than a template to force this to inline. | 66 // We use a macro rather than a template to force this to inline. |
67 // Related code for calculating max is discussed on the web. | 67 // Related code for calculating max is discussed on the web. |
68 #define CONDITIONAL_ASSIGN(assign_it, target, source) \ | 68 #define CONDITIONAL_ASSIGN(assign_it, target, source) \ |
69 ((target) ^= ((target) ^ (source)) & -static_cast<DurationInt>(assign_it)) | 69 ((target) ^= ((target) ^ (source)) & -static_cast<int32>(assign_it)) |
70 | 70 |
71 void DeathData::RecordDeath(const DurationInt queue_duration, | 71 void DeathData::RecordDeath(const int32 queue_duration, |
72 const DurationInt run_duration, | 72 const int32 run_duration, |
73 int32 random_number) { | 73 int32 random_number) { |
74 ++count_; | 74 ++count_; |
75 queue_duration_sum_ += queue_duration; | 75 queue_duration_sum_ += queue_duration; |
76 run_duration_sum_ += run_duration; | 76 run_duration_sum_ += run_duration; |
77 | 77 |
78 if (queue_duration_max_ < queue_duration) | 78 if (queue_duration_max_ < queue_duration) |
79 queue_duration_max_ = queue_duration; | 79 queue_duration_max_ = queue_duration; |
80 if (run_duration_max_ < run_duration) | 80 if (run_duration_max_ < run_duration) |
81 run_duration_max_ = run_duration; | 81 run_duration_max_ = run_duration; |
82 | 82 |
83 // Take a uniformly distributed sample over all durations ever supplied. | 83 // Take a uniformly distributed sample over all durations ever supplied. |
84 // The probability that we (instead) use this new sample is 1/count_. This | 84 // The probability that we (instead) use this new sample is 1/count_. This |
85 // results in a completely uniform selection of the sample. | 85 // results in a completely uniform selection of the sample. |
86 // We ignore the fact that we correlated our selection of a sample of run | 86 // We ignore the fact that we correlated our selection of a sample of run |
87 // and queue times. | 87 // and queue times. |
88 if (0 == (random_number % count_)) { | 88 if (0 == (random_number % count_)) { |
89 queue_duration_sample_ = queue_duration; | 89 queue_duration_sample_ = queue_duration; |
90 run_duration_sample_ = run_duration; | 90 run_duration_sample_ = run_duration; |
91 } | 91 } |
92 } | 92 } |
93 | 93 |
94 int DeathData::count() const { return count_; } | 94 int DeathData::count() const { return count_; } |
95 | 95 |
96 DurationInt DeathData::run_duration_sum() const { return run_duration_sum_; } | 96 int32 DeathData::run_duration_sum() const { return run_duration_sum_; } |
97 | 97 |
98 DurationInt DeathData::run_duration_max() const { return run_duration_max_; } | 98 int32 DeathData::run_duration_max() const { return run_duration_max_; } |
99 | 99 |
100 DurationInt DeathData::run_duration_sample() const { | 100 int32 DeathData::run_duration_sample() const { |
101 return run_duration_sample_; | 101 return run_duration_sample_; |
102 } | 102 } |
103 | 103 |
104 DurationInt DeathData::queue_duration_sum() const { | 104 int32 DeathData::queue_duration_sum() const { |
105 return queue_duration_sum_; | 105 return queue_duration_sum_; |
106 } | 106 } |
107 | 107 |
108 DurationInt DeathData::queue_duration_max() const { | 108 int32 DeathData::queue_duration_max() const { |
109 return queue_duration_max_; | 109 return queue_duration_max_; |
110 } | 110 } |
111 | 111 |
112 DurationInt DeathData::queue_duration_sample() const { | 112 int32 DeathData::queue_duration_sample() const { |
113 return queue_duration_sample_; | 113 return queue_duration_sample_; |
114 } | 114 } |
115 | 115 |
116 | 116 |
117 base::DictionaryValue* DeathData::ToValue() const { | 117 base::DictionaryValue* DeathData::ToValue() const { |
118 base::DictionaryValue* dictionary = new base::DictionaryValue; | 118 base::DictionaryValue* dictionary = new base::DictionaryValue; |
119 dictionary->Set("count", base::Value::CreateIntegerValue(count_)); | 119 dictionary->Set("count", base::Value::CreateIntegerValue(count_)); |
120 dictionary->Set("run_ms", | 120 dictionary->Set("run_ms", |
121 base::Value::CreateIntegerValue(run_duration_sum())); | 121 base::Value::CreateIntegerValue(run_duration_sum())); |
122 dictionary->Set("run_ms_max", | 122 dictionary->Set("run_ms_max", |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 // snapshot it (but they lock before copying it). | 367 // snapshot it (but they lock before copying it). |
368 base::AutoLock lock(map_lock_); | 368 base::AutoLock lock(map_lock_); |
369 parent_child_set_.insert(pair); | 369 parent_child_set_.insert(pair); |
370 } | 370 } |
371 } | 371 } |
372 | 372 |
373 return child; | 373 return child; |
374 } | 374 } |
375 | 375 |
376 void ThreadData::TallyADeath(const Births& birth, | 376 void ThreadData::TallyADeath(const Births& birth, |
377 DurationInt queue_duration, | 377 int32 queue_duration, |
378 DurationInt run_duration) { | 378 int32 run_duration) { |
379 // Stir in some randomness, plus add constant in case durations are zero. | 379 // Stir in some randomness, plus add constant in case durations are zero. |
380 const DurationInt kSomePrimeNumber = 2147483647; | 380 const int32 kSomePrimeNumber = 2147483647; |
381 random_number_ += queue_duration + run_duration + kSomePrimeNumber; | 381 random_number_ += queue_duration + run_duration + kSomePrimeNumber; |
382 // An address is going to have some randomness to it as well ;-). | 382 // An address is going to have some randomness to it as well ;-). |
383 random_number_ ^= static_cast<int32>(&birth - reinterpret_cast<Births*>(0)); | 383 random_number_ ^= static_cast<int32>(&birth - reinterpret_cast<Births*>(0)); |
384 | 384 |
385 // We don't have queue durations without OS timer. OS timer is automatically | 385 // We don't have queue durations without OS timer. OS timer is automatically |
386 // used for task-post-timing, so the use of an alternate timer implies all | 386 // used for task-post-timing, so the use of an alternate timer implies all |
387 // queue times are invalid. | 387 // queue times are invalid. |
388 if (kAllowAlternateTimeSourceHandling && now_function_) | 388 if (kAllowAlternateTimeSourceHandling && now_function_) |
389 queue_duration = 0; | 389 queue_duration = 0; |
390 | 390 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 // have for non-delayed tasks, and we consistently call it queueing delay. | 445 // have for non-delayed tasks, and we consistently call it queueing delay. |
446 TrackedTime effective_post_time = completed_task.delayed_run_time.is_null() | 446 TrackedTime effective_post_time = completed_task.delayed_run_time.is_null() |
447 ? tracked_objects::TrackedTime(completed_task.time_posted) | 447 ? tracked_objects::TrackedTime(completed_task.time_posted) |
448 : tracked_objects::TrackedTime(completed_task.delayed_run_time); | 448 : tracked_objects::TrackedTime(completed_task.delayed_run_time); |
449 | 449 |
450 // Watch out for a race where status_ is changing, and hence one or both | 450 // Watch out for a race where status_ is changing, and hence one or both |
451 // of start_of_run or end_of_run is zero. In that case, we didn't bother to | 451 // of start_of_run or end_of_run is zero. In that case, we didn't bother to |
452 // get a time value since we "weren't tracking" and we were trying to be | 452 // get a time value since we "weren't tracking" and we were trying to be |
453 // efficient by not calling for a genuine time value. For simplicity, we'll | 453 // efficient by not calling for a genuine time value. For simplicity, we'll |
454 // use a default zero duration when we can't calculate a true value. | 454 // use a default zero duration when we can't calculate a true value. |
455 DurationInt queue_duration = 0; | 455 int32 queue_duration = 0; |
456 DurationInt run_duration = 0; | 456 int32 run_duration = 0; |
457 if (!start_of_run.is_null()) { | 457 if (!start_of_run.is_null()) { |
458 queue_duration = (start_of_run - effective_post_time).InMilliseconds(); | 458 queue_duration = (start_of_run - effective_post_time).InMilliseconds(); |
459 if (!end_of_run.is_null()) | 459 if (!end_of_run.is_null()) |
460 run_duration = (end_of_run - start_of_run).InMilliseconds(); | 460 run_duration = (end_of_run - start_of_run).InMilliseconds(); |
461 } | 461 } |
462 current_thread_data->TallyADeath(*birth, queue_duration, run_duration); | 462 current_thread_data->TallyADeath(*birth, queue_duration, run_duration); |
463 } | 463 } |
464 | 464 |
465 // static | 465 // static |
466 void ThreadData::TallyRunOnWorkerThreadIfTracking( | 466 void ThreadData::TallyRunOnWorkerThreadIfTracking( |
(...skipping 16 matching lines...) Expand all Loading... |
483 // (since we'll use locks on TallyBirth and TallyDeath). The good news is | 483 // (since we'll use locks on TallyBirth and TallyDeath). The good news is |
484 // that the locks on TallyDeath will be *after* the worker thread has run, and | 484 // that the locks on TallyDeath will be *after* the worker thread has run, and |
485 // hence nothing will be waiting for the completion (... besides some other | 485 // hence nothing will be waiting for the completion (... besides some other |
486 // thread that might like to run). Also, the worker threads tasks are | 486 // thread that might like to run). Also, the worker threads tasks are |
487 // generally longer, and hence the cost of the lock may perchance be amortized | 487 // generally longer, and hence the cost of the lock may perchance be amortized |
488 // over the long task's lifetime. | 488 // over the long task's lifetime. |
489 ThreadData* current_thread_data = Get(); | 489 ThreadData* current_thread_data = Get(); |
490 if (!current_thread_data) | 490 if (!current_thread_data) |
491 return; | 491 return; |
492 | 492 |
493 DurationInt queue_duration = 0; | 493 int32 queue_duration = 0; |
494 DurationInt run_duration = 0; | 494 int32 run_duration = 0; |
495 if (!start_of_run.is_null()) { | 495 if (!start_of_run.is_null()) { |
496 queue_duration = (start_of_run - time_posted).InMilliseconds(); | 496 queue_duration = (start_of_run - time_posted).InMilliseconds(); |
497 if (!end_of_run.is_null()) | 497 if (!end_of_run.is_null()) |
498 run_duration = (end_of_run - start_of_run).InMilliseconds(); | 498 run_duration = (end_of_run - start_of_run).InMilliseconds(); |
499 } | 499 } |
500 current_thread_data->TallyADeath(*birth, queue_duration, run_duration); | 500 current_thread_data->TallyADeath(*birth, queue_duration, run_duration); |
501 } | 501 } |
502 | 502 |
503 // static | 503 // static |
504 void ThreadData::TallyRunInAScopedRegionIfTracking( | 504 void ThreadData::TallyRunInAScopedRegionIfTracking( |
505 const Births* birth, | 505 const Births* birth, |
506 const TrackedTime& start_of_run, | 506 const TrackedTime& start_of_run, |
507 const TrackedTime& end_of_run) { | 507 const TrackedTime& end_of_run) { |
508 if (!kTrackAllTaskObjects) | 508 if (!kTrackAllTaskObjects) |
509 return; // Not compiled in. | 509 return; // Not compiled in. |
510 | 510 |
511 // Even if we have been DEACTIVATED, we will process any pending births so | 511 // Even if we have been DEACTIVATED, we will process any pending births so |
512 // that our data structures (which counted the outstanding births) remain | 512 // that our data structures (which counted the outstanding births) remain |
513 // consistent. | 513 // consistent. |
514 if (!birth) | 514 if (!birth) |
515 return; | 515 return; |
516 | 516 |
517 ThreadData* current_thread_data = Get(); | 517 ThreadData* current_thread_data = Get(); |
518 if (!current_thread_data) | 518 if (!current_thread_data) |
519 return; | 519 return; |
520 | 520 |
521 DurationInt queue_duration = 0; | 521 int32 queue_duration = 0; |
522 DurationInt run_duration = 0; | 522 int32 run_duration = 0; |
523 if (!start_of_run.is_null() && !end_of_run.is_null()) | 523 if (!start_of_run.is_null() && !end_of_run.is_null()) |
524 run_duration = (end_of_run - start_of_run).InMilliseconds(); | 524 run_duration = (end_of_run - start_of_run).InMilliseconds(); |
525 current_thread_data->TallyADeath(*birth, queue_duration, run_duration); | 525 current_thread_data->TallyADeath(*birth, queue_duration, run_duration); |
526 } | 526 } |
527 | 527 |
528 const std::string ThreadData::thread_name() const { return thread_name_; } | 528 const std::string ThreadData::thread_name() const { return thread_name_; } |
529 | 529 |
530 // This may be called from another thread. | 530 // This may be called from another thread. |
531 void ThreadData::SnapshotMaps(bool reset_max, | 531 void ThreadData::SnapshotMaps(bool reset_max, |
532 BirthMap* birth_map, | 532 BirthMap* birth_map, |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
882 ++it) { | 882 ++it) { |
883 base::DictionaryValue* parent_child = new base::DictionaryValue; | 883 base::DictionaryValue* parent_child = new base::DictionaryValue; |
884 it->first->ToValue("parent", parent_child); | 884 it->first->ToValue("parent", parent_child); |
885 it->second->ToValue("child", parent_child); | 885 it->second->ToValue("child", parent_child); |
886 descendants->Append(parent_child); | 886 descendants->Append(parent_child); |
887 } | 887 } |
888 dictionary->Set("descendants", descendants); | 888 dictionary->Set("descendants", descendants); |
889 } | 889 } |
890 | 890 |
891 } // namespace tracked_objects | 891 } // namespace tracked_objects |
OLD | NEW |