Commit 91541c6f authored by Keishi Hattori's avatar Keishi Hattori Committed by Commit Bot

Implement SetPreemptedForCooperativeScheduling

Implements SetPreemptedForCooperativeScheduling which stops all task queues associated with the FrameSchedulerImpl including the unpausable ones.

Bug: 804661
Change-Id: Icd7288d85c6411c3e379908d14ed9c6eb7203ed8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1742264
Commit-Queue: Keishi Hattori <keishi@chromium.org>
Reviewed-by: default avatarAlexander Timin <altimin@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#697516}
parent c32aeeeb
...@@ -31,7 +31,7 @@ class DummyFrameScheduler : public FrameScheduler { ...@@ -31,7 +31,7 @@ class DummyFrameScheduler : public FrameScheduler {
PageScheduler* GetPageScheduler() const override { return page_scheduler_; } PageScheduler* GetPageScheduler() const override { return page_scheduler_; }
void SetPausedForCooperativeScheduling(Paused) override {} void SetPreemptedForCooperativeScheduling(Preempted) override {}
void SetFrameVisible(bool) override {} void SetFrameVisible(bool) override {}
bool IsFrameVisible() const override { return true; } bool IsFrameVisible() const override { return true; }
bool IsPageVisible() const override { return true; } bool IsPageVisible() const override { return true; }
......
...@@ -51,8 +51,8 @@ void EventLoop::Disable() { ...@@ -51,8 +51,8 @@ void EventLoop::Disable() {
loop_enabled_ = false; loop_enabled_ = false;
for (auto* scheduler : schedulers_) { for (auto* scheduler : schedulers_) {
scheduler->SetPausedForCooperativeScheduling( scheduler->SetPreemptedForCooperativeScheduling(
FrameOrWorkerScheduler::Paused(true)); FrameOrWorkerScheduler::Preempted(true));
} }
// TODO(keishi): Disable microtaskqueue too. // TODO(keishi): Disable microtaskqueue too.
} }
...@@ -61,8 +61,8 @@ void EventLoop::Enable() { ...@@ -61,8 +61,8 @@ void EventLoop::Enable() {
loop_enabled_ = true; loop_enabled_ = true;
for (auto* scheduler : schedulers_) { for (auto* scheduler : schedulers_) {
scheduler->SetPausedForCooperativeScheduling( scheduler->SetPreemptedForCooperativeScheduling(
FrameOrWorkerScheduler::Paused(false)); FrameOrWorkerScheduler::Preempted(false));
} }
// TODO(keishi): Enable microtaskqueue too. // TODO(keishi): Enable microtaskqueue too.
} }
......
...@@ -185,6 +185,12 @@ FrameSchedulerImpl::FrameSchedulerImpl( ...@@ -185,6 +185,12 @@ FrameSchedulerImpl::FrameSchedulerImpl(
this, this,
&tracing_controller_, &tracing_controller_,
YesNoStateToString), YesNoStateToString),
preempted_for_cooperative_scheduling_(
false,
"FrameScheduler.PreemptedForCooperativeScheduling",
this,
&tracing_controller_,
YesNoStateToString),
aggressive_throttling_opt_out_count(0), aggressive_throttling_opt_out_count(0),
opted_out_from_aggressive_throttling_( opted_out_from_aggressive_throttling_(
false, false,
...@@ -829,6 +835,7 @@ void FrameSchedulerImpl::UpdateQueuePolicy( ...@@ -829,6 +835,7 @@ void FrameSchedulerImpl::UpdateQueuePolicy(
DCHECK(parent_page_scheduler_); DCHECK(parent_page_scheduler_);
bool queue_disabled = false; bool queue_disabled = false;
queue_disabled |= frame_paused_ && queue->CanBePaused(); queue_disabled |= frame_paused_ && queue->CanBePaused();
queue_disabled |= preempted_for_cooperative_scheduling_;
// Per-frame freezable task queues will be frozen after 5 mins in background // Per-frame freezable task queues will be frozen after 5 mins in background
// on Android, and if the browser freezes the page in the background. They // on Android, and if the browser freezes the page in the background. They
// will be resumed when the page is visible. // will be resumed when the page is visible.
...@@ -1197,8 +1204,11 @@ FrameSchedulerImpl::DoesNotUseVirtualTimeTaskQueueTraits() { ...@@ -1197,8 +1204,11 @@ FrameSchedulerImpl::DoesNotUseVirtualTimeTaskQueueTraits() {
return QueueTraits().SetCanRunWhenVirtualTimePaused(false); return QueueTraits().SetCanRunWhenVirtualTimePaused(false);
} }
void FrameSchedulerImpl::SetPausedForCooperativeScheduling(Paused paused) { void FrameSchedulerImpl::SetPreemptedForCooperativeScheduling(
// TODO(keishi): Stop all task queues Preempted preempted) {
DCHECK_NE(preempted.value(), preempted_for_cooperative_scheduling_);
preempted_for_cooperative_scheduling_ = preempted.value();
UpdatePolicy();
} }
MainThreadTaskQueue::QueueTraits MainThreadTaskQueue::QueueTraits
......
...@@ -81,7 +81,7 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler, ...@@ -81,7 +81,7 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
~FrameSchedulerImpl() override; ~FrameSchedulerImpl() override;
// FrameOrWorkerScheduler implementation: // FrameOrWorkerScheduler implementation:
void SetPausedForCooperativeScheduling(Paused) override; void SetPreemptedForCooperativeScheduling(Preempted) override;
// FrameScheduler implementation: // FrameScheduler implementation:
void SetFrameVisible(bool frame_visible) override; void SetFrameVisible(bool frame_visible) override;
...@@ -323,6 +323,8 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler, ...@@ -323,6 +323,8 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
TraceableState<bool, TracingCategoryName::kInfo> subresource_loading_paused_; TraceableState<bool, TracingCategoryName::kInfo> subresource_loading_paused_;
StateTracer<TracingCategoryName::kInfo> url_tracer_; StateTracer<TracingCategoryName::kInfo> url_tracer_;
TraceableState<bool, TracingCategoryName::kInfo> task_queues_throttled_; TraceableState<bool, TracingCategoryName::kInfo> task_queues_throttled_;
TraceableState<bool, TracingCategoryName::kInfo>
preempted_for_cooperative_scheduling_;
// TODO(kraynov): https://crbug.com/827113 // TODO(kraynov): https://crbug.com/827113
// Trace the count of aggressive throttling opt outs. // Trace the count of aggressive throttling opt outs.
int aggressive_throttling_opt_out_count; int aggressive_throttling_opt_out_count;
......
...@@ -466,6 +466,30 @@ TEST_F(FrameSchedulerImplTest, PauseAndResume) { ...@@ -466,6 +466,30 @@ TEST_F(FrameSchedulerImplTest, PauseAndResume) {
EXPECT_EQ(5, counter); EXPECT_EQ(5, counter);
} }
TEST_F(FrameSchedulerImplTest, PauseAndResumeForCooperativeScheduling) {
EXPECT_TRUE(LoadingTaskQueue()->IsQueueEnabled());
EXPECT_TRUE(ThrottleableTaskQueue()->IsQueueEnabled());
EXPECT_TRUE(DeferrableTaskQueue()->IsQueueEnabled());
EXPECT_TRUE(PausableTaskQueue()->IsQueueEnabled());
EXPECT_TRUE(UnpausableTaskQueue()->IsQueueEnabled());
frame_scheduler_->SetPreemptedForCooperativeScheduling(
FrameOrWorkerScheduler::Preempted(true));
EXPECT_FALSE(LoadingTaskQueue()->IsQueueEnabled());
EXPECT_FALSE(ThrottleableTaskQueue()->IsQueueEnabled());
EXPECT_FALSE(DeferrableTaskQueue()->IsQueueEnabled());
EXPECT_FALSE(PausableTaskQueue()->IsQueueEnabled());
EXPECT_FALSE(UnpausableTaskQueue()->IsQueueEnabled());
frame_scheduler_->SetPreemptedForCooperativeScheduling(
FrameOrWorkerScheduler::Preempted(false));
EXPECT_TRUE(LoadingTaskQueue()->IsQueueEnabled());
EXPECT_TRUE(ThrottleableTaskQueue()->IsQueueEnabled());
EXPECT_TRUE(DeferrableTaskQueue()->IsQueueEnabled());
EXPECT_TRUE(PausableTaskQueue()->IsQueueEnabled());
EXPECT_TRUE(UnpausableTaskQueue()->IsQueueEnabled());
}
TEST_F(FrameSchedulerImplTest, FreezeForegroundOnlyTasks) { TEST_F(FrameSchedulerImplTest, FreezeForegroundOnlyTasks) {
int counter = 0; int counter = 0;
ForegroundOnlyTaskQueue()->task_runner()->PostTask( ForegroundOnlyTaskQueue()->task_runner()->PostTask(
......
...@@ -129,10 +129,8 @@ void FrameTaskQueueController::TaskQueueCreated( ...@@ -129,10 +129,8 @@ void FrameTaskQueueController::TaskQueueCreated(
const scoped_refptr<MainThreadTaskQueue>& task_queue) { const scoped_refptr<MainThreadTaskQueue>& task_queue) {
DCHECK(task_queue); DCHECK(task_queue);
std::unique_ptr<QueueEnabledVoter> voter; std::unique_ptr<QueueEnabledVoter> voter =
// Only create a voter for queues that can be disabled. task_queue->CreateQueueEnabledVoter();
if (task_queue->CanBePaused() || task_queue->CanBeFrozen())
voter = task_queue->CreateQueueEnabledVoter();
delegate_->OnTaskQueueCreated(task_queue.get(), voter.get()); delegate_->OnTaskQueueCreated(task_queue.get(), voter.get());
......
...@@ -197,16 +197,7 @@ TEST_F(FrameTaskQueueControllerTest, CreateAllTaskQueues) { ...@@ -197,16 +197,7 @@ TEST_F(FrameTaskQueueControllerTest, CreateAllTaskQueues) {
EXPECT_FALSE(it == all_task_queues.end()); EXPECT_FALSE(it == all_task_queues.end());
EXPECT_EQ(it->value, QueueCheckResult::kDidNotSeeQueue); EXPECT_EQ(it->value, QueueCheckResult::kDidNotSeeQueue);
all_task_queues.Set(task_queue_ptr, QueueCheckResult::kDidSeeQueue); all_task_queues.Set(task_queue_ptr, QueueCheckResult::kDidSeeQueue);
if (task_queue_ptr->queue_type() ==
MainThreadTaskQueue::QueueType::kFrameLoading ||
task_queue_ptr->queue_type() ==
MainThreadTaskQueue::QueueType::kFrameLoadingControl) {
EXPECT_NE(voter, nullptr); EXPECT_NE(voter, nullptr);
} else if (task_queue_ptr->GetQueueTraits().can_be_paused) {
EXPECT_NE(voter, nullptr);
} else {
EXPECT_EQ(voter, nullptr);
}
} }
} }
......
...@@ -86,9 +86,9 @@ class PLATFORM_EXPORT FrameOrWorkerScheduler { ...@@ -86,9 +86,9 @@ class PLATFORM_EXPORT FrameOrWorkerScheduler {
virtual ~FrameOrWorkerScheduler(); virtual ~FrameOrWorkerScheduler();
using Paused = util::StrongAlias<class PausedTag, bool>; using Preempted = util::StrongAlias<class PreemptedTag, bool>;
// Stops any tasks from running while we yield and run a nested loop. // Stops any tasks from running while we yield and run a nested loop.
virtual void SetPausedForCooperativeScheduling(Paused) = 0; virtual void SetPreemptedForCooperativeScheduling(Preempted) = 0;
// Notifies scheduler that this execution context has started using a feature // Notifies scheduler that this execution context has started using a feature
// which impacts scheduling decisions. // which impacts scheduling decisions.
......
...@@ -68,7 +68,7 @@ class PLATFORM_EXPORT WorkerScheduler : public FrameOrWorkerScheduler { ...@@ -68,7 +68,7 @@ class PLATFORM_EXPORT WorkerScheduler : public FrameOrWorkerScheduler {
const SchedulingPolicy& policy) override; const SchedulingPolicy& policy) override;
// FrameOrWorkerScheduler implementation: // FrameOrWorkerScheduler implementation:
void SetPausedForCooperativeScheduling(Paused) override {} void SetPreemptedForCooperativeScheduling(Preempted) override {}
protected: protected:
scoped_refptr<NonMainThreadTaskQueue> ThrottleableTaskQueue(); scoped_refptr<NonMainThreadTaskQueue> ThrottleableTaskQueue();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment