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

Unified Diff: components/scheduler/renderer/queueing_time_estimator.cc

Issue 1898233002: Report expected task queueing time via UMA (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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 side-by-side diff with in-line comments
Download patch
Index: components/scheduler/renderer/queueing_time_estimator.cc
diff --git a/components/scheduler/renderer/queueing_time_estimator.cc b/components/scheduler/renderer/queueing_time_estimator.cc
new file mode 100644
index 0000000000000000000000000000000000000000..0483614b3afb7078bee291ea74c95e88ac2ff5af
--- /dev/null
+++ b/components/scheduler/renderer/queueing_time_estimator.cc
@@ -0,0 +1,90 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/scheduler/renderer/queueing_time_estimator.h"
+
+#include "base/time/default_tick_clock.h"
+
+namespace scheduler {
+
+QueueingTimeEstimator::QueueingTimeEstimator(
+ QueueingTimeEstimator::QueueingTimeEstimatorClient* client,
+ base::TickClock* time_source,
+ base::TimeDelta window_duration)
+ : client_(client),
+ time_source_(time_source),
+ outstanding_task_count_(0),
+ window_duration_(window_duration),
+ window_start_time_(time_source->NowTicks()) {}
+
+QueueingTimeEstimator::~QueueingTimeEstimator() {}
+
+void QueueingTimeEstimator::WillProcessTask(
+ const base::PendingTask& pending_task) {
+ // Avoid measuring the duration in nested run loops.
+ if (++outstanding_task_count_ != 1)
+ return;
+
+ task_start_time_ = time_source_->NowTicks();
+}
+
+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.
+ base::TimeTicks task_end,
+ base::TimeTicks window_start,
+ base::TimeTicks window_end) {
+ DCHECK(task_start <= task_end);
+ 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.
+ base::TimeTicks task_in_window_start_time =
+ std::max(task_start, window_start);
+ base::TimeTicks task_in_window_end_time =
+ std::min(task_end, window_end);
Sami 2016/04/20 09:51:27 DCHECK(start <= end)?
tdresser 2016/04/20 15:13:32 Done.
+
+ 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.
+ static_cast<double>((task_in_window_end_time - task_in_window_start_time)
+ .InMicroseconds()) /
+ (window_end - window_start).InMicroseconds();
+
+ 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.
+ ((task_end - task_in_window_start_time) +
+ (task_end - task_in_window_end_time)) /
+ 2;
+
+ return base::TimeDelta::FromMicroseconds(
Sami 2016/04/20 09:51:27 FromMillisecondsD to avoid some truncation?
tdresser 2016/04/20 15:13:32 Done.
+ probability_of_this_task *
+ 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.
+}
+
+void QueueingTimeEstimator::DidProcessTask(
+ const base::PendingTask& pending_task) {
+ if (--outstanding_task_count_ != 0)
+ return;
+
+ bool start_past_window =
+ task_start_time_ > window_start_time_ + window_duration_;
+ bool end_past_window =
+ 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
+
+ while (end_past_window) {
+ if (!start_past_window) {
+ // Include the current task in this window.
+ current_expected_queueing_time_ += ExpectedQueueingTimeFromTask(
+ task_start_time_, time_source_->NowTicks(), window_start_time_,
+ window_start_time_ + window_duration_);
+ }
+ client_->OnQueueingTimeForWindowEstimated(current_expected_queueing_time_);
+ 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
+ current_expected_queueing_time_ = base::TimeDelta();
+
+ start_past_window =
+ task_start_time_ > window_start_time_ + window_duration_;
+ end_past_window =
+ time_source_->NowTicks() > window_start_time_ + window_duration_;
+ }
+
+ current_expected_queueing_time_ += ExpectedQueueingTimeFromTask(
+ task_start_time_, time_source_->NowTicks(), window_start_time_,
+ window_start_time_ + window_duration_);
+}
+
+} // namespace scheduler

Powered by Google App Engine
This is Rietveld 408576698