Commit 637e74c1 authored by Chase Phillips's avatar Chase Phillips Committed by Commit Bot

IndexedDB: Add a finch trial for setting Blink tasks to high priority

Bug: 984374
Change-Id: I47829925197a08fb58469418a7f392d350dd52ca
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1652747
Commit-Queue: Chase Phillips <cmp@chromium.org>
Reviewed-by: default avatarAlexander Timin <altimin@chromium.org>
Reviewed-by: default avatarDaniel Murphy <dmurph@chromium.org>
Cr-Commit-Position: refs/heads/master@{#678882}
parent 8e0cb6f5
......@@ -174,6 +174,10 @@ const base::Feature kBlinkSchedulerDisableAntiStarvationForPriorities{
"BlinkSchedulerDisableAntiStarvationForPriorities",
base::FEATURE_DISABLED_BY_DEFAULT};
// Enable setting high priority database task type from field trial parameters.
const base::Feature kHighPriorityDatabaseTaskType{
"HighPriorityDatabaseTaskType", base::FEATURE_DISABLED_BY_DEFAULT};
} // namespace scheduler
} // namespace blink
......
......@@ -398,7 +398,7 @@ base::Optional<QueueTraits> FrameSchedulerImpl::CreateQueueTraitsForTaskType(
// TODO(haraken): Optimize the mapping from TaskTypes to task runners.
switch (type) {
// kInternalContentCapture uses BestEffortTaskQueue and is handled
// sparately.
// separately.
case TaskType::kInternalContentCapture:
case TaskType::kJavascriptTimer:
return ThrottleableTaskQueueTraits();
......@@ -445,7 +445,6 @@ base::Optional<QueueTraits> FrameSchedulerImpl::CreateQueueTraitsForTaskType(
// Media events should not be deferred to ensure that media playback is
// smooth.
case TaskType::kMediaElementEvent:
case TaskType::kDatabaseAccess:
case TaskType::kInternalWebCrypto:
case TaskType::kInternalMedia:
case TaskType::kInternalMediaRealTime:
......@@ -453,6 +452,11 @@ base::Optional<QueueTraits> FrameSchedulerImpl::CreateQueueTraitsForTaskType(
case TaskType::kInternalIntersectionObserver:
case TaskType::kInternalContinueScriptLoading:
return PausableTaskQueueTraits();
case TaskType::kDatabaseAccess:
if (base::FeatureList::IsEnabled(kHighPriorityDatabaseTaskType))
return PausableTaskQueueTraits().SetIsHighPriority(true);
else
return PausableTaskQueueTraits();
case TaskType::kInternalFreezableIPC:
return FreezableTaskQueueTraits();
case TaskType::kInternalIPC:
......
......@@ -282,6 +282,11 @@ void IncrementCounter(int* counter) {
++*counter;
}
void ExpectAndIncrementCounter(int expected, int* actual) {
EXPECT_EQ(expected, *actual);
IncrementCounter(actual);
}
void RecordQueueName(String name, Vector<String>* tasks) {
tasks->push_back(std::move(name));
}
......@@ -1905,6 +1910,86 @@ TEST_F(ThrottleableOnlyTaskTypesTest, QueueTraitsFromFieldTrialParams) {
true));
}
class FrameSchedulerImplDatabaseAccessWithoutHighPriority
: public FrameSchedulerImplTest {
public:
FrameSchedulerImplDatabaseAccessWithoutHighPriority()
: FrameSchedulerImplTest({}, {kHighPriorityDatabaseTaskType}) {}
};
TEST_F(FrameSchedulerImplDatabaseAccessWithoutHighPriority, QueueTraits) {
// These tests will start to fail if the default task queues or queue traits
// change for these task types.
int counter = 0;
auto loading_queue = GetTaskQueue(TaskType::kInternalContinueScriptLoading);
EXPECT_EQ(loading_queue->GetQueuePriority(),
TaskQueue::QueuePriority::kVeryHighPriority);
loading_queue->task_runner()->PostTask(
FROM_HERE, base::BindOnce(&ExpectAndIncrementCounter, 0,
base::Unretained(&counter)));
auto da_queue = GetTaskQueue(TaskType::kDatabaseAccess);
EXPECT_EQ(da_queue->GetQueueTraits().is_high_priority, false);
EXPECT_EQ(da_queue->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
da_queue->task_runner()->PostTask(
FROM_HERE, base::BindOnce(&ExpectAndIncrementCounter, 1,
base::Unretained(&counter)));
auto content_queue = GetTaskQueue(TaskType::kInternalContentCapture);
EXPECT_EQ(content_queue->GetQueuePriority(),
TaskQueue::QueuePriority::kBestEffortPriority);
content_queue->task_runner()->PostTask(
FROM_HERE, base::BindOnce(&ExpectAndIncrementCounter, 2,
base::Unretained(&counter)));
EXPECT_EQ(0, counter);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(3, counter);
}
class FrameSchedulerImplDatabaseAccessWithHighPriority
: public FrameSchedulerImplTest {
public:
FrameSchedulerImplDatabaseAccessWithHighPriority()
: FrameSchedulerImplTest({kHighPriorityDatabaseTaskType}, {}) {}
};
TEST_F(FrameSchedulerImplDatabaseAccessWithHighPriority, QueueTraits) {
// These tests will start to fail if the default task queues or queue traits
// change for these task types.
int counter = 0;
auto loading_queue = GetTaskQueue(TaskType::kInternalContinueScriptLoading);
EXPECT_EQ(loading_queue->GetQueuePriority(),
TaskQueue::QueuePriority::kVeryHighPriority);
loading_queue->task_runner()->PostTask(
FROM_HERE, base::BindOnce(&ExpectAndIncrementCounter, 0,
base::Unretained(&counter)));
auto da_queue = GetTaskQueue(TaskType::kDatabaseAccess);
EXPECT_EQ(da_queue->GetQueueTraits().is_high_priority, true);
EXPECT_EQ(da_queue->GetQueuePriority(),
TaskQueue::QueuePriority::kHighPriority);
da_queue->task_runner()->PostTask(
FROM_HERE, base::BindOnce(&ExpectAndIncrementCounter, 1,
base::Unretained(&counter)));
auto pausable_queue = PausableTaskQueue();
EXPECT_EQ(pausable_queue->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
pausable_queue->task_runner()->PostTask(
FROM_HERE, base::BindOnce(&ExpectAndIncrementCounter, 2,
base::Unretained(&counter)));
EXPECT_EQ(0, counter);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(3, counter);
}
TEST_F(FrameSchedulerImplTest, ContentCaptureHasIdleTaskQueue) {
auto task_queue = GetTaskQueue(TaskType::kInternalContentCapture);
......
......@@ -129,19 +129,28 @@ void FrameTaskQueueController::CreateNonLoadingTaskQueue(
// |main_thread_scheduler_impl_| can be null in unit tests.
DCHECK(main_thread_scheduler_impl_);
MainThreadTaskQueue::QueueCreationParams queue_creation_params(
QueueTypeFromQueueTraits(queue_traits));
queue_creation_params =
queue_creation_params
.SetQueueTraits(queue_traits)
// Freeze when keep active is currently only set for the
// throttleable queue.
// TODO(altimin): Figure out how to set this for new queues.
// Investigate which tasks must be kept alive, and if possible
// move them to an unfreezable queue and remove this override and
// the page scheduler KeepActive freezing override.
.SetFreezeWhenKeepActive(queue_traits.can_be_throttled)
.SetFrameScheduler(frame_scheduler_impl_);
if (queue_traits.is_high_priority) {
queue_creation_params = queue_creation_params.SetFixedPriority(
TaskQueue::QueuePriority::kHighPriority);
}
scoped_refptr<MainThreadTaskQueue> task_queue =
main_thread_scheduler_impl_->NewTaskQueue(
MainThreadTaskQueue::QueueCreationParams(
QueueTypeFromQueueTraits(queue_traits))
.SetQueueTraits(queue_traits)
// Freeze when keep active is currently only set for the
// throttleable queue.
// TODO(altimin): Figure out how to set this for new queues.
// Investigate which tasks must be kept alive, and if possible
// move them to an unfreezable queue and remove this override and
// the page scheduler KeepActive freezing override.
.SetFreezeWhenKeepActive(queue_traits.can_be_throttled)
.SetFrameScheduler(frame_scheduler_impl_));
main_thread_scheduler_impl_->NewTaskQueue(queue_creation_params);
TaskQueueCreated(task_queue);
non_loading_task_queues_.insert(queue_traits.Key(), task_queue);
}
......
......@@ -104,7 +104,8 @@ class PLATFORM_EXPORT MainThreadTaskQueue
can_be_paused(false),
can_be_frozen(false),
can_run_in_background(true),
should_use_virtual_time(true) {}
should_use_virtual_time(true),
is_high_priority(false) {}
QueueTraits(const QueueTraits&) = default;
......@@ -138,13 +139,19 @@ class PLATFORM_EXPORT MainThreadTaskQueue
return *this;
}
QueueTraits SetIsHighPriority(bool value) {
is_high_priority = value;
return *this;
}
bool operator==(const QueueTraits& other) const {
return can_be_deferred == other.can_be_deferred &&
can_be_throttled == other.can_be_throttled &&
can_be_paused == other.can_be_paused &&
can_be_frozen == other.can_be_frozen &&
can_run_in_background == other.can_run_in_background &&
should_use_virtual_time == other.should_use_virtual_time;
should_use_virtual_time == other.should_use_virtual_time &&
is_high_priority == other.is_high_priority;
}
// Return a key suitable for WTF::HashMap.
......@@ -157,6 +164,7 @@ class PLATFORM_EXPORT MainThreadTaskQueue
key |= can_be_frozen << 4;
key |= can_run_in_background << 5;
key |= should_use_virtual_time << 6;
key |= is_high_priority << 7;
return key;
}
......@@ -166,6 +174,7 @@ class PLATFORM_EXPORT MainThreadTaskQueue
bool can_be_frozen : 1;
bool can_run_in_background : 1;
bool should_use_virtual_time : 1;
bool is_high_priority : 1;
};
struct QueueCreationParams {
......
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