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); |