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 {
PageScheduler* GetPageScheduler() const override { return page_scheduler_; }
void SetPausedForCooperativeScheduling(Paused) override {}
void SetPreemptedForCooperativeScheduling(Preempted) override {}
void SetFrameVisible(bool) override {}
bool IsFrameVisible() const override { return true; }
bool IsPageVisible() const override { return true; }
......
......@@ -51,8 +51,8 @@ void EventLoop::Disable() {
loop_enabled_ = false;
for (auto* scheduler : schedulers_) {
scheduler->SetPausedForCooperativeScheduling(
FrameOrWorkerScheduler::Paused(true));
scheduler->SetPreemptedForCooperativeScheduling(
FrameOrWorkerScheduler::Preempted(true));
}
// TODO(keishi): Disable microtaskqueue too.
}
......@@ -61,8 +61,8 @@ void EventLoop::Enable() {
loop_enabled_ = true;
for (auto* scheduler : schedulers_) {
scheduler->SetPausedForCooperativeScheduling(
FrameOrWorkerScheduler::Paused(false));
scheduler->SetPreemptedForCooperativeScheduling(
FrameOrWorkerScheduler::Preempted(false));
}
// TODO(keishi): Enable microtaskqueue too.
}
......
......@@ -185,6 +185,12 @@ FrameSchedulerImpl::FrameSchedulerImpl(
this,
&tracing_controller_,
YesNoStateToString),
preempted_for_cooperative_scheduling_(
false,
"FrameScheduler.PreemptedForCooperativeScheduling",
this,
&tracing_controller_,
YesNoStateToString),
aggressive_throttling_opt_out_count(0),
opted_out_from_aggressive_throttling_(
false,
......@@ -829,6 +835,7 @@ void FrameSchedulerImpl::UpdateQueuePolicy(
DCHECK(parent_page_scheduler_);
bool queue_disabled = false;
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
// on Android, and if the browser freezes the page in the background. They
// will be resumed when the page is visible.
......@@ -1197,8 +1204,11 @@ FrameSchedulerImpl::DoesNotUseVirtualTimeTaskQueueTraits() {
return QueueTraits().SetCanRunWhenVirtualTimePaused(false);
}
void FrameSchedulerImpl::SetPausedForCooperativeScheduling(Paused paused) {
// TODO(keishi): Stop all task queues
void FrameSchedulerImpl::SetPreemptedForCooperativeScheduling(
Preempted preempted) {
DCHECK_NE(preempted.value(), preempted_for_cooperative_scheduling_);
preempted_for_cooperative_scheduling_ = preempted.value();
UpdatePolicy();
}
MainThreadTaskQueue::QueueTraits
......
......@@ -81,7 +81,7 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
~FrameSchedulerImpl() override;
// FrameOrWorkerScheduler implementation:
void SetPausedForCooperativeScheduling(Paused) override;
void SetPreemptedForCooperativeScheduling(Preempted) override;
// FrameScheduler implementation:
void SetFrameVisible(bool frame_visible) override;
......@@ -323,6 +323,8 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
TraceableState<bool, TracingCategoryName::kInfo> subresource_loading_paused_;
StateTracer<TracingCategoryName::kInfo> url_tracer_;
TraceableState<bool, TracingCategoryName::kInfo> task_queues_throttled_;
TraceableState<bool, TracingCategoryName::kInfo>
preempted_for_cooperative_scheduling_;
// TODO(kraynov): https://crbug.com/827113
// Trace the count of aggressive throttling opt outs.
int aggressive_throttling_opt_out_count;
......
......@@ -466,6 +466,30 @@ TEST_F(FrameSchedulerImplTest, PauseAndResume) {
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) {
int counter = 0;
ForegroundOnlyTaskQueue()->task_runner()->PostTask(
......
......@@ -129,10 +129,8 @@ void FrameTaskQueueController::TaskQueueCreated(
const scoped_refptr<MainThreadTaskQueue>& task_queue) {
DCHECK(task_queue);
std::unique_ptr<QueueEnabledVoter> voter;
// Only create a voter for queues that can be disabled.
if (task_queue->CanBePaused() || task_queue->CanBeFrozen())
voter = task_queue->CreateQueueEnabledVoter();
std::unique_ptr<QueueEnabledVoter> voter =
task_queue->CreateQueueEnabledVoter();
delegate_->OnTaskQueueCreated(task_queue.get(), voter.get());
......
......@@ -197,16 +197,7 @@ TEST_F(FrameTaskQueueControllerTest, CreateAllTaskQueues) {
EXPECT_FALSE(it == all_task_queues.end());
EXPECT_EQ(it->value, QueueCheckResult::kDidNotSeeQueue);
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);
} else if (task_queue_ptr->GetQueueTraits().can_be_paused) {
EXPECT_NE(voter, nullptr);
} else {
EXPECT_EQ(voter, nullptr);
}
EXPECT_NE(voter, nullptr);
}
}
......
......@@ -86,9 +86,9 @@ class PLATFORM_EXPORT 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.
virtual void SetPausedForCooperativeScheduling(Paused) = 0;
virtual void SetPreemptedForCooperativeScheduling(Preempted) = 0;
// Notifies scheduler that this execution context has started using a feature
// which impacts scheduling decisions.
......
......@@ -68,7 +68,7 @@ class PLATFORM_EXPORT WorkerScheduler : public FrameOrWorkerScheduler {
const SchedulingPolicy& policy) override;
// FrameOrWorkerScheduler implementation:
void SetPausedForCooperativeScheduling(Paused) override {}
void SetPreemptedForCooperativeScheduling(Preempted) override {}
protected:
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