Commit d29dc2d1 authored by Francois Doray's avatar Francois Doray Committed by Commit Bot

[blink scheduler] Allow unaligned wake ups in same-origin frames.

This CL uses the unaligned wake ups setting added to WakeUpBudgetPool
in https://crrev.com/c/2249377 to allow unaligned wake ups in
frames that are same-origin with the main frame.

This completes implementation of the policy presented in this
message: https://groups.google.com/a/chromium.org/g/blink-dev/c/8En_5DqV_fU/m/z0Xth2xLAgAJ

Bug: 1075553
Change-Id: I1ac00f1efc58f1a701120514fb7ca4dcca94ba9f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2252935
Commit-Queue: François Doray <fdoray@chromium.org>
Reviewed-by: default avatarAlexander Timin <altimin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#782051}
parent f5a55d4e
...@@ -272,6 +272,15 @@ class FrameSchedulerImplTest : public testing::Test { ...@@ -272,6 +272,15 @@ class FrameSchedulerImplTest : public testing::Test {
frame_scheduler_delegate_->update_task_time_calls_ = 0; frame_scheduler_delegate_->update_task_time_calls_ = 0;
} }
// Fast-forwards to the next time aligned on |interval|.
void FastForwardToAlignedTime(base::TimeDelta interval) {
const base::TimeTicks now = base::TimeTicks::Now();
const base::TimeTicks aligned =
now.SnappedToNextTick(base::TimeTicks(), interval);
if (aligned != now)
task_environment_.FastForwardBy(aligned - now);
}
static uint64_t GetActiveFeaturesTrackedForBackForwardCacheMetricsMask( static uint64_t GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(
FrameSchedulerImpl* frame_scheduler) { FrameSchedulerImpl* frame_scheduler) {
return frame_scheduler return frame_scheduler
...@@ -473,12 +482,8 @@ class FrameSchedulerImplTestWithIntensiveWakeUpThrottling ...@@ -473,12 +482,8 @@ class FrameSchedulerImplTestWithIntensiveWakeUpThrottling
using Super = FrameSchedulerImplTest; using Super = FrameSchedulerImplTest;
FrameSchedulerImplTestWithIntensiveWakeUpThrottling() FrameSchedulerImplTestWithIntensiveWakeUpThrottling()
: FrameSchedulerImplTest( : FrameSchedulerImplTest({features::kIntensiveWakeUpThrottling},
{{features::kIntensiveWakeUpThrottling, {features::kStopInBackground}) {}
{// Make the grace period for intensive throttling shorter than
// the grace period for freezing, because freezing hides the
// effect of intensive throttling.
{kIntensiveWakeUpThrottling_GracePeriodSeconds_Name, "60"}}}}) {}
void SetUp() override { void SetUp() override {
Super::SetUp(); Super::SetUp();
...@@ -489,6 +494,13 @@ class FrameSchedulerImplTestWithIntensiveWakeUpThrottling ...@@ -489,6 +494,13 @@ class FrameSchedulerImplTestWithIntensiveWakeUpThrottling
ClearIntensiveWakeUpThrottlingPolicyOverrideCacheForTesting(); ClearIntensiveWakeUpThrottlingPolicyOverrideCacheForTesting();
Super::TearDown(); Super::TearDown();
} }
const int kNumTasks = 5;
const base::TimeDelta kShortDelay = base::TimeDelta::FromSeconds(1);
const base::TimeDelta kGracePeriod =
GetIntensiveWakeUpThrottlingGracePeriod();
const base::TimeDelta kDurationBetweenWakeUps =
GetIntensiveWakeUpThrottlingDurationBetweenWakeUps();
}; };
class FrameSchedulerImplTestWithIntensiveWakeUpThrottlingPolicyOverride class FrameSchedulerImplTestWithIntensiveWakeUpThrottlingPolicyOverride
...@@ -697,7 +709,7 @@ void RePostTask(scoped_refptr<base::SingleThreadTaskRunner> task_runner, ...@@ -697,7 +709,7 @@ void RePostTask(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
} // namespace } // namespace
// Verify that tasks in a throttled task queues run at the expected time, when // Verify that tasks in a throttled task queue run at the expected time, when
// intensive wake up throttling is disabled. Disable the kStopInBackground // intensive wake up throttling is disabled. Disable the kStopInBackground
// feature because it hides the effect of intensive wake up throttling. // feature because it hides the effect of intensive wake up throttling.
TEST_F(FrameSchedulerImplStopInBackgroundDisabledTest, ThrottledTaskExecution) { TEST_F(FrameSchedulerImplStopInBackgroundDisabledTest, ThrottledTaskExecution) {
...@@ -2476,16 +2488,12 @@ void RecordRunTime(std::vector<base::TimeTicks>* run_times) { ...@@ -2476,16 +2488,12 @@ void RecordRunTime(std::vector<base::TimeTicks>* run_times) {
} }
} // namespace } // namespace
// Verified that tasks posted with TaskType::kJavascriptTimer run at the // Verify that tasks posted with TaskType::kJavascriptTimer run at the expected
// expected time when throttled. // time when throttled.
TEST_F(FrameSchedulerImplTest, ThrottledJSTimerTasksRunTime) { TEST_F(FrameSchedulerImplTest, ThrottledJSTimerTasksRunTime) {
// Snap the time to a multiple of 1 second. Otherwise, the exact run time // Snap the time to a multiple of 1 second. Otherwise, the exact run time
// of throttled tasks after hidding the page will vary. // of throttled tasks after hiding the page will vary.
const base::TimeTicks start_time = base::TimeTicks::Now(); FastForwardToAlignedTime(base::TimeDelta::FromSeconds(1));
const base::TimeTicks aligned_start_time = start_time.SnappedToNextTick(
base::TimeTicks(), base::TimeDelta::FromSeconds(1));
if (aligned_start_time != start_time)
task_environment_.FastForwardBy(aligned_start_time - start_time);
const base::TimeTicks start = base::TimeTicks::Now(); const base::TimeTicks start = base::TimeTicks::Now();
// Hide the page to start throttling JS Timers. // Hide the page to start throttling JS Timers.
...@@ -2528,23 +2536,20 @@ TEST_F(FrameSchedulerImplTest, ThrottledJSTimerTasksRunTime) { ...@@ -2528,23 +2536,20 @@ TEST_F(FrameSchedulerImplTest, ThrottledJSTimerTasksRunTime) {
start + base::TimeDelta::FromMilliseconds(6000))); start + base::TimeDelta::FromMilliseconds(6000)));
} }
TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottling, TaskExecution) { // Verify that tasks run at the expected time in frame that is same-origin with
constexpr int kNumTasks = 5; // the main frame with intensive wake up throttling.
constexpr base::TimeDelta kShortDelay = base::TimeDelta::FromSeconds(1); TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottling,
const base::TimeDelta kGracePeriod = TaskExecutionSameOriginFrame) {
GetIntensiveWakeUpThrottlingGracePeriod(); ASSERT_FALSE(frame_scheduler_->IsCrossOriginToMainFrame());
const base::TimeDelta kDurationBetweenWakeUps =
GetIntensiveWakeUpThrottlingDurationBetweenWakeUps(); // Throttled TaskRunner to which tasks are posted in this test.
const scoped_refptr<base::SingleThreadTaskRunner> task_runner = const scoped_refptr<base::SingleThreadTaskRunner> task_runner =
frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimer); frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimer);
// Snap the time to a multiple of |kDurationBetweenWakeUps|. Otherwise, // Snap the time to a multiple of |kDurationBetweenWakeUps|. Otherwise,
// the time at which tasks can run after throttling is enabled will vary. // the time at which tasks can run after throttling is enabled will vary.
const base::TimeTicks start_time = base::TimeTicks::Now(); FastForwardToAlignedTime(kDurationBetweenWakeUps);
const base::TimeTicks aligned_start_time = const base::TimeTicks test_start = base::TimeTicks::Now();
start_time.SnappedToNextTick(base::TimeTicks(), kDurationBetweenWakeUps);
if (aligned_start_time != start_time)
task_environment_.FastForwardBy(aligned_start_time - start_time);
// Hide the page. This starts the delay to throttle background wake ups. // Hide the page. This starts the delay to throttle background wake ups.
EXPECT_TRUE(page_scheduler_->IsPageVisible()); EXPECT_TRUE(page_scheduler_->IsPageVisible());
...@@ -2552,55 +2557,355 @@ TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottling, TaskExecution) { ...@@ -2552,55 +2557,355 @@ TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottling, TaskExecution) {
// Initially, wake ups are not throttled. // Initially, wake ups are not throttled.
{ {
int counter = 0; const base::TimeTicks scope_start = base::TimeTicks::Now();
EXPECT_EQ(scope_start, test_start);
std::vector<base::TimeTicks> run_times;
for (int i = 0; i < kNumTasks; ++i) { for (int i = 0; i < kNumTasks; ++i) {
task_runner->PostDelayedTask( task_runner->PostDelayedTask(FROM_HERE,
FROM_HERE, base::BindOnce(&RecordRunTime, &run_times),
base::BindOnce(&IncrementCounter, base::Unretained(&counter)), i * kShortDelay);
i * kShortDelay);
} }
EXPECT_EQ(0, counter); task_environment_.FastForwardBy(kGracePeriod);
task_environment_.FastForwardBy(kShortDelay * kNumTasks); EXPECT_THAT(run_times, testing::ElementsAre(
EXPECT_EQ(kNumTasks, counter); scope_start + base::TimeDelta::FromSeconds(0),
task_environment_.FastForwardBy(kGracePeriod - kNumTasks * kShortDelay); scope_start + base::TimeDelta::FromSeconds(1),
scope_start + base::TimeDelta::FromSeconds(2),
scope_start + base::TimeDelta::FromSeconds(3),
scope_start + base::TimeDelta::FromSeconds(4)));
} }
// After |kGracePeriod|, wake ups are limited to 1 per // After |kGracePeriod|, a wake up can occur |kDurationBetweenWakeUps| after
// |kDurationBetweenWakeUps|. // the last wake up, or at a time aligned on |kDurationBetweenWakeUps|.
// Test waking up |kDurationBetweenWakeUps| after the last
// wake up.
{ {
int counter = 0; const base::TimeTicks scope_start = base::TimeTicks::Now();
EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(5));
std::vector<base::TimeTicks> run_times;
task_runner->PostDelayedTask(
FROM_HERE, base::BindOnce(&RecordRunTime, &run_times), kShortDelay);
task_environment_.FastForwardBy(kShortDelay);
EXPECT_THAT(run_times, testing::ElementsAre(
scope_start + base::TimeDelta::FromSeconds(1)));
}
// Test waking up at a time aligned on ||kDurationBetweenWakeUps|.
{
const base::TimeTicks scope_start = base::TimeTicks::Now();
EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(5) +
base::TimeDelta::FromSeconds(1));
std::vector<base::TimeTicks> run_times;
for (int i = 0; i < kNumTasks; ++i) { for (int i = 0; i < kNumTasks; ++i) {
task_runner->PostDelayedTask( task_runner->PostDelayedTask(FROM_HERE,
FROM_HERE, base::BindOnce(&RecordRunTime, &run_times),
base::BindOnce(&IncrementCounter, base::Unretained(&counter)), (i + 1) * kShortDelay);
(i + 1) * kShortDelay);
} }
EXPECT_EQ(0, counter); // // All tasks should run at the next aligned time.
// No task should run before |kDurationBetweenWakeUps| has elapsed. FastForwardToAlignedTime(kDurationBetweenWakeUps);
EXPECT_THAT(run_times, testing::ElementsAre(
scope_start + base::TimeDelta::FromSeconds(59),
scope_start + base::TimeDelta::FromSeconds(59),
scope_start + base::TimeDelta::FromSeconds(59),
scope_start + base::TimeDelta::FromSeconds(59),
scope_start + base::TimeDelta::FromSeconds(59)));
}
// Post an extra task with a short delay. It should run at the next time
// aligned on |kDurationBetweenWakeUps|.
{
const base::TimeTicks scope_start = base::TimeTicks::Now();
EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(6));
std::vector<base::TimeTicks> run_times;
task_runner->PostDelayedTask(
FROM_HERE, base::BindOnce(&RecordRunTime, &run_times), kShortDelay);
task_environment_.FastForwardBy(kDurationBetweenWakeUps);
EXPECT_THAT(run_times, testing::ElementsAre(
scope_start + base::TimeDelta::FromMinutes(1)));
}
// Post an extra task with a delay that is longer than
// |kDurationBetweenWakeUps|. The task should run at its
// desired run time, even if it's not aligned on |kDurationBetweenWakeUps|.
{
const base::TimeTicks scope_start = base::TimeTicks::Now();
EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(7));
std::vector<base::TimeTicks> run_times;
const base::TimeDelta kLongDelay =
kDurationBetweenWakeUps * 5 + kShortDelay;
task_runner->PostDelayedTask(
FROM_HERE, base::BindOnce(&RecordRunTime, &run_times), kLongDelay);
task_environment_.FastForwardUntilNoTasksRemain();
EXPECT_THAT(run_times, testing::ElementsAre(scope_start + kLongDelay));
}
}
// Verify that tasks run at the expected time in a frame that is cross-origin
// with the main frame with intensive wake up throttling.
TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottling,
TaskExecutionCrossOriginFrame) {
frame_scheduler_->SetCrossOriginToMainFrame(true);
// Throttled TaskRunner to which tasks are posted in this test.
const scoped_refptr<base::SingleThreadTaskRunner> task_runner =
frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimer);
// Snap the time to a multiple of |kDurationBetweenWakeUps|. Otherwise,
// the time at which tasks can run after throttling is enabled will vary.
FastForwardToAlignedTime(kDurationBetweenWakeUps);
const base::TimeTicks test_start = base::TimeTicks::Now();
// Hide the page. This starts the delay to throttle background wake ups.
EXPECT_TRUE(page_scheduler_->IsPageVisible());
page_scheduler_->SetPageVisible(false);
// Initially, wake ups are not throttled.
{
const base::TimeTicks scope_start = base::TimeTicks::Now();
EXPECT_EQ(scope_start, test_start);
std::vector<base::TimeTicks> run_times;
for (int i = 0; i < kNumTasks; ++i) { for (int i = 0; i < kNumTasks; ++i) {
task_environment_.FastForwardBy(kShortDelay); task_runner->PostDelayedTask(FROM_HERE,
EXPECT_EQ(0, counter); base::BindOnce(&RecordRunTime, &run_times),
i * kShortDelay);
} }
// All tasks should run after |kDurationBetweenWakeUps| has elapsed.
task_environment_.FastForwardBy(kDurationBetweenWakeUps - task_environment_.FastForwardBy(kGracePeriod);
kNumTasks * kShortDelay); EXPECT_THAT(run_times, testing::ElementsAre(
EXPECT_EQ(kNumTasks, counter); scope_start + base::TimeDelta::FromSeconds(0),
scope_start + base::TimeDelta::FromSeconds(1),
scope_start + base::TimeDelta::FromSeconds(2),
scope_start + base::TimeDelta::FromSeconds(3),
scope_start + base::TimeDelta::FromSeconds(4)));
} }
// After |kGracePeriod|, a wake up can occur aligned on
// |kDurationBetweenWakeUps| only.
// Test posting a first task. It should run at the next aligned time (in a
// main frame, it would have run kDurationBetweenWakeUps
// after the last wake up).
{
const base::TimeTicks scope_start = base::TimeTicks::Now();
EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(5));
std::vector<base::TimeTicks> run_times;
task_runner->PostDelayedTask(
FROM_HERE, base::BindOnce(&RecordRunTime, &run_times), kShortDelay);
task_environment_.FastForwardBy(kDurationBetweenWakeUps);
EXPECT_THAT(run_times, testing::ElementsAre(
scope_start + base::TimeDelta::FromMinutes(1)));
}
// Test posting many tasks with short delays. They should all run on the next
// time aligned on |kDurationBetweenWakeUps|.
{ {
// Post an extra task. It should run after another |kDurationBetweenWakeUps| const base::TimeTicks scope_start = base::TimeTicks::Now();
// has elapsed. EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(6));
std::vector<base::TimeTicks> run_times;
for (int i = 0; i < kNumTasks; ++i) {
task_runner->PostDelayedTask(FROM_HERE,
base::BindOnce(&RecordRunTime, &run_times),
(i + 1) * kShortDelay);
}
task_environment_.FastForwardBy(kDurationBetweenWakeUps);
EXPECT_THAT(run_times, testing::ElementsAre(
scope_start + base::TimeDelta::FromMinutes(1),
scope_start + base::TimeDelta::FromMinutes(1),
scope_start + base::TimeDelta::FromMinutes(1),
scope_start + base::TimeDelta::FromMinutes(1),
scope_start + base::TimeDelta::FromMinutes(1)));
}
// Post an extra task with a short delay. It should run at the next time
// aligned on |kDurationBetweenWakeUps|.
{
const base::TimeTicks scope_start = base::TimeTicks::Now();
EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(7));
std::vector<base::TimeTicks> run_times;
task_runner->PostDelayedTask(
FROM_HERE, base::BindOnce(&RecordRunTime, &run_times), kShortDelay);
task_environment_.FastForwardBy(kDurationBetweenWakeUps);
EXPECT_THAT(run_times, testing::ElementsAre(
scope_start + base::TimeDelta::FromMinutes(1)));
}
// Post an extra task with a delay that is longer than
// |kDurationBetweenWakeUps|. The task should run at an aligned time (in a
// main frame, it would have run at is desired unaligned run time).
{
const base::TimeTicks scope_start = base::TimeTicks::Now();
EXPECT_EQ(scope_start, test_start + base::TimeDelta::FromMinutes(8));
std::vector<base::TimeTicks> run_times;
const base::TimeDelta kLongDelay =
kDurationBetweenWakeUps * 5 + base::TimeDelta::FromSeconds(1);
task_runner->PostDelayedTask(
FROM_HERE, base::BindOnce(&RecordRunTime, &run_times), kLongDelay);
task_environment_.FastForwardUntilNoTasksRemain();
EXPECT_THAT(run_times, testing::ElementsAre(scope_start +
kDurationBetweenWakeUps * 6));
}
}
// Verify that tasks from different frames that are same-origin with the main
// frame run at the expected time.
TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottling,
ManySameFrameOriginFrames) {
ASSERT_FALSE(frame_scheduler_->IsCrossOriginToMainFrame());
const scoped_refptr<base::SingleThreadTaskRunner> task_runner =
frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimer);
// Create a FrameScheduler that is same-origin with the main frame, and an
// associated throttled TaskRunner.
std::unique_ptr<FrameSchedulerImpl> other_frame_scheduler =
CreateFrameScheduler(page_scheduler_.get(),
frame_scheduler_delegate_.get(), nullptr,
FrameScheduler::FrameType::kSubframe);
ASSERT_FALSE(other_frame_scheduler->IsCrossOriginToMainFrame());
const scoped_refptr<base::SingleThreadTaskRunner> other_task_runner =
other_frame_scheduler->GetTaskRunner(TaskType::kJavascriptTimer);
// Snap the time to a multiple of |kDurationBetweenWakeUps|. Otherwise,
// the time at which tasks can run after throttling is enabled will vary.
FastForwardToAlignedTime(kDurationBetweenWakeUps);
// Hide the page and wait until the intensive throttling grace period has
// elapsed.
EXPECT_TRUE(page_scheduler_->IsPageVisible());
page_scheduler_->SetPageVisible(false);
task_environment_.FastForwardBy(kGracePeriod);
// Post tasks in both frames, with delays shorter than the wake up interval.
int counter = 0;
task_runner->PostDelayedTask(
FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter)),
kShortDelay);
int other_counter = 0;
other_task_runner->PostDelayedTask(
FROM_HERE,
base::BindOnce(&IncrementCounter, base::Unretained(&other_counter)),
2 * kShortDelay);
// The first task should run at an unaligned time, because no wake up occurred
// in the last |kDurationBetweenWakeUps|.
EXPECT_EQ(0, counter);
task_environment_.FastForwardBy(kShortDelay);
EXPECT_EQ(1, counter);
// The second task must run at an aligned time.
constexpr base::TimeDelta kEpsilon = base::TimeDelta::FromMicroseconds(1);
EXPECT_EQ(0, other_counter);
task_environment_.FastForwardBy(kShortDelay);
EXPECT_EQ(0, other_counter);
task_environment_.FastForwardBy(kDurationBetweenWakeUps - 2 * kShortDelay -
kEpsilon);
EXPECT_EQ(0, other_counter);
task_environment_.FastForwardBy(kEpsilon);
EXPECT_EQ(1, other_counter);
}
// Verify that tasks run at the same time when a frame switches between being
// same-origin and cross-origin with the main frame.
TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottling,
FrameChangesOriginType) {
EXPECT_FALSE(frame_scheduler_->IsCrossOriginToMainFrame());
const scoped_refptr<base::SingleThreadTaskRunner> task_runner =
frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimer);
// Create a new FrameScheduler that remains cross-origin with the main frame
// throughout the test.
std::unique_ptr<FrameSchedulerImpl> cross_origin_frame_scheduler =
CreateFrameScheduler(page_scheduler_.get(),
frame_scheduler_delegate_.get(), nullptr,
FrameScheduler::FrameType::kSubframe);
cross_origin_frame_scheduler->SetCrossOriginToMainFrame(true);
const scoped_refptr<base::SingleThreadTaskRunner> cross_origin_task_runner =
cross_origin_frame_scheduler->GetTaskRunner(TaskType::kJavascriptTimer);
// Snap the time to a multiple of |kDurationBetweenWakeUps|. Otherwise,
// the time at which tasks can run after throttling is enabled will vary.
FastForwardToAlignedTime(kDurationBetweenWakeUps);
// Hide the page and wait until the intensive throttling grace period has
// elapsed.
EXPECT_TRUE(page_scheduler_->IsPageVisible());
page_scheduler_->SetPageVisible(false);
task_environment_.FastForwardBy(kGracePeriod);
{
// Post delayed tasks with short delays to both frames. The
// main-frame-origin task can run at the desired time, because no wake up
// occurred in the last |kDurationBetweenWakeUps|. The
// cross-origin task must run at an aligned time.
int counter = 0; int counter = 0;
task_runner->PostDelayedTask( task_runner->PostDelayedTask(
FROM_HERE, FROM_HERE,
base::BindOnce(&IncrementCounter, base::Unretained(&counter)), base::BindOnce(&IncrementCounter, base::Unretained(&counter)),
kShortDelay); kShortDelay);
int cross_origin_counter = 0;
cross_origin_task_runner->PostDelayedTask(
FROM_HERE,
base::BindOnce(&IncrementCounter,
base::Unretained(&cross_origin_counter)),
kShortDelay);
// Make the |frame_scheduler_| cross-origin. Its task must now run at an
// aligned time.
frame_scheduler_->SetCrossOriginToMainFrame(true);
task_environment_.FastForwardBy(kShortDelay); task_environment_.FastForwardBy(kShortDelay);
EXPECT_EQ(0, counter); EXPECT_EQ(0, counter);
task_environment_.FastForwardBy(kDurationBetweenWakeUps - kShortDelay); EXPECT_EQ(0, cross_origin_counter);
FastForwardToAlignedTime(kDurationBetweenWakeUps);
EXPECT_EQ(1, counter);
EXPECT_EQ(1, cross_origin_counter);
}
{
// Post delayed tasks with long delays that aren't aligned with the wake up
// interval. They should run at aligned times, since they are cross-origin.
const base::TimeDelta kLongUnalignedDelay =
5 * kDurationBetweenWakeUps + kShortDelay;
int counter = 0;
task_runner->PostDelayedTask(
FROM_HERE,
base::BindOnce(&IncrementCounter, base::Unretained(&counter)),
kLongUnalignedDelay);
int cross_origin_counter = 0;
cross_origin_task_runner->PostDelayedTask(
FROM_HERE,
base::BindOnce(&IncrementCounter,
base::Unretained(&cross_origin_counter)),
kLongUnalignedDelay);
// Make the |frame_scheduler_| same-origin. Its task can now run at an
// unaligned time.
frame_scheduler_->SetCrossOriginToMainFrame(false);
task_environment_.FastForwardBy(kLongUnalignedDelay);
EXPECT_EQ(1, counter);
EXPECT_EQ(0, cross_origin_counter);
FastForwardToAlignedTime(kDurationBetweenWakeUps);
EXPECT_EQ(1, counter); EXPECT_EQ(1, counter);
EXPECT_EQ(1, cross_origin_counter);
} }
} }
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/scheduler/common/features.h" #include "third_party/blink/renderer/platform/scheduler/common/features.h"
#include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h"
#include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
...@@ -637,9 +638,14 @@ void PageSchedulerImpl::MaybeInitializeWakeUpBudgetPools( ...@@ -637,9 +638,14 @@ void PageSchedulerImpl::MaybeInitializeWakeUpBudgetPools(
main_thread_scheduler_->task_queue_throttler()->CreateWakeUpBudgetPool( main_thread_scheduler_->task_queue_throttler()->CreateWakeUpBudgetPool(
"Page Wake Up Throttling - Cross-Origin to Main Frame"); "Page Wake Up Throttling - Cross-Origin to Main Frame");
// The Wake Up Interval is set in UpdateWakeUpBudgetPools(), based on current // The Wake Up Duration and Unaligned Wake Ups Allowance are constant and set
// state. The Wake Up Duration is constant and is set here. // here. The Wake Up Interval is set in UpdateWakeUpBudgetPools(), based on
// current state.
same_origin_wake_up_budget_pool_->SetWakeUpDuration(kThrottledWakeUpDuration); same_origin_wake_up_budget_pool_->SetWakeUpDuration(kThrottledWakeUpDuration);
if (IsIntensiveWakeUpThrottlingEnabled()) {
same_origin_wake_up_budget_pool_->AllowUnalignedWakeUpIfNoRecentWakeUp();
}
cross_origin_wake_up_budget_pool_->SetWakeUpDuration( cross_origin_wake_up_budget_pool_->SetWakeUpDuration(
kThrottledWakeUpDuration); kThrottledWakeUpDuration);
......
...@@ -286,9 +286,6 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler { ...@@ -286,9 +286,6 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler {
// //
// This pool allows aligned wake ups and unaligned wake ups if there hasn't // This pool allows aligned wake ups and unaligned wake ups if there hasn't
// been a recent wake up. // been a recent wake up.
//
// TODO(https://crbug.com/1075553): Implement unaligned wake ups if there
// hasn't been a recent wake up.
WakeUpBudgetPool* same_origin_wake_up_budget_pool_; WakeUpBudgetPool* same_origin_wake_up_budget_pool_;
// Throttles wake ups in throttleable TaskQueues of frames that are // Throttles wake ups in throttleable TaskQueues of frames that are
// cross-origin with the main frame. // cross-origin with the main frame.
......
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