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

Side by Side Diff: base/tracked_objects.cc

Issue 8502001: Switch to using an intergral type for durations inside profiler (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 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 | Annotate | Revision Log
« no previous file with comments | « base/tracked_objects.h ('k') | base/tracked_objects_unittest.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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 8
9 #include "base/format_macros.h" 9 #include "base/format_macros.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
(...skipping 15 matching lines...) Expand all
26 // that we only record after parsing the command line flag --enable-tracking. 26 // that we only record after parsing the command line flag --enable-tracking.
27 // Note that the flag may force either state, so this really controls only the 27 // Note that the flag may force either state, so this really controls only the
28 // period of time up until that flag is parsed. If there is no flag seen, then 28 // period of time up until that flag is parsed. If there is no flag seen, then
29 // this state may prevail for much or all of the process lifetime. 29 // this state may prevail for much or all of the process lifetime.
30 static const ThreadData::Status kInitialStartupState = ThreadData::ACTIVE; 30 static const ThreadData::Status kInitialStartupState = ThreadData::ACTIVE;
31 } // anonymous namespace. 31 } // anonymous namespace.
32 32
33 //------------------------------------------------------------------------------ 33 //------------------------------------------------------------------------------
34 // DeathData tallies durations when a death takes place. 34 // DeathData tallies durations when a death takes place.
35 35
36 void DeathData::RecordDeath(const Duration& queue_duration, 36 void DeathData::RecordDeath(DurationInt queue_duration,
37 const Duration& run_duration) { 37 DurationInt run_duration) {
38 ++count_; 38 ++count_;
39 queue_time_.AddDuration(queue_duration); 39 queue_time_.AddDuration(queue_duration);
40 run_time_.AddDuration(run_duration); 40 run_time_.AddDuration(run_duration);
41 } 41 }
42 42
43 int DeathData::AverageMsRunDuration() const { 43 DurationInt DeathData::AverageMsRunDuration() const {
44 return run_time_.AverageMsDuration(count_); 44 return run_time_.AverageMsDuration(count_);
45 } 45 }
46 46
47 int DeathData::AverageMsQueueDuration() const { 47 DurationInt DeathData::AverageMsQueueDuration() const {
48 return queue_time_.AverageMsDuration(count_); 48 return queue_time_.AverageMsDuration(count_);
49 } 49 }
50 50
51 void DeathData::AddDeathData(const DeathData& other) { 51 void DeathData::AddDeathData(const DeathData& other) {
52 count_ += other.count_; 52 count_ += other.count_;
53 queue_time_.AddData(other.queue_time_); 53 queue_time_.AddData(other.queue_time_);
54 run_time_.AddData(other.run_time_); 54 run_time_.AddData(other.run_time_);
55 } 55 }
56 56
57 void DeathData::WriteHTML(std::string* output) const { 57 void DeathData::WriteHTML(std::string* output) const {
58 if (!count_) 58 if (!count_)
59 return; 59 return;
60 base::StringAppendF(output, "%s:%d, ", 60 base::StringAppendF(output, "%s:%d, ",
61 (count_ == 1) ? "Life" : "Lives", count_); 61 (count_ == 1) ? "Life" : "Lives", count_);
62 output->append("Run:"); 62 output->append("Run:");
63 run_time_.WriteHTML(count_, output); 63 run_time_.WriteHTML(count_, output);
64 64
65 output->append("Queue:"); 65 output->append("Queue:");
66 queue_time_.WriteHTML(count_, output); 66 queue_time_.WriteHTML(count_, output);
67 } 67 }
68 68
69 base::DictionaryValue* DeathData::ToValue() const { 69 base::DictionaryValue* DeathData::ToValue() const {
70 base::DictionaryValue* dictionary = new base::DictionaryValue; 70 base::DictionaryValue* dictionary = new base::DictionaryValue;
71 dictionary->Set("count", base::Value::CreateIntegerValue(count_)); 71 dictionary->Set("count", base::Value::CreateIntegerValue(count_));
72 dictionary->Set("run_ms", 72 dictionary->Set("run_ms",
73 base::Value::CreateIntegerValue(run_time_.duration().InMilliseconds())); 73 base::Value::CreateIntegerValue(run_time_.duration()));
74 dictionary->Set("queue_ms", 74 dictionary->Set("queue_ms",
75 base::Value::CreateIntegerValue(queue_time_.duration().InMilliseconds())); 75 base::Value::CreateIntegerValue(queue_time_.duration()));
76 dictionary->Set("run_ms_max", 76 dictionary->Set("run_ms_max",
77 base::Value::CreateIntegerValue(run_time_.max().InMilliseconds())); 77 base::Value::CreateIntegerValue(run_time_.max()));
78 dictionary->Set("queue_ms_max", 78 dictionary->Set("queue_ms_max",
79 base::Value::CreateIntegerValue(queue_time_.max().InMilliseconds())); 79 base::Value::CreateIntegerValue(queue_time_.max()));
80 return dictionary; 80 return dictionary;
81 } 81 }
82 82
83 void DeathData::Clear() { 83 void DeathData::Clear() {
84 count_ = 0; 84 count_ = 0;
85 run_time_.Clear(); 85 run_time_.Clear();
86 queue_time_.Clear(); 86 queue_time_.Clear();
87 } 87 }
88 88
89 //------------------------------------------------------------------------------ 89 //------------------------------------------------------------------------------
90 90
91 void DeathData::Data::WriteHTML(int count, std::string* output) const { 91 void DeathData::Data::WriteHTML(int count, std::string* output) const {
92 // Be careful to leave static_casts intact, as the type returned by 92 // Be careful to leave static_casts intact, as the type returned by
93 // InMilliseconds() may not always be an int, even if it can generally fit 93 // InMilliseconds() may not always be an int, even if it can generally fit
94 // into an int. 94 // into an int.
95 base::StringAppendF(output, "%dms", 95 base::StringAppendF(output, "%dms",
96 static_cast<int>(duration_.InMilliseconds())); 96 static_cast<int>(duration_));
97 if (count == 1) { 97 if (count == 1) {
98 output->append(" "); 98 output->append(" ");
99 return; 99 return;
100 } 100 }
101 base::StringAppendF(output, "(%dms/life,max:%dms) ", 101 base::StringAppendF(output, "(%dms/life,max:%dms) ",
102 AverageMsDuration(count), 102 static_cast<int>(AverageMsDuration(count)),
103 static_cast<int>(max_.InMilliseconds())); 103 static_cast<int>(max_));
104 } 104 }
105 105
106 void DeathData::Data::AddData(const Data& other) { 106 void DeathData::Data::AddData(const Data& other) {
107 duration_ += other.duration_; 107 duration_ += other.duration_;
108 if (max_ > other.max_) 108 if (max_ > other.max_)
109 return; 109 return;
110 max_ = other.max_; 110 max_ = other.max_;
111 } 111 }
112 112
113 void DeathData::Data::AddDuration(const Duration& duration) { 113 void DeathData::Data::AddDuration(DurationInt duration) {
114 duration_ += duration; 114 duration_ += duration;
115 if (max_ > duration) 115 if (max_ > duration)
116 return; 116 return;
117 max_ = duration; 117 max_ = duration;
118 } 118 }
119 119
120 int DeathData::Data::AverageMsDuration(int count) const { 120 DurationInt DeathData::Data::AverageMsDuration(int count) const {
121 if (duration_ == Duration() || !count) 121 if (duration_ == 0 || !count)
122 return 0; 122 return 0;
123 return static_cast<int>(duration_.InMilliseconds() + count / 2) / count; 123 return (duration_ + count / 2) / count;
124 } 124 }
125 125
126 void DeathData::Data::Clear() { 126 void DeathData::Data::Clear() {
127 duration_ = Duration(); 127 duration_ = 0;
128 max_ = Duration(); 128 max_ = 0;
129 } 129 }
130 //------------------------------------------------------------------------------ 130 //------------------------------------------------------------------------------
131 BirthOnThread::BirthOnThread(const Location& location, 131 BirthOnThread::BirthOnThread(const Location& location,
132 const ThreadData& current) 132 const ThreadData& current)
133 : location_(location), 133 : location_(location),
134 birth_thread_(&current) {} 134 birth_thread_(&current) {}
135 135
136 //------------------------------------------------------------------------------ 136 //------------------------------------------------------------------------------
137 Births::Births(const Location& location, const ThreadData& current) 137 Births::Births(const Location& location, const ThreadData& current)
138 : BirthOnThread(location, current), 138 : BirthOnThread(location, current),
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 394
395 Births* tracker = new Births(location, *this); 395 Births* tracker = new Births(location, *this);
396 // Lock since the map may get relocated now, and other threads sometimes 396 // Lock since the map may get relocated now, and other threads sometimes
397 // snapshot it (but they lock before copying it). 397 // snapshot it (but they lock before copying it).
398 base::AutoLock lock(lock_); 398 base::AutoLock lock(lock_);
399 birth_map_[location] = tracker; 399 birth_map_[location] = tracker;
400 return tracker; 400 return tracker;
401 } 401 }
402 402
403 void ThreadData::TallyADeath(const Births& birth, 403 void ThreadData::TallyADeath(const Births& birth,
404 const Duration& queue_duration, 404 DurationInt queue_duration,
405 const Duration& run_duration) { 405 DurationInt run_duration) {
406 DeathMap::iterator it = death_map_.find(&birth); 406 DeathMap::iterator it = death_map_.find(&birth);
407 DeathData* death_data; 407 DeathData* death_data;
408 if (it != death_map_.end()) { 408 if (it != death_map_.end()) {
409 death_data = &it->second; 409 death_data = &it->second;
410 } else { 410 } else {
411 base::AutoLock lock(lock_); // Lock since the map may get relocated now. 411 base::AutoLock lock(lock_); // Lock since the map may get relocated now.
412 death_data = &death_map_[&birth]; 412 death_data = &death_map_[&birth];
413 } // Release lock ASAP. 413 } // Release lock ASAP.
414 death_data->RecordDeath(queue_duration, run_duration); 414 death_data->RecordDeath(queue_duration, run_duration);
415 } 415 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 // have for non-delayed tasks, and we consistently call it queueing delay. 453 // have for non-delayed tasks, and we consistently call it queueing delay.
454 TrackedTime effective_post_time = completed_task.delayed_run_time.is_null() 454 TrackedTime effective_post_time = completed_task.delayed_run_time.is_null()
455 ? tracked_objects::TrackedTime(completed_task.time_posted) 455 ? tracked_objects::TrackedTime(completed_task.time_posted)
456 : tracked_objects::TrackedTime(completed_task.delayed_run_time); 456 : tracked_objects::TrackedTime(completed_task.delayed_run_time);
457 457
458 // Watch out for a race where status_ is changing, and hence one or both 458 // Watch out for a race where status_ is changing, and hence one or both
459 // of start_of_run or end_of_run is zero. IN that case, we didn't bother to 459 // of start_of_run or end_of_run is zero. IN that case, we didn't bother to
460 // get a time value since we "weren't tracking" and we were trying to be 460 // get a time value since we "weren't tracking" and we were trying to be
461 // efficient by not calling for a genuine time value. For simplicity, we'll 461 // efficient by not calling for a genuine time value. For simplicity, we'll
462 // use a default zero duration when we can't calculate a true value. 462 // use a default zero duration when we can't calculate a true value.
463 Duration queue_duration; 463 DurationInt queue_duration = 0;
464 Duration run_duration; 464 DurationInt run_duration = 0;
465 if (!start_of_run.is_null()) { 465 if (!start_of_run.is_null()) {
466 queue_duration = start_of_run - effective_post_time; 466 queue_duration = (start_of_run - effective_post_time).InMilliseconds();
467 if (!end_of_run.is_null()) 467 if (!end_of_run.is_null())
468 run_duration = end_of_run - start_of_run; 468 run_duration = (end_of_run - start_of_run).InMilliseconds();
469 } 469 }
470 current_thread_data->TallyADeath(*birth, queue_duration, run_duration); 470 current_thread_data->TallyADeath(*birth, queue_duration, run_duration);
471 } 471 }
472 472
473 // static 473 // static
474 void ThreadData::TallyRunOnWorkerThreadIfTracking( 474 void ThreadData::TallyRunOnWorkerThreadIfTracking(
475 const Births* birth, 475 const Births* birth,
476 const TrackedTime& time_posted, 476 const TrackedTime& time_posted,
477 const TrackedTime& start_of_run, 477 const TrackedTime& start_of_run,
478 const TrackedTime& end_of_run) { 478 const TrackedTime& end_of_run) {
(...skipping 12 matching lines...) Expand all
491 // (since we'll use locks on TallyBirth and TallyDeath). The good news is 491 // (since we'll use locks on TallyBirth and TallyDeath). The good news is
492 // that the locks on TallyDeath will be *after* the worker thread has run, and 492 // that the locks on TallyDeath will be *after* the worker thread has run, and
493 // hence nothing will be waiting for the completion (... besides some other 493 // hence nothing will be waiting for the completion (... besides some other
494 // thread that might like to run). Also, the worker threads tasks are 494 // thread that might like to run). Also, the worker threads tasks are
495 // generally longer, and hence the cost of the lock may perchance be amortized 495 // generally longer, and hence the cost of the lock may perchance be amortized
496 // over the long task's lifetime. 496 // over the long task's lifetime.
497 ThreadData* current_thread_data = Get(); 497 ThreadData* current_thread_data = Get();
498 if (!current_thread_data) 498 if (!current_thread_data)
499 return; 499 return;
500 500
501 Duration queue_duration; 501 DurationInt queue_duration = 0;
502 Duration run_duration; 502 DurationInt run_duration = 0;
503 if (!start_of_run.is_null()) { 503 if (!start_of_run.is_null()) {
504 queue_duration = start_of_run - time_posted; 504 queue_duration = (start_of_run - time_posted).InMilliseconds();
505 if (!end_of_run.is_null()) 505 if (!end_of_run.is_null())
506 run_duration = end_of_run - start_of_run; 506 run_duration = (end_of_run - start_of_run).InMilliseconds();
507 } 507 }
508 current_thread_data->TallyADeath(*birth, queue_duration, run_duration); 508 current_thread_data->TallyADeath(*birth, queue_duration, run_duration);
509 } 509 }
510 510
511 // static 511 // static
512 void ThreadData::TallyRunInAScopedRegionIfTracking( 512 void ThreadData::TallyRunInAScopedRegionIfTracking(
513 const Births* birth, 513 const Births* birth,
514 const TrackedTime& start_of_run, 514 const TrackedTime& start_of_run,
515 const TrackedTime& end_of_run) { 515 const TrackedTime& end_of_run) {
516 if (!kTrackAllTaskObjects) 516 if (!kTrackAllTaskObjects)
517 return; // Not compiled in. 517 return; // Not compiled in.
518 518
519 // Even if we have been DEACTIVATED, we will process any pending births so 519 // Even if we have been DEACTIVATED, we will process any pending births so
520 // that our data structures (which counted the outstanding births) remain 520 // that our data structures (which counted the outstanding births) remain
521 // consistent. 521 // consistent.
522 if (!birth) 522 if (!birth)
523 return; 523 return;
524 524
525 ThreadData* current_thread_data = Get(); 525 ThreadData* current_thread_data = Get();
526 if (!current_thread_data) 526 if (!current_thread_data)
527 return; 527 return;
528 528
529 Duration queue_duration = Duration(); 529 DurationInt queue_duration = 0;
530 Duration run_duration = end_of_run - start_of_run; 530 DurationInt run_duration = (end_of_run - start_of_run).InMilliseconds();
531 current_thread_data->TallyADeath(*birth, queue_duration, run_duration); 531 current_thread_data->TallyADeath(*birth, queue_duration, run_duration);
532 } 532 }
533 533
534 534
535 535
536 // static 536 // static
537 ThreadData* ThreadData::first() { 537 ThreadData* ThreadData::first() {
538 base::AutoLock lock(*list_lock_); 538 base::AutoLock lock(*list_lock_);
539 return all_thread_data_list_head_; 539 return all_thread_data_list_head_;
540 } 540 }
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after
1247 (combined_selectors_ & BIRTH_THREAD) ? "*" : 1247 (combined_selectors_ & BIRTH_THREAD) ? "*" :
1248 sample.birth().birth_thread()->thread_name().c_str(), 1248 sample.birth().birth_thread()->thread_name().c_str(),
1249 (combined_selectors_ & DEATH_THREAD) ? "*" : 1249 (combined_selectors_ & DEATH_THREAD) ? "*" :
1250 sample.DeathThreadName().c_str()); 1250 sample.DeathThreadName().c_str());
1251 sample.birth().location().Write(!(combined_selectors_ & BIRTH_FILE), 1251 sample.birth().location().Write(!(combined_selectors_ & BIRTH_FILE),
1252 !(combined_selectors_ & BIRTH_FUNCTION), 1252 !(combined_selectors_ & BIRTH_FUNCTION),
1253 output); 1253 output);
1254 } 1254 }
1255 1255
1256 } // namespace tracked_objects 1256 } // namespace tracked_objects
OLDNEW
« no previous file with comments | « base/tracked_objects.h ('k') | base/tracked_objects_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698