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

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: Fix build. 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 339bf45dcff2daeeca6f62def37bf3a84587eb69..dfb03bd5e4713184ff2fdd5ea628105ca76ef4bb 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
@@ -42,6 +42,10 @@ constexpr base::TimeDelta kThreadLoadTrackerReportingInterval =
constexpr base::TimeDelta kThreadLoadTrackerWaitingPeriodBeforeReporting =
base::TimeDelta::FromMinutes(2);
+// Maximum task queueing time before the main thread is considered unresponsive.
+const base::TimeDelta kMainThreadUnresponsiveQueueingTime =
Sami 2016/11/02 19:01:42 constexpr to avoid a global static initializer.
tdresser 2016/11/03 13:56:10 Done.
+ base::TimeDelta::FromMilliseconds(200);
+
void ReportForegroundRendererTaskLoad(base::TimeTicks time, double load) {
int load_percentage = static_cast<int>(load * 100);
UMA_HISTOGRAM_PERCENTAGE("RendererScheduler.ForegroundRendererMainThreadLoad",
@@ -86,10 +90,13 @@ 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_),
weak_factory_(this) {
task_queue_throttler_.reset(
@@ -152,8 +159,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,
@@ -192,7 +197,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),
@@ -1437,6 +1443,36 @@ void RendererSchedulerImpl::SetRAILModeObserver(RAILModeObserver* observer) {
MainThreadOnly().rail_mode_observer = observer;
}
+bool RendererSchedulerImpl::
+ ShouldForceEventsNonBlockingForUnresponsiveMainThread() const {
+ base::TimeTicks now = base::TimeTicks::Now();
+ base::TimeDelta estimated_queueing_time;
+
+ std::unique_ptr<QueueingTimeEstimator> queueing_time_estimator;
+ {
+ bool can_read = false;
+ base::subtle::Atomic32 version;
+ seqlock_queueing_time_estimator_.seqlock.ReadOrFail(&can_read, &version);
+
+ if (can_read) {
+ // TODO - is this copy okay? Use memcpy?
Sami 2016/11/02 19:01:42 I'd need to think about this a bit more, but I thi
tdresser 2016/11/03 13:56:10 Done, though it's a bit ugly. This is probably a b
alex clarke (OOO till 29th) 2016/11/03 15:20:53 I'm not sure what we gain by /not/ copying the bas
+ queueing_time_estimator.reset(
+ new QueueingTimeEstimator(seqlock_queueing_time_estimator_.data));
+ }
+
+ // If we didn't successfully read the first time, assume we aren't busy.
+ if (seqlock_queueing_time_estimator_.seqlock.ReadRetry(version))
+ queueing_time_estimator.reset();
+ }
+
+ if (queueing_time_estimator) {
+ estimated_queueing_time =
+ queueing_time_estimator->EstimateQueueingTimeIncludingCurrentTask(now);
+ }
+
+ return estimated_queueing_time > kMainThreadUnresponsiveQueueingTime;
+}
+
void RendererSchedulerImpl::RegisterTimeDomain(TimeDomain* time_domain) {
helper_.RegisterTimeDomain(time_domain);
}
@@ -1506,17 +1542,28 @@ void RendererSchedulerImpl::OnTriedToExecuteBlockedTask(
}
}
-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);

Powered by Google App Engine
This is Rietveld 408576698