OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "components/scheduler/renderer/queueing_time_estimator.h" | |
6 | |
7 #include "base/time/default_tick_clock.h" | |
8 | |
9 namespace scheduler { | |
10 | |
11 QueueingTimeEstimator::QueueingTimeEstimator( | |
12 QueueingTimeEstimator::QueueingTimeEstimatorClient* client, | |
13 base::TickClock* time_source, | |
14 base::TimeDelta window_duration) | |
15 : client_(client), | |
16 time_source_(time_source), | |
17 outstanding_task_count_(0), | |
18 window_duration_(window_duration), | |
19 window_start_time_(time_source->NowTicks()) {} | |
20 | |
21 QueueingTimeEstimator::~QueueingTimeEstimator() {} | |
22 | |
23 void QueueingTimeEstimator::WillProcessTask( | |
24 const base::PendingTask& pending_task) { | |
25 // Avoid measuring the duration in nested run loops. | |
26 if (++outstanding_task_count_ != 1) | |
27 return; | |
28 | |
29 task_start_time_ = time_source_->NowTicks(); | |
30 } | |
31 | |
32 base::TimeDelta ExpectedQueueingTimeFromTask(base::TimeTicks task_start, | |
Sami
2016/04/20 09:51:27
Could you move this into an unnamed namespace?
tdresser
2016/04/20 15:13:32
Done.
| |
33 base::TimeTicks task_end, | |
34 base::TimeTicks window_start, | |
35 base::TimeTicks window_end) { | |
36 DCHECK(task_start <= task_end); | |
37 DCHECK(window_start < window_end); | |
Sami
2016/04/20 09:51:27
DCHECK(task_start <= window_end);
DCHECK(task_end
tdresser
2016/04/20 15:13:32
Done.
| |
38 base::TimeTicks task_in_window_start_time = | |
39 std::max(task_start, window_start); | |
40 base::TimeTicks task_in_window_end_time = | |
41 std::min(task_end, window_end); | |
Sami
2016/04/20 09:51:27
DCHECK(start <= end)?
tdresser
2016/04/20 15:13:32
Done.
| |
42 | |
43 double probability_of_this_task = | |
Sami
2016/04/20 09:51:27
You could use, e.g., InMillisecondsF() to avoid th
tdresser
2016/04/20 15:13:32
Won't that cause loss of precision? Dividing both
Sami
2016/04/21 10:04:01
Good point, let's keep the code you have.
| |
44 static_cast<double>((task_in_window_end_time - task_in_window_start_time) | |
45 .InMicroseconds()) / | |
46 (window_end - window_start).InMicroseconds(); | |
47 | |
48 base::TimeDelta expected_queueing_duration_within_task = | |
Sami
2016/04/20 09:51:26
I'm not sure I understand this equation. Shouldn't
tdresser
2016/04/20 15:13:32
Here's an example where that doesn't work.
With a
Sami
2016/04/21 10:04:01
Thanks for the explanation, that made it clear.
| |
49 ((task_end - task_in_window_start_time) + | |
50 (task_end - task_in_window_end_time)) / | |
51 2; | |
52 | |
53 return base::TimeDelta::FromMicroseconds( | |
Sami
2016/04/20 09:51:27
FromMillisecondsD to avoid some truncation?
tdresser
2016/04/20 15:13:32
Done.
| |
54 probability_of_this_task * | |
55 expected_queueing_duration_within_task.InMicroseconds()); | |
Sami
2016/04/20 09:51:27
InMillisecondsF if you decide to make the above ch
tdresser
2016/04/20 15:13:32
Done.
| |
56 } | |
57 | |
58 void QueueingTimeEstimator::DidProcessTask( | |
59 const base::PendingTask& pending_task) { | |
60 if (--outstanding_task_count_ != 0) | |
61 return; | |
62 | |
63 bool start_past_window = | |
64 task_start_time_ > window_start_time_ + window_duration_; | |
65 bool end_past_window = | |
66 time_source_->NowTicks() > window_start_time_ + window_duration_; | |
Sami
2016/04/20 09:51:27
We like to minimize the number of calls to Now() s
tdresser
2016/04/20 15:13:32
Fixed. This is better from a readability perspecti
| |
67 | |
68 while (end_past_window) { | |
69 if (!start_past_window) { | |
70 // Include the current task in this window. | |
71 current_expected_queueing_time_ += ExpectedQueueingTimeFromTask( | |
72 task_start_time_, time_source_->NowTicks(), window_start_time_, | |
73 window_start_time_ + window_duration_); | |
74 } | |
75 client_->OnQueueingTimeForWindowEstimated(current_expected_queueing_time_); | |
76 window_start_time_ += window_duration_; | |
Sami
2016/04/20 09:51:27
We only really care about the window we are curren
tdresser
2016/04/20 15:13:32
The intermediate windows definitely matter.
We ne
Sami
2016/04/21 10:04:01
Ah, I didn't realize the client was expected to sa
| |
77 current_expected_queueing_time_ = base::TimeDelta(); | |
78 | |
79 start_past_window = | |
80 task_start_time_ > window_start_time_ + window_duration_; | |
81 end_past_window = | |
82 time_source_->NowTicks() > window_start_time_ + window_duration_; | |
83 } | |
84 | |
85 current_expected_queueing_time_ += ExpectedQueueingTimeFromTask( | |
86 task_start_time_, time_source_->NowTicks(), window_start_time_, | |
87 window_start_time_ + window_duration_); | |
88 } | |
89 | |
90 } // namespace scheduler | |
OLD | NEW |