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

Side by Side Diff: third_party/WebKit/Source/platform/scheduler/base/thread_load_tracker.cc

Issue 2391593002: [scheduler] Change ThreadLoadTracker to use only recent data. (Closed)
Patch Set: Rebased Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "platform/scheduler/base/thread_load_tracker.h" 5 #include "platform/scheduler/base/thread_load_tracker.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 namespace blink { 9 namespace blink {
10 namespace scheduler { 10 namespace scheduler {
11 11
12 namespace {
13
14 const int kLoadReportingIntervalInSeconds = 1;
15 const int kWaitingPeriodBeforeReportingInSeconds = 10;
16
17 } // namespace
18
19 ThreadLoadTracker::ThreadLoadTracker(base::TimeTicks now, 12 ThreadLoadTracker::ThreadLoadTracker(base::TimeTicks now,
20 const Callback& callback) 13 const Callback& callback,
14 base::TimeDelta reporting_interval,
15 base::TimeDelta waiting_period)
21 : time_(now), 16 : time_(now),
22 next_reporting_time_(now),
23 thread_state_(ThreadState::ACTIVE), 17 thread_state_(ThreadState::ACTIVE),
24 last_state_change_time_(now), 18 last_state_change_time_(now),
25 waiting_period_( 19 waiting_period_(waiting_period),
26 base::TimeDelta::FromSeconds(kWaitingPeriodBeforeReportingInSeconds)), 20 reporting_interval_(reporting_interval),
27 reporting_interval_( 21 callback_(callback) {
28 base::TimeDelta::FromSeconds(kLoadReportingIntervalInSeconds)), 22 next_reporting_time_ = now + waiting_period_;
29 callback_(callback) {} 23 }
30 24
31 ThreadLoadTracker::~ThreadLoadTracker() {} 25 ThreadLoadTracker::~ThreadLoadTracker() {}
32 26
33 void ThreadLoadTracker::Pause(base::TimeTicks now) { 27 void ThreadLoadTracker::Pause(base::TimeTicks now) {
34 Advance(now, TaskState::IDLE); 28 Advance(now, TaskState::IDLE);
35 thread_state_ = ThreadState::PAUSED; 29 thread_state_ = ThreadState::PAUSED;
36 last_state_change_time_ = now; 30 last_state_change_time_ = now;
37 } 31 }
38 32
39 void ThreadLoadTracker::Resume(base::TimeTicks now) { 33 void ThreadLoadTracker::Resume(base::TimeTicks now) {
40 Advance(now, TaskState::IDLE); 34 Advance(now, TaskState::IDLE);
41 thread_state_ = ThreadState::ACTIVE; 35 thread_state_ = ThreadState::ACTIVE;
42 last_state_change_time_ = now; 36 last_state_change_time_ = now;
37
38 next_reporting_time_ = now + reporting_interval_;
39 run_time_inside_window_ = base::TimeDelta();
43 } 40 }
44 41
45 void ThreadLoadTracker::RecordTaskTime(base::TimeTicks start_time, 42 void ThreadLoadTracker::RecordTaskTime(base::TimeTicks start_time,
46 base::TimeTicks end_time) { 43 base::TimeTicks end_time) {
47 start_time = std::max(last_state_change_time_, start_time); 44 start_time = std::max(last_state_change_time_, start_time);
48 end_time = std::max(last_state_change_time_, end_time); 45 end_time = std::max(last_state_change_time_, end_time);
49 46
50 Advance(start_time, TaskState::IDLE); 47 Advance(start_time, TaskState::IDLE);
51 Advance(end_time, TaskState::TASK_RUNNING); 48 Advance(end_time, TaskState::TASK_RUNNING);
52 } 49 }
53 50
54 void ThreadLoadTracker::RecordIdle(base::TimeTicks now) { 51 void ThreadLoadTracker::RecordIdle(base::TimeTicks now) {
55 Advance(now, TaskState::IDLE); 52 Advance(now, TaskState::IDLE);
56 } 53 }
57 54
55 namespace {
56
57 // Calculates length of intersection of two time intervals.
58 base::TimeDelta Intersection(base::TimeTicks left1,
59 base::TimeTicks right1,
60 base::TimeTicks left2,
61 base::TimeTicks right2) {
62 DCHECK_LT(left1, right1);
63 DCHECK_LT(left2, right2);
64 base::TimeTicks left = std::max(left1, left2);
65 base::TimeTicks right = std::min(right1, right2);
66
67 if (left <= right)
68 return right - left;
69
70 return base::TimeDelta();
71 }
72
73 } // namespace
74
58 void ThreadLoadTracker::Advance(base::TimeTicks now, TaskState task_state) { 75 void ThreadLoadTracker::Advance(base::TimeTicks now, TaskState task_state) {
59 // This function advances |time_| to now and calls |callback_| 76 // This function advances |time_| to now and calls |callback_|
60 // when appropriate. 77 // when appropriate.
61 if (time_ > now) { 78 DCHECK_LE(time_, now);
62 return;
63 }
64 79
65 if (thread_state_ == ThreadState::PAUSED) { 80 if (thread_state_ == ThreadState::PAUSED) {
66 // If the load tracker is paused, bail out early. 81 // If the load tracker is paused, bail out early.
67 time_ = now; 82 time_ = now;
68 next_reporting_time_ = now + reporting_interval_;
69 return; 83 return;
70 } 84 }
71 85
72 while (time_ < now) { 86 while (time_ < now) {
73 // Forward time_ to the earliest of following: 87 // Advance time_ to the earliest of following:
74 // a) time to call |callback_| 88 // a) time to call |callback_|
75 // b) requested time to forward (|now|). 89 // b) requested time to forward (|now|).
76 base::TimeTicks next_current_time = std::min(next_reporting_time_, now); 90 base::TimeTicks next_current_time = std::min(next_reporting_time_, now);
77 91
78 base::TimeDelta delta = next_current_time - time_; 92 base::TimeDelta delta = next_current_time - time_;
79 93
80 // Forward time and recalculate |total_time_| and |total_runtime_|. 94 // Keep a running total of the time spent running tasks within the window
81 if (thread_state_ == ThreadState::ACTIVE) { 95 // and the total time.
82 total_time_ += delta; 96 total_active_time_ += delta;
83 if (task_state == TaskState::TASK_RUNNING) { 97 if (task_state == TaskState::TASK_RUNNING) {
84 total_runtime_ += delta; 98 run_time_inside_window_ +=
85 } 99 Intersection(next_reporting_time_ - reporting_interval_,
100 next_reporting_time_, time_, time_ + delta);
86 } 101 }
102
87 time_ = next_current_time; 103 time_ = next_current_time;
88 104
89 if (time_ == next_reporting_time_) { 105 if (time_ == next_reporting_time_) {
90 // Call |callback_| if need and update next callback time. 106 // Call |callback_| if need and update next callback time.
91 if (thread_state_ == ThreadState::ACTIVE && 107 if (thread_state_ == ThreadState::ACTIVE &&
92 total_time_ >= waiting_period_) { 108 total_active_time_ >= waiting_period_) {
93 callback_.Run(time_, Load()); 109 callback_.Run(time_, Load());
110 DCHECK_EQ(thread_state_, ThreadState::ACTIVE);
94 } 111 }
95 next_reporting_time_ += reporting_interval_; 112 next_reporting_time_ += reporting_interval_;
113 run_time_inside_window_ = base::TimeDelta();
96 } 114 }
97 } 115 }
98 } 116 }
99 117
100 double ThreadLoadTracker::Load() { 118 double ThreadLoadTracker::Load() {
101 if (total_time_.is_zero()) { 119 return run_time_inside_window_.InSecondsF() /
102 return 0; 120 reporting_interval_.InSecondsF();
103 }
104 return total_runtime_.InSecondsF() / total_time_.InSecondsF();
105 } 121 }
106 122
107 } // namespace scheduler 123 } // namespace scheduler
108 } // namespace blink 124 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698