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

Unified Diff: third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc

Issue 2273703002: Force events to be non blocking if main thread is unresponsive. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add tests, fix bugs. Created 4 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc
index 25376e87f14eab36a4df8cfeac668a9928540ad9..9430977554e611ef4bdb6568464884859c6415fa 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc
@@ -45,6 +45,9 @@ constexpr base::TimeDelta kThreadLoadTrackerWaitingPeriodBeforeReporting =
// We do not throttle anything while audio is played and shortly after that.
constexpr base::TimeDelta kThrottlingDelayAfterAudioIsPlayed =
base::TimeDelta::FromSeconds(5);
+// Maximum task queueing time before the main thread is considered unresponsive.
+constexpr base::TimeDelta kMainThreadResponsivenessThreshold =
+ base::TimeDelta::FromMilliseconds(200);
void ReportForegroundRendererTaskLoad(base::TimeTicks time, double load) {
int load_percentage = static_cast<int>(load * 100);
@@ -64,8 +67,8 @@ void ReportBackgroundRendererTaskLoad(base::TimeTicks time, double load) {
base::TimeTicks MonotonicTimeInSecondsToTimeTicks(
double monotonicTimeInSeconds) {
- return base::TimeTicks() + base::TimeDelta::FromSecondsD(
- monotonicTimeInSeconds);
+ return base::TimeTicks() +
+ base::TimeDelta::FromSecondsD(monotonicTimeInSeconds);
}
} // namespace
@@ -90,11 +93,15 @@ RendererSchedulerImpl::RendererSchedulerImpl(
base::Bind(&RendererSchedulerImpl::UpdatePolicy,
base::Unretained(this)),
helper_.ControlTaskRunner()),
+ seqlock_queueing_time_estimator_(
+ QueueingTimeEstimator(this, base::TimeDelta::FromSeconds(1))),
main_thread_only_(this,
compositor_task_runner_,
helper_.scheduler_tqm_delegate().get(),
helper_.scheduler_tqm_delegate()->NowTicks()),
+ any_thread_(this),
policy_may_need_update_(&any_thread_lock_),
+ main_thread_responsiveness_threshold_(kMainThreadResponsivenessThreshold),
weak_factory_(this) {
task_queue_throttler_.reset(
new TaskQueueThrottler(this, "renderer.scheduler"));
@@ -156,8 +163,6 @@ RendererSchedulerImpl::MainThreadOnly::MainThreadOnly(
timer_task_cost_estimator(time_source,
kTimerTaskEstimationSampleCount,
kTimerTaskEstimationPercentile),
- queueing_time_estimator(renderer_scheduler_impl,
- base::TimeDelta::FromSeconds(1)),
idle_time_estimator(compositor_task_runner,
time_source,
kShortIdlePeriodDurationSampleCount,
@@ -197,7 +202,8 @@ RendererSchedulerImpl::MainThreadOnly::MainThreadOnly(
RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() {}
-RendererSchedulerImpl::AnyThread::AnyThread()
+RendererSchedulerImpl::AnyThread::AnyThread(
+ RendererSchedulerImpl* renderer_scheduler_impl)
: awaiting_touch_start_response(false),
in_idle_period(false),
begin_main_frame_on_critical_path(false),
@@ -208,7 +214,8 @@ RendererSchedulerImpl::AnyThread::AnyThread()
RendererSchedulerImpl::AnyThread::~AnyThread() {}
RendererSchedulerImpl::CompositorThreadOnly::CompositorThreadOnly()
- : last_input_type(blink::WebInputEvent::Undefined) {}
+ : last_input_type(blink::WebInputEvent::Undefined),
+ main_thread_seems_unresponsive(false) {}
RendererSchedulerImpl::CompositorThreadOnly::~CompositorThreadOnly() {}
@@ -1510,6 +1517,43 @@ void RendererSchedulerImpl::SetRAILModeObserver(RAILModeObserver* observer) {
MainThreadOnly().rail_mode_observer = observer;
}
+bool RendererSchedulerImpl::MainThreadSeemsUnresponsive() {
+ base::TimeTicks now = tick_clock()->NowTicks();
alex clarke (OOO till 29th) 2016/11/14 17:00:17 Is it worth adding a TRACE_EVENT here?
tdresser 2016/12/15 13:17:00 For when we're checking if the main thread is unre
+ base::TimeDelta estimated_queueing_time;
+
+ bool can_read = false;
+ QueueingTimeEstimator::Data queueing_time_estimator_data;
+
+ base::subtle::Atomic32 version;
+ seqlock_queueing_time_estimator_.seqlock.ReadOrFail(&can_read, &version);
+
+ // If we fail to determine if the main thread is busy, assume whether or not
+ // it's busy hasn't change since the last time we asked.
+ if (!can_read)
+ return CompositorThreadOnly().main_thread_seems_unresponsive;
+
+ queueing_time_estimator_data = seqlock_queueing_time_estimator_.data.data();
+
+ // If we fail to determine if the main thread is busy, assume whether or not
+ // it's busy hasn't change since the last time we asked.
+ if (seqlock_queueing_time_estimator_.seqlock.ReadRetry(version))
+ return CompositorThreadOnly().main_thread_seems_unresponsive;
+
+ QueueingTimeEstimator queueing_time_estimator(queueing_time_estimator_data);
+
+ estimated_queueing_time =
+ queueing_time_estimator.EstimateQueueingTimeIncludingCurrentTask(now);
+
+ bool main_thread_seems_unresponsive =
+ estimated_queueing_time > main_thread_responsiveness_threshold_;
+ {
Sami 2016/11/14 21:16:45 nit: any reason for these braces? We're not grabbi
tdresser 2016/12/15 13:17:00 Done.
+ CompositorThreadOnly().main_thread_seems_unresponsive =
+ main_thread_seems_unresponsive;
+ }
+
+ return main_thread_seems_unresponsive;
+}
+
void RendererSchedulerImpl::RegisterTimeDomain(TimeDomain* time_domain) {
helper_.RegisterTimeDomain(time_domain);
}
@@ -1574,22 +1618,33 @@ void RendererSchedulerImpl::OnTriedToExecuteBlockedTask(
"Blink deferred a task in order to make scrolling smoother. "
"Your timer and network tasks should take less than 50ms to run "
"to avoid this. Please see "
- "https://developers.google.com/web/tools/chrome-devtools/profile/evaluate-performance/rail"
+ "https://developers.google.com/web/tools/chrome-devtools/profile/"
+ "evaluate-performance/rail"
" and https://crbug.com/574343#c40 for more information.");
}
}
-void RendererSchedulerImpl::ReportTaskTime(TaskQueue* task_queue,
- double start_time,
- double end_time) {
+void RendererSchedulerImpl::ReportTaskStartTime(double start_time) {
+ base::TimeTicks start_time_ticks =
+ MonotonicTimeInSecondsToTimeTicks(start_time);
+ MainThreadOnly().current_task_start_time = start_time_ticks;
+ seqlock_queueing_time_estimator_.seqlock.WriteBegin();
+ seqlock_queueing_time_estimator_.data.OnTopLevelTaskStarted(start_time_ticks);
+ seqlock_queueing_time_estimator_.seqlock.WriteEnd();
+}
+
+void RendererSchedulerImpl::ReportTaskEndTime(TaskQueue* task_queue,
+ double start_time,
+ double end_time) {
// TODO(scheduler-dev): Remove conversions when Blink starts using
// base::TimeTicks instead of doubles for time.
base::TimeTicks start_time_ticks =
MonotonicTimeInSecondsToTimeTicks(start_time);
base::TimeTicks end_time_ticks = MonotonicTimeInSecondsToTimeTicks(end_time);
- MainThreadOnly().queueing_time_estimator.OnToplevelTaskCompleted(
- start_time_ticks, end_time_ticks);
+ seqlock_queueing_time_estimator_.seqlock.WriteBegin();
+ seqlock_queueing_time_estimator_.data.OnTopLevelTaskCompleted(end_time_ticks);
+ seqlock_queueing_time_estimator_.seqlock.WriteEnd();
task_queue_throttler()->OnTaskRunTimeReported(task_queue, start_time_ticks,
end_time_ticks);
@@ -1601,9 +1656,9 @@ void RendererSchedulerImpl::ReportTaskTime(TaskQueue* task_queue,
MainThreadOnly().background_main_thread_load_tracker.RecordTaskTime(
start_time_ticks, end_time_ticks);
// TODO(altimin): Per-page metrics should also be considered.
- UMA_HISTOGRAM_CUSTOM_COUNTS("RendererScheduler.TaskTime",
- (end_time_ticks - start_time_ticks).InMicroseconds(), 1,
- 1000000, 50);
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "RendererScheduler.TaskTime",
+ (end_time_ticks - start_time_ticks).InMicroseconds(), 1, 1000000, 50);
UMA_HISTOGRAM_ENUMERATION("RendererScheduler.NumberOfTasksPerQueueType",
static_cast<int>(task_queue->GetQueueType()),
static_cast<int>(TaskQueue::QueueType::COUNT));

Powered by Google App Engine
This is Rietveld 408576698