Chromium Code Reviews| 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); |