0

SequenceManager: Make priorities configurable (yield API 1/n)

This CL makes SequenceManager priorities configurable through a new
SequenceManager::Settings option, with a single priority being
configured as the default. This is being done in advance of adding new
renderer-specific priorities to support `scheduler.yield()`, as well
as experimenting with downshifting priorities in backgrounded agents.

Configurable priorities have a few advantages:
 - Priority definitions are closer to where they're used, making it
   clear what priority system is being used where. This also enables
   better semantic (re)naming of priorities in the future, where it
   makes sense.
 - It prevents render-specific details from creeping into
   SequenceManager
 - It reduces data structure sizes for sequences that don't use
   priorities (currently only renderer main thread, (blink) workers,
   and browser UI thread).

SequenceManager is already (mostly) set up to handle an arbitrary
number of priorities; the main non-mechanical changes are:
 - A few data structures need to be vectors instead of arrays (this
   was cleaner and simpler than templating SequenceManager).
 - Tracing needs to support multiple priority systems, which is
   implemented with a configurable priority-to-proto-priority
   conversion function, along with expanding the proto enum to be the
   union of browser, renderer, and worker priorities.
 - TaskEnvironment is updated to support configurable priorities in
   its constructor, which BrowserTaskEnvironment uses to set up
   the required settings for the browser task queues.
 - The idle task priority is passed to IdleHelper along with the idle
   queue since it differs between main and non-main renderer threads.
   I'll try to set this set ahead of time in a follow-up, but this
   would have increased the complexity of this CL because of how things
   are constructed.

Bug: 979020
Low-Coverage-Reason: pure refactor / missing coverage predated this
Change-Id: I06b47347838c992bcecfe1fe69518c5e8835cdc9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4114556
Commit-Queue: Scott Haseley <shaseley@chromium.org>
Reviewed-by: Francois Pierre Doray <fdoray@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: Alexander Timin <altimin@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1106608}
This commit is contained in:
Scott Haseley
2023-02-17 03:29:25 +00:00
committed by Chromium LUCI CQ
parent 56f688d37c
commit 72d89b0bb8
71 changed files with 1128 additions and 646 deletions
base
codelabs/threading_and_scheduling
content
third_party/blink/renderer/platform

@ -4,15 +4,104 @@
#include "base/task/sequence_manager/sequence_manager.h"
#include <utility>
namespace base {
namespace sequence_manager {
namespace {
#if BUILDFLAG(ENABLE_BASE_TRACING)
perfetto::protos::pbzero::SequenceManagerTask::Priority
DefaultTaskPriorityToProto(TaskQueue::QueuePriority priority) {
DCHECK_EQ(priority, static_cast<TaskQueue::QueuePriority>(
TaskQueue::DefaultQueuePriority::kNormalPriority));
return perfetto::protos::pbzero::SequenceManagerTask::Priority::
NORMAL_PRIORITY;
}
#endif
void CheckPriorities(TaskQueue::QueuePriority priority_count,
TaskQueue::QueuePriority default_priority) {
CHECK_LE(static_cast<size_t>(priority_count),
SequenceManager::PrioritySettings::kMaxPriorities)
<< "The number of priorities cannot exceed kMaxPriorities.";
CHECK_LT(static_cast<size_t>(default_priority), priority_count)
<< "The default priority must be within the priority range.";
}
} // namespace
SequenceManager::MetricRecordingSettings::MetricRecordingSettings(
double task_thread_time_sampling_rate)
: task_sampling_rate_for_recording_cpu_time(
base::ThreadTicks::IsSupported() ? task_thread_time_sampling_rate
: 0) {}
// static
SequenceManager::PrioritySettings
SequenceManager::PrioritySettings::CreateDefault() {
PrioritySettings settings(
TaskQueue::DefaultQueuePriority::kQueuePriorityCount,
TaskQueue::DefaultQueuePriority::kNormalPriority);
#if BUILDFLAG(ENABLE_BASE_TRACING)
settings.SetProtoPriorityConverter(&DefaultTaskPriorityToProto);
#endif
return settings;
}
SequenceManager::PrioritySettings::PrioritySettings(
TaskQueue::QueuePriority priority_count,
TaskQueue::QueuePriority default_priority)
#if DCHECK_IS_ON()
: PrioritySettings(priority_count,
default_priority,
std::vector<TimeDelta>(priority_count),
std::vector<TimeDelta>(priority_count)){}
#else
: priority_count_(priority_count), default_priority_(default_priority) {
CheckPriorities(priority_count, default_priority);
}
#endif
#if DCHECK_IS_ON()
SequenceManager::PrioritySettings::PrioritySettings(
TaskQueue::QueuePriority priority_count,
TaskQueue::QueuePriority default_priority,
std::vector<TimeDelta> per_priority_cross_thread_task_delay,
std::vector<TimeDelta> per_priority_same_thread_task_delay)
: priority_count_(priority_count),
default_priority_(default_priority),
per_priority_cross_thread_task_delay_(
std::move(per_priority_cross_thread_task_delay)),
per_priority_same_thread_task_delay_(
std::move(per_priority_same_thread_task_delay)) {
CheckPriorities(priority_count, default_priority);
DCHECK_EQ(priority_count, per_priority_cross_thread_task_delay_.size());
DCHECK_EQ(priority_count, per_priority_same_thread_task_delay_.size());
}
#endif
#if BUILDFLAG(ENABLE_BASE_TRACING)
perfetto::protos::pbzero::SequenceManagerTask::Priority
SequenceManager::PrioritySettings::TaskPriorityToProto(
TaskQueue::QueuePriority priority) const {
// `proto_priority_converter_` will be null in some unit tests, but those
// tests should not be tracing.
DCHECK(proto_priority_converter_)
<< "A tracing priority-to-proto-priority function was not provided";
return proto_priority_converter_(priority);
}
#endif
SequenceManager::PrioritySettings::~PrioritySettings() = default;
SequenceManager::PrioritySettings::PrioritySettings(PrioritySettings&&) =
default;
SequenceManager::PrioritySettings& SequenceManager::PrioritySettings::operator=(
PrioritySettings&&) = default;
SequenceManager::Settings::Settings() = default;
SequenceManager::Settings::Settings(Settings&& move_from) noexcept = default;
@ -50,6 +139,13 @@ SequenceManager::Settings::Builder::SetAddQueueTimeToTasks(
return *this;
}
SequenceManager::Settings::Builder&
SequenceManager::Settings::Builder::SetPrioritySettings(
SequenceManager::PrioritySettings settings) {
settings_.priority_settings = std::move(settings);
return *this;
}
#if DCHECK_IS_ON()
SequenceManager::Settings::Builder&
@ -79,23 +175,6 @@ SequenceManager::Settings::Builder::SetLogTaskDelayExpiry(
return *this;
}
SequenceManager::Settings::Builder&
SequenceManager::Settings::Builder::SetPerPriorityCrossThreadTaskDelay(
std::array<TimeDelta, TaskQueue::kQueuePriorityCount>
per_priority_cross_thread_task_delay_val) {
settings_.per_priority_cross_thread_task_delay =
per_priority_cross_thread_task_delay_val;
return *this;
}
SequenceManager::Settings::Builder&
SequenceManager::Settings::Builder::SetPerPrioritySameThreadTaskDelay(
std::array<TimeDelta, TaskQueue::kQueuePriorityCount>
per_priority_same_thread_task_delay_val) {
settings_.per_priority_same_thread_task_delay =
per_priority_same_thread_task_delay_val;
return *this;
}
#endif // DCHECK_IS_ON()
SequenceManager::Settings SequenceManager::Settings::Builder::Build() {

@ -7,7 +7,9 @@
#include <memory>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
#include "base/base_export.h"
#include "base/dcheck_is_on.h"
@ -67,6 +69,87 @@ class BASE_EXPORT SequenceManager {
}
};
class BASE_EXPORT PrioritySettings {
public:
// This limit is based on an implementation detail of `TaskQueueSelector`'s
// `ActivePriorityTracker`, which can be refactored if more priorities are
// needed.
static constexpr size_t kMaxPriorities = sizeof(size_t) * 8 - 1;
static PrioritySettings CreateDefault();
template <typename T,
typename = typename std::enable_if_t<std::is_enum_v<T>>>
PrioritySettings(T priority_count, T default_priority)
: PrioritySettings(
static_cast<TaskQueue::QueuePriority>(priority_count),
static_cast<TaskQueue::QueuePriority>(default_priority)) {
static_assert(
std::is_same_v<std::underlying_type_t<T>, TaskQueue::QueuePriority>,
"Enumerated priorites must have the same underlying type as "
"TaskQueue::QueuePriority");
}
PrioritySettings(TaskQueue::QueuePriority priority_count,
TaskQueue::QueuePriority default_priority);
~PrioritySettings();
PrioritySettings(PrioritySettings&&);
PrioritySettings& operator=(PrioritySettings&&);
TaskQueue::QueuePriority priority_count() const { return priority_count_; }
TaskQueue::QueuePriority default_priority() const {
return default_priority_;
}
#if BUILDFLAG(ENABLE_BASE_TRACING)
void SetProtoPriorityConverter(
perfetto::protos::pbzero::SequenceManagerTask::Priority (
*proto_priority_converter)(TaskQueue::QueuePriority)) {
proto_priority_converter_ = proto_priority_converter;
}
perfetto::protos::pbzero::SequenceManagerTask::Priority TaskPriorityToProto(
TaskQueue::QueuePriority priority) const;
#endif
private:
TaskQueue::QueuePriority priority_count_;
TaskQueue::QueuePriority default_priority_;
#if BUILDFLAG(ENABLE_BASE_TRACING)
perfetto::protos::pbzero::SequenceManagerTask::Priority (
*proto_priority_converter_)(TaskQueue::QueuePriority) = nullptr;
#endif
#if DCHECK_IS_ON()
public:
PrioritySettings(
TaskQueue::QueuePriority priority_count,
TaskQueue::QueuePriority default_priority,
std::vector<TimeDelta> per_priority_cross_thread_task_delay,
std::vector<TimeDelta> per_priority_same_thread_task_delay);
const std::vector<TimeDelta>& per_priority_cross_thread_task_delay() const {
return per_priority_cross_thread_task_delay_;
}
const std::vector<TimeDelta>& per_priority_same_thread_task_delay() const {
return per_priority_same_thread_task_delay_;
}
private:
// Scheduler policy induced raciness is an area of concern. This lets us
// apply an extra delay per priority for cross thread posting.
std::vector<TimeDelta> per_priority_cross_thread_task_delay_;
// Like the above but for same thread posting.
std::vector<TimeDelta> per_priority_same_thread_task_delay_;
#endif
};
// Settings defining the desired SequenceManager behaviour: the type of the
// MessageLoop and whether randomised sampling should be enabled.
struct BASE_EXPORT Settings {
@ -89,6 +172,8 @@ class BASE_EXPORT SequenceManager {
// If true, add the timestamp the task got queued to the task.
bool add_queue_time_to_tasks = false;
PrioritySettings priority_settings = PrioritySettings::CreateDefault();
#if DCHECK_IS_ON()
// TODO(alexclarke): Consider adding command line flags to control these.
enum class TaskLogging {
@ -110,15 +195,6 @@ class BASE_EXPORT SequenceManager {
// to run.
bool log_task_delay_expiry = false;
// Scheduler policy induced raciness is an area of concern. This lets us
// apply an extra delay per priority for cross thread posting.
std::array<TimeDelta, TaskQueue::kQueuePriorityCount>
per_priority_cross_thread_task_delay;
// Like the above but for same thread posting.
std::array<TimeDelta, TaskQueue::kQueuePriorityCount>
per_priority_same_thread_task_delay;
// If not zero this seeds a PRNG used by the task selection logic to choose
// a random TaskQueue for a given priority rather than the TaskQueue with
// the oldest EnqueueOrder.
@ -202,6 +278,8 @@ class BASE_EXPORT SequenceManager {
// Returns the metric recording configuration for the current SequenceManager.
virtual const MetricRecordingSettings& GetMetricRecordingSettings() const = 0;
virtual TaskQueue::QueuePriority GetPriorityCount() const = 0;
// Creates a task queue with the given type, `spec` and args.
// Must be called on the main thread.
// TODO(scheduler-dev): SequenceManager should not create TaskQueues.
@ -273,6 +351,8 @@ class BASE_EXPORT SequenceManager::Settings::Builder {
// Whether or not queueing timestamp will be added to tasks.
Builder& SetAddQueueTimeToTasks(bool add_queue_time_to_tasks);
Builder& SetPrioritySettings(PrioritySettings settings);
#if DCHECK_IS_ON()
// Controls task execution logging.
Builder& SetTaskLogging(TaskLogging task_execution_logging);
@ -284,18 +364,6 @@ class BASE_EXPORT SequenceManager::Settings::Builder {
// eligible to run.
Builder& SetLogTaskDelayExpiry(bool log_task_delay_expiry);
// Scheduler policy induced raciness is an area of concern. This lets us
// apply an extra delay per priority for cross thread posting.
Builder& SetPerPriorityCrossThreadTaskDelay(
std::array<TimeDelta, TaskQueue::kQueuePriorityCount>
per_priority_cross_thread_task_delay);
// Scheduler policy induced raciness is an area of concern. This lets us
// apply an extra delay per priority for same thread posting.
Builder& SetPerPrioritySameThreadTaskDelay(
std::array<TimeDelta, TaskQueue::kQueuePriorityCount>
per_priority_same_thread_task_delay);
// If not zero this seeds a PRNG used by the task selection logic to choose a
// random TaskQueue for a given priority rather than the TaskQueue with the
// oldest EnqueueOrder.

@ -69,31 +69,6 @@ class TracedBaseValue : public trace_event::ConvertableToTraceFormat {
base::Value value_;
};
#if BUILDFLAG(ENABLE_BASE_TRACING)
perfetto::protos::pbzero::SequenceManagerTask::Priority TaskPriorityToProto(
TaskQueue::QueuePriority priority) {
using ProtoPriority = perfetto::protos::pbzero::SequenceManagerTask::Priority;
switch (priority) {
case TaskQueue::QueuePriority::kControlPriority:
return ProtoPriority::CONTROL_PRIORITY;
case TaskQueue::QueuePriority::kHighestPriority:
return ProtoPriority::HIGHEST_PRIORITY;
case TaskQueue::QueuePriority::kVeryHighPriority:
return ProtoPriority::VERY_HIGH_PRIORITY;
case TaskQueue::QueuePriority::kHighPriority:
return ProtoPriority::HIGH_PRIORITY;
case TaskQueue::QueuePriority::kNormalPriority:
return ProtoPriority::NORMAL_PRIORITY;
case TaskQueue::QueuePriority::kLowPriority:
return ProtoPriority::LOW_PRIORITY;
case TaskQueue::QueuePriority::kBestEffortPriority:
return ProtoPriority::BEST_EFFORT_PRIORITY;
case TaskQueue::QueuePriority::kQueuePriorityCount:
return ProtoPriority::UNKNOWN;
}
}
#endif // BUILDFLAG(ENABLE_BASE_TRACING)
} // namespace
std::unique_ptr<SequenceManager> CreateSequenceManagerOnCurrentThread(
@ -415,7 +390,8 @@ SequenceManagerImpl::CreateTaskQueueImpl(const TaskQueue::Spec& spec) {
: main_thread_only().wake_up_queue.get(),
spec);
main_thread_only().active_queues.insert(task_queue.get());
main_thread_only().selector.AddQueue(task_queue.get());
main_thread_only().selector.AddQueue(
task_queue.get(), settings().priority_settings.default_priority());
return task_queue;
}
@ -539,7 +515,7 @@ void SequenceManagerImpl::SetNextWakeUp(LazyNow* lazy_now,
void SequenceManagerImpl::MaybeEmitTaskDetails(
perfetto::EventContext& ctx,
const SequencedTaskSource::SelectedTask& selected_task) {
const SequencedTaskSource::SelectedTask& selected_task) const {
#if BUILDFLAG(ENABLE_BASE_TRACING)
// Other parameters are included only when "scheduler" category is enabled.
const uint8_t* scheduler_category_enabled =
@ -550,7 +526,7 @@ void SequenceManagerImpl::MaybeEmitTaskDetails(
auto* event = ctx.event<perfetto::protos::pbzero::ChromeTrackEvent>();
auto* sequence_manager_task = event->set_sequence_manager_task();
sequence_manager_task->set_priority(
TaskPriorityToProto(selected_task.priority));
settings().priority_settings.TaskPriorityToProto(selected_task.priority));
sequence_manager_task->set_queue_name(selected_task.task_queue_name);
#endif // BUILDFLAG(ENABLE_BASE_TRACING)
@ -1281,6 +1257,10 @@ internal::TaskQueueImpl* SequenceManagerImpl::currently_executing_task_queue()
return main_thread_only().task_execution_stack.rbegin()->task_queue;
}
TaskQueue::QueuePriority SequenceManagerImpl::GetPriorityCount() const {
return settings().priority_settings.priority_count();
}
constexpr TimeDelta SequenceManagerImpl::kReclaimMemoryInterval;
} // namespace internal

@ -113,10 +113,6 @@ class BASE_EXPORT SequenceManagerImpl
// according to its default state.
static void ResetNoWakeUpsForCanceledTasksForTesting();
static void MaybeEmitTaskDetails(
perfetto::EventContext& ctx,
const SequencedTaskSource::SelectedTask& selected_task);
// SequenceManager implementation:
void BindToCurrentThread() override;
scoped_refptr<SequencedTaskRunner> GetTaskRunnerForCurrentTask() override;
@ -145,6 +141,7 @@ class BASE_EXPORT SequenceManagerImpl
void AddTaskObserver(TaskObserver* task_observer) override;
void RemoveTaskObserver(TaskObserver* task_observer) override;
absl::optional<WakeUp> GetNextDelayedWakeUp() const override;
TaskQueue::QueuePriority GetPriorityCount() const override;
// SequencedTaskSource implementation:
absl::optional<SelectedTask> SelectNextTask(
@ -157,6 +154,9 @@ class BASE_EXPORT SequenceManagerImpl
SelectTaskOption option = SelectTaskOption::kDefault) const override;
bool HasPendingHighResolutionTasks() override;
bool OnSystemIdle() override;
void MaybeEmitTaskDetails(
perfetto::EventContext& ctx,
const SequencedTaskSource::SelectedTask& selected_task) const override;
void AddDestructionObserver(
CurrentThread::DestructionObserver* destruction_observer);

@ -94,6 +94,21 @@ enum class WakeUpType {
kAlign,
};
enum class TestQueuePriority : TaskQueue::QueuePriority {
kControlPriority = 0,
kHighestPriority = 1,
kVeryHighPriority = 2,
kHighPriority = 3,
kNormalPriority = 4,
kDefaultPriority = kNormalPriority,
kLowPriority = 5,
kBestEffortPriority = 6,
kQueuePriorityCount = 7,
kFirstQueuePriority = kControlPriority,
};
std::string ToString(RunnerType type) {
switch (type) {
case RunnerType::kMockTaskRunner:
@ -187,6 +202,9 @@ class FixtureWithMockTaskRunner final : public Fixture {
.SetMessagePumpType(MessagePumpType::DEFAULT)
.SetRandomisedSamplingEnabled(false)
.SetTickClock(mock_tick_clock())
.SetPrioritySettings(SequenceManager::PrioritySettings(
TestQueuePriority::kQueuePriorityCount,
TestQueuePriority::kDefaultPriority))
.Build())) {
// A null clock triggers some assertions.
AdvanceMockTickClock(Milliseconds(1));
@ -270,6 +288,9 @@ class FixtureWithMockMessagePump : public Fixture {
.SetMessagePumpType(MessagePumpType::DEFAULT)
.SetRandomisedSamplingEnabled(false)
.SetTickClock(mock_tick_clock())
.SetPrioritySettings(SequenceManager::PrioritySettings(
TestQueuePriority::kQueuePriorityCount,
TestQueuePriority::kDefaultPriority))
.Build();
auto thread_controller =
std::make_unique<ThreadControllerWithMessagePumpImpl>(std::move(pump),
@ -3604,10 +3625,10 @@ TEST_P(SequenceManagerTest, DelayedTasksNotSelectedWithImmediateTask) {
TEST_P(SequenceManagerTest,
DelayedTasksNotSelectedWithImmediateTaskWithPriority) {
auto queues = CreateTaskQueues(4u);
queues[0]->SetQueuePriority(TaskQueue::QueuePriority::kLowPriority);
queues[1]->SetQueuePriority(TaskQueue::QueuePriority::kNormalPriority);
queues[2]->SetQueuePriority(TaskQueue::QueuePriority::kHighPriority);
queues[3]->SetQueuePriority(TaskQueue::QueuePriority::kVeryHighPriority);
queues[0]->SetQueuePriority(TestQueuePriority::kLowPriority);
queues[1]->SetQueuePriority(TestQueuePriority::kNormalPriority);
queues[2]->SetQueuePriority(TestQueuePriority::kHighPriority);
queues[3]->SetQueuePriority(TestQueuePriority::kVeryHighPriority);
// Post immediate tasks.
queues[0]->task_runner()->PostTask(FROM_HERE, BindOnce(&NopTask));
@ -4572,7 +4593,7 @@ TEST_P(SequenceManagerTest, HasPendingHighResolutionTasks) {
TEST_P(SequenceManagerTest, HasPendingHighResolutionTasksLowPriority) {
auto queue = CreateTaskQueue();
queue->SetQueuePriority(TaskQueue::QueuePriority::kLowPriority);
queue->SetQueuePriority(TestQueuePriority::kLowPriority);
bool supports_high_res = false;
#if BUILDFLAG(IS_WIN)
supports_high_res = true;
@ -4590,10 +4611,10 @@ TEST_P(SequenceManagerTest, HasPendingHighResolutionTasksLowPriority) {
EXPECT_FALSE(sequence_manager()->HasPendingHighResolutionTasks());
// Increasing queue priority should enable high resolution timer.
queue->SetQueuePriority(TaskQueue::QueuePriority::kNormalPriority);
queue->SetQueuePriority(TestQueuePriority::kNormalPriority);
EXPECT_EQ(sequence_manager()->HasPendingHighResolutionTasks(),
supports_high_res);
queue->SetQueuePriority(TaskQueue::QueuePriority::kLowPriority);
queue->SetQueuePriority(TestQueuePriority::kLowPriority);
EXPECT_FALSE(sequence_manager()->HasPendingHighResolutionTasks());
// Running immediate tasks doesn't affect pending high resolution tasks.
@ -4614,9 +4635,9 @@ TEST_P(SequenceManagerTest, HasPendingHighResolutionTasksLowPriority) {
TEST_P(SequenceManagerTest,
HasPendingHighResolutionTasksLowAndNormalPriorityQueues) {
auto queueLow = CreateTaskQueue();
queueLow->SetQueuePriority(TaskQueue::QueuePriority::kLowPriority);
queueLow->SetQueuePriority(TestQueuePriority::kLowPriority);
auto queueNormal = CreateTaskQueue();
queueNormal->SetQueuePriority(TaskQueue::QueuePriority::kNormalPriority);
queueNormal->SetQueuePriority(TestQueuePriority::kNormalPriority);
bool supports_high_res = false;
#if BUILDFLAG(IS_WIN)
supports_high_res = true;
@ -4632,7 +4653,7 @@ TEST_P(SequenceManagerTest,
EXPECT_FALSE(sequence_manager()->HasPendingHighResolutionTasks());
// Increasing queue priority should enable high resolution timer.
queueLow->SetQueuePriority(TaskQueue::QueuePriority::kNormalPriority);
queueLow->SetQueuePriority(TestQueuePriority::kNormalPriority);
EXPECT_EQ(sequence_manager()->HasPendingHighResolutionTasks(),
supports_high_res);
}
@ -4978,11 +4999,13 @@ TEST_P(SequenceManagerTest, DescribeAllPendingTasks) {
}
TEST_P(SequenceManagerTest, TaskPriortyInterleaving) {
auto queues = CreateTaskQueues(TaskQueue::QueuePriority::kQueuePriorityCount);
auto queues = CreateTaskQueues(
static_cast<size_t>(TestQueuePriority::kQueuePriorityCount));
for (uint8_t priority = 0;
priority < TaskQueue::QueuePriority::kQueuePriorityCount; priority++) {
if (priority != TaskQueue::QueuePriority::kNormalPriority) {
priority < static_cast<uint8_t>(TestQueuePriority::kQueuePriorityCount);
priority++) {
if (priority != static_cast<uint8_t>(TestQueuePriority::kNormalPriority)) {
queues[priority]->SetQueuePriority(
static_cast<TaskQueue::QueuePriority>(priority));
}
@ -4991,7 +5014,9 @@ TEST_P(SequenceManagerTest, TaskPriortyInterleaving) {
std::string order;
for (int i = 0; i < 60; i++) {
for (uint8_t priority = 0;
priority < TaskQueue::QueuePriority::kQueuePriorityCount; priority++) {
priority <
static_cast<uint8_t>(TestQueuePriority::kQueuePriorityCount);
priority++) {
queues[priority]->task_runner()->PostTask(
FROM_HERE,
base::BindOnce([](std::string* str, char c) { str->push_back(c); },
@ -5329,8 +5354,8 @@ TEST_P(SequenceManagerTest,
sequence_manager()->AddTaskObserver(&observer);
queue->task_runner()->PostTask(FROM_HERE, DoNothing());
queue->SetQueuePriority(TaskQueue::QueuePriority::kLowPriority);
queue->SetQueuePriority(TaskQueue::QueuePriority::kNormalPriority);
queue->SetQueuePriority(TestQueuePriority::kLowPriority);
queue->SetQueuePriority(TestQueuePriority::kNormalPriority);
EXPECT_CALL(observer,
WillProcessTask(_, /*was_blocked_or_low_priority=*/true));
@ -5346,9 +5371,9 @@ TEST_P(SequenceManagerTest,
testing::StrictMock<MockTaskObserver> observer;
sequence_manager()->AddTaskObserver(&observer);
queue->SetQueuePriority(TaskQueue::QueuePriority::kLowPriority);
queue->SetQueuePriority(TestQueuePriority::kLowPriority);
queue->task_runner()->PostTask(FROM_HERE, DoNothing());
queue->SetQueuePriority(TaskQueue::QueuePriority::kNormalPriority);
queue->SetQueuePriority(TestQueuePriority::kNormalPriority);
EXPECT_CALL(observer,
WillProcessTask(_, /*was_blocked_or_low_priority=*/true));
@ -5365,7 +5390,7 @@ TEST_P(SequenceManagerTest,
sequence_manager()->AddTaskObserver(&observer);
queue->task_runner()->PostTask(FROM_HERE, DoNothing());
queue->SetQueuePriority(TaskQueue::QueuePriority::kLowPriority);
queue->SetQueuePriority(TestQueuePriority::kLowPriority);
EXPECT_CALL(observer,
WillProcessTask(_, /*was_blocked_or_low_priority=*/true));
@ -5381,14 +5406,14 @@ TEST_P(SequenceManagerTest,
testing::StrictMock<MockTaskObserver> observer;
sequence_manager()->AddTaskObserver(&observer);
queue->SetQueuePriority(TaskQueue::QueuePriority::kLowPriority);
queue->SetQueuePriority(TestQueuePriority::kLowPriority);
queue->task_runner()->PostTask(FROM_HERE, DoNothing());
queue->GetTaskQueueImpl()->InsertFence(
TaskQueue::InsertFencePosition::kBeginningOfTime);
queue->task_runner()->PostTask(FROM_HERE, DoNothing());
queue->GetTaskQueueImpl()->RemoveFence();
queue->task_runner()->PostTask(FROM_HERE, DoNothing());
queue->SetQueuePriority(TaskQueue::QueuePriority::kNormalPriority);
queue->SetQueuePriority(TestQueuePriority::kNormalPriority);
// Post a task while the queue is kNormalPriority and unblocked, but has a
// backlog of tasks that were blocked.
queue->task_runner()->PostTask(FROM_HERE, DoNothing());
@ -5410,7 +5435,7 @@ TEST_P(SequenceManagerTest, TaskObserverBlockedOrLowPriority_Mix) {
testing::StrictMock<MockTaskObserver> observer;
sequence_manager()->AddTaskObserver(&observer);
queue->SetQueuePriority(TaskQueue::QueuePriority::kLowPriority);
queue->SetQueuePriority(TestQueuePriority::kLowPriority);
queue->task_runner()->PostTask(FROM_HERE, DoNothing());
queue->GetTaskQueueImpl()->InsertFence(
TaskQueue::InsertFencePosition::kBeginningOfTime);
@ -5425,7 +5450,7 @@ TEST_P(SequenceManagerTest, TaskObserverBlockedOrLowPriority_Mix) {
RunLoop().RunUntilIdle();
testing::Mock::VerifyAndClear(&observer);
queue->SetQueuePriority(TaskQueue::QueuePriority::kNormalPriority);
queue->SetQueuePriority(TestQueuePriority::kNormalPriority);
queue->task_runner()->PostTask(FROM_HERE, DoNothing());
EXPECT_CALL(observer,
WillProcessTask(_, /*was_blocked_or_low_priority=*/false));

@ -83,6 +83,11 @@ class SequencedTaskSource {
// becomes available as a result of any processing done by this callback,
// return true to schedule a future DoWork.
virtual bool OnSystemIdle() = 0;
// Called prior to running `selected_task` to emit trace event data for it.
virtual void MaybeEmitTaskDetails(
perfetto::EventContext& ctx,
const SelectedTask& selected_task) const = 0;
};
} // namespace internal

@ -252,8 +252,12 @@ void TaskQueue::SetQueuePriority(TaskQueue::QueuePriority priority) {
TaskQueue::QueuePriority TaskQueue::GetQueuePriority() const {
DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker);
if (!impl_)
return TaskQueue::QueuePriority::kLowPriority;
// TODO(crbug.com/1413795): change this to DCHECK(impl_) since task queues
// should not be used after shutdown.
if (!impl_) {
DCHECK(sequence_manager_);
return sequence_manager_->settings().priority_settings.default_priority();
}
return impl_->GetQueuePriority();
}

@ -7,6 +7,7 @@
#include <cstdint>
#include <memory>
#include <type_traits>
#include "base/base_export.h"
#include "base/check.h"
@ -99,36 +100,22 @@ class BASE_EXPORT TaskQueue : public RefCountedThreadSafe<TaskQueue> {
// Shuts down the queue when there are no more tasks queued.
void ShutdownTaskQueueGracefully();
// Queues with higher priority are selected to run before queues of lower
// priority. Note that there is no starvation protection, i.e., a constant
// stream of high priority work can mean that tasks in lower priority queues
// won't get to run.
// TODO(scheduler-dev): Could we define a more clear list of priorities?
// See https://crbug.com/847858.
enum QueuePriority : uint8_t {
// Queues with control priority will run before any other queue, and will
// explicitly starve other queues. Typically this should only be used for
// private queues which perform control operations.
kControlPriority = 0,
// Queues with higher priority (smaller number) are selected to run before
// queues of lower priority. Note that there is no starvation protection,
// i.e., a constant stream of high priority work can mean that tasks in lower
// priority queues won't get to run.
using QueuePriority = uint8_t;
kHighestPriority = 1,
kVeryHighPriority = 2,
kHighPriority = 3,
kNormalPriority = 4, // Queues with normal priority are the default.
kLowPriority = 5,
// Queues with best effort priority will only be run if all other queues are
// empty.
kBestEffortPriority = 6,
// By default there is only a single priority. Sequences making use of
// priorities should parameterize the `SequenceManager` with the appropriate
// `SequenceManager::PrioritySettings`.
enum class DefaultQueuePriority : QueuePriority {
kNormalPriority = 0,
// Must be the last entry.
kQueuePriorityCount = 7,
kFirstQueuePriority = kControlPriority,
kQueuePriorityCount = 1,
};
// Can be called on any thread.
static const char* PriorityToString(QueuePriority priority);
// Options for constructing a TaskQueue.
struct Spec {
explicit Spec(QueueName name) : name(name) {}
@ -294,6 +281,15 @@ class BASE_EXPORT TaskQueue : public RefCountedThreadSafe<TaskQueue> {
// the thread this TaskQueue was created by.
void SetQueuePriority(QueuePriority priority);
// Same as above but with an enum value as the priority.
template <typename T, typename = typename std::enable_if_t<std::is_enum_v<T>>>
void SetQueuePriority(T priority) {
static_assert(std::is_same_v<std::underlying_type_t<T>, QueuePriority>,
"Enumerated priorites must have the same underlying type as "
"TaskQueue::QueuePriority");
SetQueuePriority(static_cast<QueuePriority>(priority));
}
// Returns the current queue priority.
QueuePriority GetQueuePriority() const;

@ -49,29 +49,6 @@ BASE_FEATURE(kSweepCancelledTasks,
} // namespace
// static
const char* TaskQueue::PriorityToString(TaskQueue::QueuePriority priority) {
switch (priority) {
case kControlPriority:
return "control";
case kHighestPriority:
return "highest";
case kVeryHighPriority:
return "very_high";
case kHighPriority:
return "high";
case kNormalPriority:
return "normal";
case kLowPriority:
return "low";
case kBestEffortPriority:
return "best_effort";
default:
NOTREACHED();
return nullptr;
}
}
namespace internal {
namespace {
@ -398,10 +375,12 @@ TimeDelta TaskQueueImpl::GetTaskDelayAdjustment(CurrentThread current_thread) {
// Add a per-priority delay to cross thread tasks. This can help diagnose
// scheduler induced flakiness by making things flake most of the time.
return sequence_manager_->settings()
.per_priority_cross_thread_task_delay[any_thread_.queue_set_index];
.priority_settings
.per_priority_cross_thread_task_delay()[any_thread_.queue_set_index];
} else {
return sequence_manager_->settings().per_priority_same_thread_task_delay
[main_thread_only().immediate_work_queue->work_queue_set_index()];
return sequence_manager_->settings()
.priority_settings.per_priority_same_thread_task_delay()
[main_thread_only().immediate_work_queue->work_queue_set_index()];
}
#else
// No delay adjustment.
@ -683,11 +662,10 @@ absl::optional<WakeUp> TaskQueueImpl::GetNextDesiredWakeUp() {
// High resolution is needed if the queue contains high resolution tasks and
// has a priority index <= kNormalPriority (precise execution time is
// unnecessary for a low priority queue).
WakeUpResolution resolution =
has_pending_high_resolution_tasks() &&
GetQueuePriority() <= TaskQueue::QueuePriority::kNormalPriority
? WakeUpResolution::kHigh
: WakeUpResolution::kLow;
WakeUpResolution resolution = has_pending_high_resolution_tasks() &&
GetQueuePriority() <= DefaultPriority()
? WakeUpResolution::kHigh
: WakeUpResolution::kLow;
const auto& top_task = main_thread_only().delayed_incoming_queue.top();
return WakeUp{top_task.delayed_run_time, top_task.leeway, resolution,
@ -810,16 +788,13 @@ void TaskQueueImpl::SetQueuePriority(TaskQueue::QueuePriority priority) {
UpdateWakeUp(&lazy_now);
#endif
static_assert(TaskQueue::QueuePriority::kLowPriority >
TaskQueue::QueuePriority::kNormalPriority,
"Priorities are not ordered as expected");
if (priority > TaskQueue::QueuePriority::kNormalPriority) {
// |priority| is now kLowPriority or less important so update accordingly.
if (priority > DefaultPriority()) {
// |priority| is now lower than the default, so update accordingly.
main_thread_only()
.enqueue_order_at_which_we_became_unblocked_with_normal_priority =
EnqueueOrder::max();
} else if (previous_priority > TaskQueue::QueuePriority::kNormalPriority) {
// |priority| is no longer kLowPriority or less important so record current
} else if (previous_priority > DefaultPriority()) {
// |priority| is no longer lower than the default, so record current
// sequence number.
DCHECK_EQ(
main_thread_only()
@ -908,7 +883,7 @@ Value::Dict TaskQueueImpl::AsValue(TimeTicks now, bool force_verbose) const {
state.Set("delayed_incoming_queue",
main_thread_only().delayed_incoming_queue.AsValue(now));
}
state.Set("priority", TaskQueue::PriorityToString(GetQueuePriority()));
state.Set("priority", GetQueuePriority());
return state;
}
@ -1534,12 +1509,8 @@ void TaskQueueImpl::OnQueueUnblocked() {
main_thread_only().enqueue_order_at_which_we_became_unblocked =
sequence_manager_->GetNextSequenceNumber();
static_assert(TaskQueue::QueuePriority::kLowPriority >
TaskQueue::QueuePriority::kNormalPriority,
"Priorities are not ordered as expected");
if (GetQueuePriority() <= TaskQueue::QueuePriority::kNormalPriority) {
// We are kNormalPriority or more important so update
if (GetQueuePriority() <= DefaultPriority()) {
// We are default priority or more important so update
// |enqueue_order_at_which_we_became_unblocked_with_normal_priority|.
main_thread_only()
.enqueue_order_at_which_we_became_unblocked_with_normal_priority =
@ -1634,6 +1605,10 @@ TaskQueueImpl::OnTaskPostedCallbackHandleImpl::
task_queue_impl_->RemoveOnTaskPostedHandler(this);
}
TaskQueue::QueuePriority TaskQueueImpl::DefaultPriority() const {
return sequence_manager()->settings().priority_settings.default_priority();
}
} // namespace internal
} // namespace sequence_manager
} // namespace base

@ -554,6 +554,8 @@ class BASE_EXPORT TaskQueueImpl {
void RemoveOnTaskPostedHandler(
OnTaskPostedCallbackHandleImpl* on_task_posted_callback_handle);
TaskQueue::QueuePriority DefaultPriority() const;
QueueName name_;
const raw_ptr<SequenceManagerImpl, DanglingUntriaged> sequence_manager_;

@ -26,16 +26,19 @@ TaskQueueSelector::TaskQueueSelector(
#if DCHECK_IS_ON()
random_task_selection_(settings.random_task_selection_seed != 0),
#endif
non_empty_set_counts_(
std::vector<int>(settings.priority_settings.priority_count(), 0)),
delayed_work_queue_sets_("delayed", this, settings),
immediate_work_queue_sets_("immediate", this, settings) {
}
TaskQueueSelector::~TaskQueueSelector() = default;
void TaskQueueSelector::AddQueue(internal::TaskQueueImpl* queue) {
void TaskQueueSelector::AddQueue(internal::TaskQueueImpl* queue,
TaskQueue::QueuePriority priority) {
DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker);
DCHECK(queue->IsQueueEnabled());
AddQueueImpl(queue, TaskQueue::kNormalPriority);
AddQueueImpl(queue, priority);
}
void TaskQueueSelector::RemoveQueue(internal::TaskQueueImpl* queue) {
@ -61,7 +64,7 @@ void TaskQueueSelector::DisableQueue(internal::TaskQueueImpl* queue) {
void TaskQueueSelector::SetQueuePriority(internal::TaskQueueImpl* queue,
TaskQueue::QueuePriority priority) {
DCHECK_LT(priority, TaskQueue::kQueuePriorityCount);
DCHECK_LT(priority, priority_count());
DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker);
if (queue->IsQueueEnabled()) {
ChangeSetIndex(queue, priority);
@ -74,12 +77,6 @@ void TaskQueueSelector::SetQueuePriority(internal::TaskQueueImpl* queue,
DCHECK_EQ(priority, queue->GetQueuePriority());
}
TaskQueue::QueuePriority TaskQueueSelector::NextPriority(
TaskQueue::QueuePriority priority) {
DCHECK(priority < TaskQueue::kQueuePriorityCount);
return static_cast<TaskQueue::QueuePriority>(static_cast<int>(priority) + 1);
}
void TaskQueueSelector::AddQueueImpl(internal::TaskQueueImpl* queue,
TaskQueue::QueuePriority priority) {
#if DCHECK_IS_ON()
@ -234,11 +231,11 @@ TaskQueueSelector::GetHighestPendingPriority(SelectTaskOption option) const {
TaskQueue::QueuePriority highest_priority =
active_priority_tracker_.HighestActivePriority();
DCHECK_LT(highest_priority, priority_count());
if (option != SelectTaskOption::kSkipDelayedTask)
return highest_priority;
for (; highest_priority != TaskQueue::kQueuePriorityCount;
highest_priority = NextPriority(highest_priority)) {
for (; highest_priority != priority_count(); ++highest_priority) {
if (active_priority_tracker_.IsActive(highest_priority) &&
!immediate_work_queue_sets_.IsSetEmpty(highest_priority)) {
return highest_priority;
@ -264,12 +261,12 @@ TaskQueueSelector::ActivePriorityTracker::ActivePriorityTracker() = default;
void TaskQueueSelector::ActivePriorityTracker::SetActive(
TaskQueue::QueuePriority priority,
bool is_active) {
DCHECK_LT(priority, TaskQueue::QueuePriority::kQueuePriorityCount);
DCHECK_LT(priority, SequenceManager::PrioritySettings::kMaxPriorities);
DCHECK_NE(IsActive(priority), is_active);
if (is_active) {
active_priorities_ |= (1u << static_cast<size_t>(priority));
active_priorities_ |= (size_t{1} << static_cast<size_t>(priority));
} else {
active_priorities_ &= ~(1u << static_cast<size_t>(priority));
active_priorities_ &= ~(size_t{1} << static_cast<size_t>(priority));
}
}

@ -41,7 +41,8 @@ class BASE_EXPORT TaskQueueSelector : public WorkQueueSets::Observer {
// Called to register a queue that can be selected. This function is called
// on the main thread.
void AddQueue(internal::TaskQueueImpl* queue);
void AddQueue(internal::TaskQueueImpl* queue,
TaskQueue::QueuePriority priority);
// The specified work will no longer be considered for selection. This
// function is called on the main thread.
@ -121,7 +122,7 @@ class BASE_EXPORT TaskQueueSelector : public WorkQueueSets::Observer {
bool HasActivePriority() const { return active_priorities_ != 0; }
bool IsActive(TaskQueue::QueuePriority priority) const {
return active_priorities_ & (1u << static_cast<size_t>(priority));
return active_priorities_ & (size_t{1} << static_cast<size_t>(priority));
}
void SetActive(TaskQueue::QueuePriority priority, bool is_active);
@ -129,7 +130,7 @@ class BASE_EXPORT TaskQueueSelector : public WorkQueueSets::Observer {
TaskQueue::QueuePriority HighestActivePriority() const;
private:
static_assert(TaskQueue::QueuePriority::kQueuePriorityCount <
static_assert(SequenceManager::PrioritySettings::kMaxPriorities <
sizeof(size_t) * 8,
"The number of priorities must be strictly less than the "
"number of bits of |active_priorities_|!");
@ -197,6 +198,8 @@ class BASE_EXPORT TaskQueueSelector : public WorkQueueSets::Observer {
}
private:
size_t priority_count() const { return non_empty_set_counts_.size(); }
void ChangeSetIndex(internal::TaskQueueImpl* queue,
TaskQueue::QueuePriority priority);
void AddQueueImpl(internal::TaskQueueImpl* queue,
@ -223,10 +226,6 @@ class BASE_EXPORT TaskQueueSelector : public WorkQueueSets::Observer {
return ChooseDelayedOnlyWithPriority<SetOperation>(priority);
}
// Returns the priority which is next after |priority|.
static TaskQueue::QueuePriority NextPriority(
TaskQueue::QueuePriority priority);
// Returns true if there are pending tasks with priority |priority|.
bool HasTasksWithPriority(TaskQueue::QueuePriority priority) const;
@ -238,7 +237,7 @@ class BASE_EXPORT TaskQueueSelector : public WorkQueueSets::Observer {
// Count of the number of sets (delayed or immediate) for each priority.
// Should only contain 0, 1 or 2.
std::array<int, TaskQueue::kQueuePriorityCount> non_empty_set_counts_ = {{0}};
std::vector<int> non_empty_set_counts_;
static constexpr const int kMaxNonEmptySetCount = 2;

@ -33,6 +33,18 @@ namespace internal {
// To avoid symbol collisions in jumbo builds.
namespace task_queue_selector_unittest {
namespace {
const TaskQueue::QueuePriority kHighestPriority = 0;
const TaskQueue::QueuePriority kHighPriority = 4;
const TaskQueue::QueuePriority kDefaultPriority = 5;
const TaskQueue::QueuePriority kPriorityCount = 10;
const size_t kTaskQueueCount = kPriorityCount;
// Tests assume high priority is higher than default priority, but nothing about
// their values.
static_assert(kHighPriority < kDefaultPriority);
} // namespace
class MockObserver : public TaskQueueSelector::Observer {
public:
MockObserver() = default;
@ -54,7 +66,13 @@ class TaskQueueSelectorForTest : public TaskQueueSelector {
explicit TaskQueueSelectorForTest(
scoped_refptr<AssociatedThreadId> associated_thread)
: TaskQueueSelector(associated_thread, SequenceManager::Settings()) {}
: TaskQueueSelector(
associated_thread,
SequenceManager::Settings::Builder()
.SetPrioritySettings(
SequenceManager::PrioritySettings(kPriorityCount,
kDefaultPriority))
.Build()) {}
};
class TaskQueueSelectorTest : public testing::Test {
@ -112,12 +130,11 @@ class TaskQueueSelectorTest : public testing::Test {
std::unique_ptr<TaskQueueImpl> task_queue =
std::make_unique<TaskQueueImpl>(nullptr, nullptr,
TaskQueue::Spec(QueueName::TEST_TQ));
selector_.AddQueue(task_queue.get());
selector_.AddQueue(task_queue.get(), kDefaultPriority);
task_queues_.push_back(std::move(task_queue));
}
for (size_t i = 0; i < kTaskQueueCount; i++) {
EXPECT_EQ(TaskQueue::kNormalPriority, task_queues_[i]->GetQueuePriority())
<< i;
EXPECT_EQ(kDefaultPriority, task_queues_[i]->GetQueuePriority()) << i;
queue_to_index_map_.insert(std::make_pair(task_queues_[i].get(), i));
}
}
@ -137,8 +154,6 @@ class TaskQueueSelectorTest : public testing::Test {
TaskQueue::Spec(QueueName::TEST_TQ));
}
const size_t kTaskQueueCount =
static_cast<size_t>(TaskQueue::QueuePriority::kQueuePriorityCount);
RepeatingClosure test_closure_;
scoped_refptr<AssociatedThreadId> associated_thread_;
TaskQueueSelectorForTest selector_;
@ -152,52 +167,35 @@ TEST_F(TaskQueueSelectorTest, TestDefaultPriority) {
EXPECT_THAT(PopTasksAndReturnQueueIndices(), ElementsAre(4, 3, 2, 1, 0));
}
TEST_F(TaskQueueSelectorTest, TestHighestPriority) {
size_t queue_order[] = {0, 1, 2, 3, 4};
PushTasks(queue_order, 5);
selector_.SetQueuePriority(task_queues_[2].get(),
TaskQueue::kHighestPriority);
EXPECT_THAT(PopTasksAndReturnQueueIndices(), ElementsAre(2, 0, 1, 3, 4));
TEST_F(TaskQueueSelectorTest, TestPriorities) {
for (size_t priority = 0; priority < kDefaultPriority; ++priority) {
size_t queue_order[] = {0, 1, 2, 3, 4};
PushTasks(queue_order, 5);
if (priority != kDefaultPriority) {
selector_.SetQueuePriority(task_queues_[2].get(), priority);
}
EXPECT_THAT(PopTasksAndReturnQueueIndices(), ElementsAre(2, 0, 1, 3, 4));
}
}
TEST_F(TaskQueueSelectorTest, TestHighPriority) {
size_t queue_order[] = {0, 1, 2, 3, 4};
PushTasks(queue_order, 5);
selector_.SetQueuePriority(task_queues_[2].get(),
TaskQueue::kHighestPriority);
selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::kHighPriority);
selector_.SetQueuePriority(task_queues_[0].get(), TaskQueue::kLowPriority);
EXPECT_THAT(PopTasksAndReturnQueueIndices(), ElementsAre(2, 1, 3, 4, 0));
}
TEST_F(TaskQueueSelectorTest, TestMultiplePriorities) {
size_t reverse_priority_order[kPriorityCount];
for (size_t priority = 0; priority < kPriorityCount; ++priority) {
reverse_priority_order[(kPriorityCount - 1) - priority] = priority;
}
TEST_F(TaskQueueSelectorTest, TestLowPriority) {
size_t queue_order[] = {0, 1, 2, 3, 4};
PushTasks(queue_order, 5);
selector_.SetQueuePriority(task_queues_[2].get(), TaskQueue::kLowPriority);
EXPECT_THAT(PopTasksAndReturnQueueIndices(), ElementsAre(0, 1, 3, 4, 2));
}
PushTasks(reverse_priority_order, kPriorityCount);
TEST_F(TaskQueueSelectorTest, TestBestEffortPriority) {
size_t queue_order[] = {0, 1, 2, 3, 4};
PushTasks(queue_order, 5);
selector_.SetQueuePriority(task_queues_[0].get(),
TaskQueue::kBestEffortPriority);
selector_.SetQueuePriority(task_queues_[2].get(), TaskQueue::kLowPriority);
selector_.SetQueuePriority(task_queues_[3].get(),
TaskQueue::kHighestPriority);
EXPECT_THAT(PopTasksAndReturnQueueIndices(), ElementsAre(3, 1, 4, 2, 0));
}
for (size_t i = 0; i < kPriorityCount; ++i) {
TaskQueue::QueuePriority priority = reverse_priority_order[i];
if (priority != kDefaultPriority) {
selector_.SetQueuePriority(task_queues_[i].get(), priority);
}
EXPECT_EQ(task_queues_[i]->GetQueuePriority(), priority);
}
TEST_F(TaskQueueSelectorTest, TestControlPriority) {
size_t queue_order[] = {0, 1, 2, 3, 4};
PushTasks(queue_order, 5);
selector_.SetQueuePriority(task_queues_[4].get(),
TaskQueue::kControlPriority);
EXPECT_EQ(TaskQueue::kControlPriority, task_queues_[4]->GetQueuePriority());
selector_.SetQueuePriority(task_queues_[2].get(),
TaskQueue::kHighestPriority);
EXPECT_EQ(TaskQueue::kHighestPriority, task_queues_[2]->GetQueuePriority());
EXPECT_THAT(PopTasksAndReturnQueueIndices(), ElementsAre(4, 2, 0, 1, 3));
EXPECT_THAT(PopTasksAndReturnQueueIndices(),
ElementsAre(9, 8, 7, 6, 5, 4, 3, 2, 1, 0));
}
TEST_F(TaskQueueSelectorTest, TestObserverWithEnabledQueue) {
@ -217,14 +215,12 @@ TEST_F(TaskQueueSelectorTest, TestObserverWithEnabledQueue) {
TEST_F(TaskQueueSelectorTest,
TestObserverWithSetQueuePriorityAndQueueAlreadyEnabled) {
selector_.SetQueuePriority(task_queues_[1].get(),
TaskQueue::kHighestPriority);
selector_.SetQueuePriority(task_queues_[1].get(), kHighPriority);
{
MockObserver mock_observer;
selector_.SetTaskQueueSelectorObserver(&mock_observer);
EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)).Times(0);
selector_.SetQueuePriority(task_queues_[1].get(),
TaskQueue::kNormalPriority);
selector_.SetQueuePriority(task_queues_[1].get(), kDefaultPriority);
// Clear observer before it goes out of scope.
selector_.SetTaskQueueSelectorObserver(nullptr);
@ -242,15 +238,14 @@ TEST_F(TaskQueueSelectorTest, TestDisableEnable) {
task_queues_[4]->SetQueueEnabled(false);
selector_.DisableQueue(task_queues_[4].get());
// Disabling a queue should not affect its priority.
EXPECT_EQ(TaskQueue::kNormalPriority, task_queues_[2]->GetQueuePriority());
EXPECT_EQ(TaskQueue::kNormalPriority, task_queues_[4]->GetQueuePriority());
EXPECT_EQ(kDefaultPriority, task_queues_[2]->GetQueuePriority());
EXPECT_EQ(kDefaultPriority, task_queues_[4]->GetQueuePriority());
EXPECT_THAT(PopTasksAndReturnQueueIndices(), ElementsAre(0, 1, 3));
EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)).Times(2);
task_queues_[2]->SetQueueEnabled(true);
selector_.EnableQueue(task_queues_[2].get());
selector_.SetQueuePriority(task_queues_[2].get(),
TaskQueue::kBestEffortPriority);
selector_.SetQueuePriority(task_queues_[2].get(), kPriorityCount - 1);
EXPECT_THAT(PopTasksAndReturnQueueIndices(), ElementsAre(2));
task_queues_[4]->SetQueueEnabled(true);
selector_.EnableQueue(task_queues_[4].get());
@ -265,8 +260,7 @@ TEST_F(TaskQueueSelectorTest, TestDisableChangePriorityThenEnable) {
EXPECT_TRUE(task_queues_[2]->immediate_work_queue()->Empty());
task_queues_[2]->SetQueueEnabled(false);
selector_.SetQueuePriority(task_queues_[2].get(),
TaskQueue::kHighestPriority);
selector_.SetQueuePriority(task_queues_[2].get(), kHighPriority);
size_t queue_order[] = {0, 1, 2, 3, 4};
PushTasks(queue_order, 5);
@ -275,7 +269,7 @@ TEST_F(TaskQueueSelectorTest, TestDisableChangePriorityThenEnable) {
EXPECT_FALSE(task_queues_[2]->immediate_work_queue()->Empty());
task_queues_[2]->SetQueueEnabled(true);
EXPECT_EQ(TaskQueue::kHighestPriority, task_queues_[2]->GetQueuePriority());
EXPECT_EQ(kHighPriority, task_queues_[2]->GetQueuePriority());
EXPECT_THAT(PopTasksAndReturnQueueIndices(), ElementsAre(2, 0, 1, 3, 4));
}
@ -362,14 +356,14 @@ TEST_F(TaskQueueSelectorTest, GetHighestPendingPriority) {
size_t queue_order[] = {0, 1};
PushTasks(queue_order, 2);
selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::kHighPriority);
selector_.SetQueuePriority(task_queues_[1].get(), kHighPriority);
EXPECT_EQ(TaskQueue::kHighPriority, *selector_.GetHighestPendingPriority());
EXPECT_EQ(kHighPriority, *selector_.GetHighestPendingPriority());
PopTasksAndReturnQueueIndices();
EXPECT_FALSE(selector_.GetHighestPendingPriority().has_value());
PushTasks(queue_order, 1);
EXPECT_EQ(TaskQueue::kNormalPriority, *selector_.GetHighestPendingPriority());
EXPECT_EQ(kDefaultPriority, *selector_.GetHighestPendingPriority());
PopTasksAndReturnQueueIndices();
EXPECT_FALSE(selector_.GetHighestPendingPriority().has_value());
}
@ -379,7 +373,7 @@ TEST_F(TaskQueueSelectorTest, ChooseWithPriority_Empty) {
nullptr,
selector_
.ChooseWithPriority<TaskQueueSelectorForTest::SetOperationOldest>(
TaskQueue::kNormalPriority));
kDefaultPriority));
}
TEST_F(TaskQueueSelectorTest, ChooseWithPriority_OnlyDelayed) {
@ -391,7 +385,7 @@ TEST_F(TaskQueueSelectorTest, ChooseWithPriority_OnlyDelayed) {
task_queues_[0]->delayed_work_queue(),
selector_
.ChooseWithPriority<TaskQueueSelectorForTest::SetOperationOldest>(
TaskQueue::kNormalPriority));
kDefaultPriority));
}
TEST_F(TaskQueueSelectorTest, ChooseWithPriority_OnlyImmediate) {
@ -403,7 +397,7 @@ TEST_F(TaskQueueSelectorTest, ChooseWithPriority_OnlyImmediate) {
task_queues_[0]->immediate_work_queue(),
selector_
.ChooseWithPriority<TaskQueueSelectorForTest::SetOperationOldest>(
TaskQueue::kNormalPriority));
kDefaultPriority));
}
TEST_F(TaskQueueSelectorTest,
@ -483,7 +477,7 @@ TEST_F(TaskQueueSelectorTest, TestObserverWithOneBlockedQueue) {
EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)).Times(1);
std::unique_ptr<TaskQueueImpl> task_queue(NewTaskQueueWithBlockReporting());
selector.AddQueue(task_queue.get());
selector.AddQueue(task_queue.get(), kDefaultPriority);
task_queue->SetQueueEnabled(false);
selector.DisableQueue(task_queue.get());
@ -507,15 +501,15 @@ TEST_F(TaskQueueSelectorTest, TestObserverWithTwoBlockedQueues) {
std::unique_ptr<TaskQueueImpl> task_queue(NewTaskQueueWithBlockReporting());
std::unique_ptr<TaskQueueImpl> task_queue2(NewTaskQueueWithBlockReporting());
selector.AddQueue(task_queue.get());
selector.AddQueue(task_queue2.get());
selector.AddQueue(task_queue.get(), kDefaultPriority);
selector.AddQueue(task_queue2.get(), kDefaultPriority);
task_queue->SetQueueEnabled(false);
task_queue2->SetQueueEnabled(false);
selector.DisableQueue(task_queue.get());
selector.DisableQueue(task_queue2.get());
selector.SetQueuePriority(task_queue2.get(), TaskQueue::kControlPriority);
selector.SetQueuePriority(task_queue2.get(), kHighestPriority);
Task task1(PostedTask(nullptr, test_closure_, FROM_HERE),
EnqueueOrder::FromIntForTesting(2),
@ -546,7 +540,7 @@ TEST_F(TaskQueueSelectorTest, TestObserverWithTwoBlockedQueues) {
TEST_F(TaskQueueSelectorTest, CollectSkippedOverLowerPriorityTasks) {
size_t queue_order[] = {0, 1, 2, 3, 2, 1, 0};
PushTasks(queue_order, 7);
selector_.SetQueuePriority(task_queues_[3].get(), TaskQueue::kHighPriority);
selector_.SetQueuePriority(task_queues_[3].get(), kHighPriority);
std::vector<const Task*> result;
selector_.CollectSkippedOverLowerPriorityTasks(
@ -593,7 +587,7 @@ TEST_P(ChooseWithPriorityTest, RoundRobinTest) {
WorkQueue* chosen_work_queue =
selector_
.ChooseWithPriority<TaskQueueSelectorForTest::SetOperationOldest>(
TaskQueue::kNormalPriority);
kDefaultPriority);
EXPECT_EQ(chosen_work_queue->task_queue(), task_queues_[0].get());
EXPECT_STREQ(chosen_work_queue->name(), GetParam().expected_work_queue_name);
}
@ -609,28 +603,24 @@ class ActivePriorityTrackerTest : public testing::Test {
TEST_F(ActivePriorityTrackerTest, SetPriorityActiveAndInactive) {
EXPECT_FALSE(active_priority_tracker_.HasActivePriority());
EXPECT_FALSE(active_priority_tracker_.IsActive(
TaskQueue::QueuePriority::kNormalPriority));
EXPECT_FALSE(active_priority_tracker_.IsActive(kDefaultPriority));
active_priority_tracker_.SetActive(TaskQueue::QueuePriority::kNormalPriority,
true);
active_priority_tracker_.SetActive(kDefaultPriority, true);
EXPECT_TRUE(active_priority_tracker_.HasActivePriority());
EXPECT_TRUE(active_priority_tracker_.IsActive(
TaskQueue::QueuePriority::kNormalPriority));
EXPECT_TRUE(active_priority_tracker_.IsActive(kDefaultPriority));
active_priority_tracker_.SetActive(TaskQueue::QueuePriority::kNormalPriority,
false);
active_priority_tracker_.SetActive(kDefaultPriority, false);
EXPECT_FALSE(active_priority_tracker_.HasActivePriority());
EXPECT_FALSE(active_priority_tracker_.IsActive(
TaskQueue::QueuePriority::kNormalPriority));
EXPECT_FALSE(active_priority_tracker_.IsActive(kDefaultPriority));
}
TEST_F(ActivePriorityTrackerTest, HighestActivePriority) {
EXPECT_FALSE(active_priority_tracker_.HasActivePriority());
for (size_t i = 0; i < TaskQueue::QueuePriority::kQueuePriorityCount; i++) {
for (size_t i = 0; i < SequenceManager::PrioritySettings::kMaxPriorities;
i++) {
TaskQueue::QueuePriority priority =
static_cast<TaskQueue::QueuePriority>(i);
EXPECT_FALSE(active_priority_tracker_.IsActive(priority));
@ -638,7 +628,8 @@ TEST_F(ActivePriorityTrackerTest, HighestActivePriority) {
EXPECT_TRUE(active_priority_tracker_.IsActive(priority));
}
for (size_t i = 0; i < TaskQueue::QueuePriority::kQueuePriorityCount; i++) {
for (size_t i = 0; i < SequenceManager::PrioritySettings::kMaxPriorities;
i++) {
EXPECT_TRUE(active_priority_tracker_.HasActivePriority());
TaskQueue::QueuePriority priority =
static_cast<TaskQueue::QueuePriority>(i);

@ -208,13 +208,14 @@ void ThreadControllerImpl::DoWork(WorkType work_type) {
// Note: all arguments after task are just passed to a TRACE_EVENT for
// logging so lambda captures are safe as lambda is executed inline.
SequencedTaskSource* source = sequence_;
task_annotator_.RunTask(
"ThreadControllerImpl::RunTask", *selected_task->task,
[&selected_task](perfetto::EventContext& ctx) {
[&selected_task, &source](perfetto::EventContext& ctx) {
if (selected_task->task_execution_trace_logger)
selected_task->task_execution_trace_logger.Run(
ctx, *selected_task->task);
SequenceManagerImpl::MaybeEmitTaskDetails(ctx, *selected_task);
source->MaybeEmitTaskDetails(ctx, *selected_task);
});
if (!weak_ptr)
return;

@ -486,14 +486,14 @@ WorkDetails ThreadControllerWithMessagePumpImpl::DoWorkImpl(
// Note: all arguments after task are just passed to a TRACE_EVENT for
// logging so lambda captures are safe as lambda is executed inline.
SequencedTaskSource* source = main_thread_only().task_source;
task_annotator_.RunTask(
"ThreadControllerImpl::RunTask", *selected_task->task,
[&selected_task](perfetto::EventContext& ctx) {
[&selected_task, &source](perfetto::EventContext& ctx) {
if (selected_task->task_execution_trace_logger)
selected_task->task_execution_trace_logger.Run(
ctx, *selected_task->task);
SequenceManagerImpl::MaybeEmitTaskDetails(ctx,
selected_task.value());
source->MaybeEmitTaskDetails(ctx, selected_task.value());
});
}

@ -138,7 +138,8 @@ class FakeSequencedTaskSource : public SequencedTaskSource {
running_stack_.push_back(std::move(tasks_.front()));
tasks_.pop();
return SelectedTask(running_stack_.back(), TaskExecutionTraceLogger(),
TaskQueue::QueuePriority::kNormalPriority,
static_cast<TaskQueue::QueuePriority>(
TaskQueue::DefaultQueuePriority::kNormalPriority),
QueueName::TEST_TQ);
}
@ -184,6 +185,9 @@ class FakeSequencedTaskSource : public SequencedTaskSource {
bool OnSystemIdle() override { return false; }
void MaybeEmitTaskDetails(perfetto::EventContext& ctx,
const SelectedTask& selected_task) const override {}
private:
raw_ptr<TickClock> clock_;
std::queue<Task> tasks_;

@ -478,19 +478,25 @@ TEST_F(WakeUpQueueTest, HighResolutionWakeUps) {
TEST_F(WakeUpQueueTest, SetNextWakeUpForQueueInThePast) {
constexpr auto kType = MessagePumpType::DEFAULT;
constexpr auto kDelay = Milliseconds(20);
constexpr TaskQueue::QueuePriority kHighestPriority = 0;
constexpr TaskQueue::QueuePriority kDefaultPriority = 1;
constexpr TaskQueue::QueuePriority kLowestPriority = 2;
constexpr TaskQueue::QueuePriority kPriorityCount = 3;
auto sequence_manager = sequence_manager::CreateUnboundSequenceManager(
SequenceManager::Settings::Builder()
.SetMessagePumpType(kType)
.SetTickClock(&tick_clock_)
.SetPrioritySettings(SequenceManager::PrioritySettings(
kPriorityCount, kDefaultPriority))
.Build());
sequence_manager->BindToMessagePump(MessagePump::Create(kType));
auto high_prio_queue =
sequence_manager->CreateTaskQueue(TaskQueue::Spec(QueueName::TEST_TQ));
high_prio_queue->SetQueuePriority(TaskQueue::kHighestPriority);
high_prio_queue->SetQueuePriority(kHighestPriority);
auto high_prio_runner = high_prio_queue->CreateTaskRunner(kTaskTypeNone);
auto low_prio_queue =
sequence_manager->CreateTaskQueue(TaskQueue::Spec(QueueName::TEST2_TQ));
low_prio_queue->SetQueuePriority(TaskQueue::kBestEffortPriority);
low_prio_queue->SetQueuePriority(kLowestPriority);
auto low_prio_runner = low_prio_queue->CreateTaskRunner(kTaskTypeNone);
sequence_manager->SetDefaultTaskRunner(high_prio_runner);
base::MockCallback<base::OnceCallback<void()>> task_1, task_2;

@ -17,6 +17,7 @@ WorkQueueSets::WorkQueueSets(const char* name,
Observer* observer,
const SequenceManager::Settings& settings)
: name_(name),
work_queue_heaps_(settings.priority_settings.priority_count()),
#if DCHECK_IS_ON()
last_rand_(settings.random_task_selection_seed),
#endif
@ -214,7 +215,7 @@ void WorkQueueSets::CollectSkippedOverLowerPriorityTasks(
selected_work_queue->GetFrontTaskOrder();
CHECK(task_order);
for (size_t priority = selected_work_queue->work_queue_set_index() + 1;
priority < TaskQueue::kQueuePriorityCount; priority++) {
priority < work_queue_heaps_.size(); priority++) {
for (const OldestTaskOrder& pair : work_queue_heaps_[priority]) {
pair.value->CollectTasksOlderThan(*task_order, result);
}

@ -5,7 +5,6 @@
#ifndef BASE_TASK_SEQUENCE_MANAGER_WORK_QUEUE_SETS_H_
#define BASE_TASK_SEQUENCE_MANAGER_WORK_QUEUE_SETS_H_
#include <array>
#include <functional>
#include <vector>
@ -123,9 +122,7 @@ class BASE_EXPORT WorkQueueSets {
// For each set |work_queue_heaps_| has a queue of WorkQueue ordered by the
// oldest task in each WorkQueue.
std::array<IntrusiveHeap<OldestTaskOrder, std::greater<>>,
TaskQueue::kQueuePriorityCount>
work_queue_heaps_;
std::vector<IntrusiveHeap<OldestTaskOrder, std::greater<>>> work_queue_heaps_;
#if DCHECK_IS_ON()
static inline uint64_t MurmurHash3(uint64_t value) {

@ -13,6 +13,7 @@
#include "base/task/sequence_manager/enqueue_order.h"
#include "base/task/sequence_manager/fence.h"
#include "base/task/sequence_manager/task_order.h"
#include "base/task/sequence_manager/task_queue.h"
#include "base/task/sequence_manager/work_queue.h"
#include "base/time/time.h"
#include "testing/gmock/include/gmock/gmock.h"
@ -32,13 +33,21 @@ class MockObserver : public WorkQueueSets::Observer {
MOCK_METHOD1(WorkQueueSetBecameNonEmpty, void(size_t set_index));
};
const TaskQueue::QueuePriority kHighestPriority = 0;
const TaskQueue::QueuePriority kDefaultPriority = 5;
const TaskQueue::QueuePriority kPriorityCount = 10;
} // namespace
class WorkQueueSetsTest : public testing::Test {
public:
void SetUp() override {
work_queue_sets_ = std::make_unique<WorkQueueSets>(
"test", &mock_observer_, SequenceManager::Settings());
"test", &mock_observer_,
SequenceManager::Settings::Builder()
.SetPrioritySettings(SequenceManager::PrioritySettings(
kPriorityCount, kDefaultPriority))
.Build());
}
void TearDown() override {
@ -54,7 +63,7 @@ class WorkQueueSetsTest : public testing::Test {
WorkQueue::QueueType queue_type = WorkQueue::QueueType::kImmediate) {
WorkQueue* queue = new WorkQueue(nullptr, "test", queue_type);
work_queues_.push_back(WrapUnique(queue));
work_queue_sets_->AddQueue(queue, TaskQueue::kControlPriority);
work_queue_sets_->AddQueue(queue, kHighestPriority);
return queue;
}
@ -97,21 +106,21 @@ class WorkQueueSetsTest : public testing::Test {
TEST_F(WorkQueueSetsTest, ChangeSetIndex) {
WorkQueue* work_queue = NewTaskQueue("queue");
size_t set = TaskQueue::kNormalPriority;
size_t set = kDefaultPriority;
work_queue_sets_->ChangeSetIndex(work_queue, set);
EXPECT_EQ(set, work_queue->work_queue_set_index());
}
TEST_F(WorkQueueSetsTest, GetOldestQueueAndTaskOrderInSet_QueueEmpty) {
WorkQueue* work_queue = NewTaskQueue("queue");
size_t set = TaskQueue::kNormalPriority;
size_t set = kDefaultPriority;
work_queue_sets_->ChangeSetIndex(work_queue, set);
EXPECT_FALSE(work_queue_sets_->GetOldestQueueAndTaskOrderInSet(set));
}
TEST_F(WorkQueueSetsTest, OnTaskPushedToEmptyQueue) {
WorkQueue* work_queue = NewTaskQueue("queue");
size_t set = TaskQueue::kNormalPriority;
size_t set = kDefaultPriority;
work_queue_sets_->ChangeSetIndex(work_queue, set);
EXPECT_FALSE(work_queue_sets_->GetOldestQueueAndTaskOrderInSet(set));
@ -338,7 +347,7 @@ TEST_F(WorkQueueSetsTest, BlockQueuesByFence) {
queue1->Push(FakeTaskWithEnqueueOrder(8));
queue2->Push(FakeTaskWithEnqueueOrder(9));
size_t set = TaskQueue::kControlPriority;
size_t set = kHighestPriority;
EXPECT_EQ(queue1, GetOldestQueueInSet(set));
@ -408,7 +417,7 @@ TEST_F(WorkQueueSetsTest, CompareDelayedTasksWithSameEnqueueOrder) {
/*sequence_num=*/2),
};
constexpr size_t kSet = TaskQueue::kNormalPriority;
constexpr size_t kSet = kDefaultPriority;
for (int i = 0; i < kNumQueues; i++) {
queues[i]->Push(FakeTaskWithTaskOrder(task_orders[i]));
@ -442,7 +451,7 @@ TEST_F(WorkQueueSetsTest, CompareDelayedTasksWithSameEnqueueOrderAndRunTime) {
/*sequence_num=*/4),
};
constexpr size_t kSet = TaskQueue::kNormalPriority;
constexpr size_t kSet = kDefaultPriority;
for (int i = 0; i < kNumQueues; i++) {
queues[i]->Push(FakeTaskWithTaskOrder(task_orders[i]));
@ -491,7 +500,7 @@ TEST_F(WorkQueueSetsTest, CompareDelayedAndImmediateTasks) {
/*sequence_num=*/2),
};
constexpr size_t kSet = TaskQueue::kNormalPriority;
constexpr size_t kSet = kDefaultPriority;
for (int i = kNumQueues - 1; i >= 0; i--) {
queues[i]->Push(FakeTaskWithTaskOrder(task_orders[i]));

@ -26,6 +26,7 @@
#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
#include "base/task/common/lazy_now.h"
#include "base/task/sequence_manager/sequence_manager.h"
#include "base/task/sequence_manager/sequence_manager_impl.h"
#include "base/task/sequence_manager/time_domain.h"
#include "base/task/simple_task_executor.h"
@ -88,12 +89,14 @@ base::MessagePumpType GetMessagePumpTypeForMainThreadType(
std::unique_ptr<sequence_manager::SequenceManager>
CreateSequenceManagerForMainThreadType(
TaskEnvironment::MainThreadType main_thread_type) {
TaskEnvironment::MainThreadType main_thread_type,
sequence_manager::SequenceManager::PrioritySettings priority_settings) {
auto type = GetMessagePumpTypeForMainThreadType(main_thread_type);
return sequence_manager::CreateSequenceManagerOnCurrentThreadWithPump(
MessagePump::Create(type),
base::sequence_manager::SequenceManager::Settings::Builder()
.SetMessagePumpType(type)
.SetPrioritySettings(std::move(priority_settings))
.Build());
}
@ -370,6 +373,7 @@ TaskEnvironment::MockTimeDomain*
TaskEnvironment::MockTimeDomain::current_mock_time_domain_ = nullptr;
TaskEnvironment::TaskEnvironment(
sequence_manager::SequenceManager::PrioritySettings priority_settings,
TimeSource time_source,
MainThreadType main_thread_type,
ThreadPoolExecutionMode thread_pool_execution_mode,
@ -383,7 +387,8 @@ TaskEnvironment::TaskEnvironment(
thread_pool_com_environment_(thread_pool_com_environment),
subclass_creates_default_taskrunner_(subclass_creates_default_taskrunner),
sequence_manager_(
CreateSequenceManagerForMainThreadType(main_thread_type)),
CreateSequenceManagerForMainThreadType(main_thread_type,
std::move(priority_settings))),
mock_time_domain_(
time_source != TimeSource::SYSTEM_TIME
? std::make_unique<TaskEnvironment::MockTimeDomain>(

@ -203,20 +203,9 @@ class TaskEnvironment {
trait_helpers::AreValidTraits<ValidTraits,
TaskEnvironmentTraits...>::value>>
NOINLINE explicit TaskEnvironment(TaskEnvironmentTraits... traits)
: TaskEnvironment(
trait_helpers::GetEnum<TimeSource, TimeSource::DEFAULT>(traits...),
trait_helpers::GetEnum<MainThreadType, MainThreadType::DEFAULT>(
traits...),
trait_helpers::GetEnum<ThreadPoolExecutionMode,
ThreadPoolExecutionMode::DEFAULT>(traits...),
trait_helpers::GetEnum<ThreadingMode, ThreadingMode::DEFAULT>(
traits...),
trait_helpers::GetEnum<ThreadPoolCOMEnvironment,
ThreadPoolCOMEnvironment::DEFAULT>(
traits...),
trait_helpers::HasTrait<SubclassCreatesDefaultTaskRunner,
TaskEnvironmentTraits...>(),
trait_helpers::NotATraitTag()) {}
: TaskEnvironment(sequence_manager::SequenceManager::PrioritySettings::
CreateDefault(),
traits...) {}
TaskEnvironment(const TaskEnvironment&) = delete;
TaskEnvironment& operator=(const TaskEnvironment&) = delete;
@ -389,7 +378,42 @@ class TaskEnvironment {
static constexpr int kNumForegroundThreadPoolThreads = 4;
protected:
explicit TaskEnvironment(TaskEnvironment&& other);
template <typename... TaskEnvironmentTraits,
class CheckArgumentsAreValid = std::enable_if_t<
trait_helpers::AreValidTraits<ValidTraits,
TaskEnvironmentTraits...>::value>>
NOINLINE static TaskEnvironment CreateTaskEnvironmentWithPriorities(
sequence_manager::SequenceManager::PrioritySettings priority_settings,
TaskEnvironmentTraits... traits) {
return TaskEnvironment(std::move(priority_settings), traits...);
}
// Constructor accepts zero or more traits which customize the testing
// environment.
template <typename... TaskEnvironmentTraits,
class CheckArgumentsAreValid = std::enable_if_t<
trait_helpers::AreValidTraits<ValidTraits,
TaskEnvironmentTraits...>::value>>
NOINLINE explicit TaskEnvironment(
sequence_manager::SequenceManager::PrioritySettings priority_settings,
TaskEnvironmentTraits... traits)
: TaskEnvironment(
std::move(priority_settings),
trait_helpers::GetEnum<TimeSource, TimeSource::DEFAULT>(traits...),
trait_helpers::GetEnum<MainThreadType, MainThreadType::DEFAULT>(
traits...),
trait_helpers::GetEnum<ThreadPoolExecutionMode,
ThreadPoolExecutionMode::DEFAULT>(traits...),
trait_helpers::GetEnum<ThreadingMode, ThreadingMode::DEFAULT>(
traits...),
trait_helpers::GetEnum<ThreadPoolCOMEnvironment,
ThreadPoolCOMEnvironment::DEFAULT>(
traits...),
trait_helpers::HasTrait<SubclassCreatesDefaultTaskRunner,
TaskEnvironmentTraits...>(),
trait_helpers::NotATraitTag()) {}
TaskEnvironment(TaskEnvironment&& other);
constexpr MainThreadType main_thread_type() const {
return main_thread_type_;
@ -423,13 +447,15 @@ class TaskEnvironment {
// The template constructor has to be in the header but it delegates to this
// constructor to initialize all other members out-of-line.
TaskEnvironment(TimeSource time_source,
MainThreadType main_thread_type,
ThreadPoolExecutionMode thread_pool_execution_mode,
ThreadingMode threading_mode,
ThreadPoolCOMEnvironment thread_pool_com_environment,
bool subclass_creates_default_taskrunner,
trait_helpers::NotATraitTag tag);
TaskEnvironment(
sequence_manager::SequenceManager::PrioritySettings priority_settings,
TimeSource time_source,
MainThreadType main_thread_type,
ThreadPoolExecutionMode thread_pool_execution_mode,
ThreadingMode threading_mode,
ThreadPoolCOMEnvironment thread_pool_com_environment,
bool subclass_creates_default_taskrunner,
trait_helpers::NotATraitTag tag);
const MainThreadType main_thread_type_;
const ThreadPoolExecutionMode thread_pool_execution_mode_;

@ -16,6 +16,13 @@ enum class TaskType : unsigned char {
kSource2 = 2,
};
enum class TaskPriority : base::sequence_manager::TaskQueue::QueuePriority {
kHighPriority = 0,
kNormalPriority = 1,
kNumPriorities = 2,
};
void Task(base::StringPiece tq, int task_number) {
if (tq == "A") {
LOG(INFO) << "TaskQueue(" << tq << "): " << task_number;
@ -35,13 +42,18 @@ int main() {
std::unique_ptr<base::MessagePump> pump =
base::MessagePump::Create(base::MessagePumpType::DEFAULT);
base::sequence_manager::SequenceManager::PrioritySettings priority_settings(
TaskPriority::kNumPriorities, TaskPriority::kNormalPriority);
// Create the main thread's SequenceManager; it will choose which of the two
// below TaskQueues will be served at each spin of the loop, based on their
// priority.
std::unique_ptr<base::sequence_manager::SequenceManager> sequence_manager =
base::sequence_manager::CreateSequenceManagerOnCurrentThreadWithPump(
std::move(pump),
base::sequence_manager::SequenceManager::Settings::Builder().Build());
base::sequence_manager::SequenceManager::Settings::Builder()
.SetPrioritySettings(std::move(priority_settings))
.Build());
// Create two TaskQueues that feed into the main thread's SequenceManager,
// each with a different priority to demonstrate that TaskQueue is the
@ -51,13 +63,11 @@ int main() {
scoped_refptr<base::sequence_manager::TaskQueue> tq_a =
sequence_manager->CreateTaskQueue(base::sequence_manager::TaskQueue::Spec(
base::sequence_manager::QueueName::TEST_TQ));
tq_a->SetQueuePriority(
base::sequence_manager::TaskQueue::QueuePriority::kNormalPriority);
tq_a->SetQueuePriority(TaskPriority::kNormalPriority);
scoped_refptr<base::sequence_manager::TaskQueue> tq_b =
sequence_manager->CreateTaskQueue(base::sequence_manager::TaskQueue::Spec(
base::sequence_manager::QueueName::TEST2_TQ));
tq_b->SetQueuePriority(
base::sequence_manager::TaskQueue::QueuePriority::kHighPriority);
tq_b->SetQueuePriority(TaskPriority::kHighPriority);
// Get TaskRunners for both TaskQueues.
scoped_refptr<base::SingleThreadTaskRunner> a_runner_1 =

@ -1896,6 +1896,8 @@ source_set("browser") {
"scheduler/browser_io_thread_delegate.h",
"scheduler/browser_task_executor.cc",
"scheduler/browser_task_executor.h",
"scheduler/browser_task_priority.cc",
"scheduler/browser_task_priority.h",
"scheduler/browser_task_queues.cc",
"scheduler/browser_task_queues.h",
"scheduler/browser_ui_thread_scheduler.cc",

@ -27,6 +27,7 @@
#include "content/browser/browser_thread_impl.h"
#include "content/browser/scheduler/browser_io_thread_delegate.h"
#include "content/browser/scheduler/browser_task_executor.h"
#include "content/browser/scheduler/browser_task_priority.h"
#include "content/browser/scheduler/browser_ui_thread_scheduler.h"
#include "content/public/browser/browser_task_traits.h"
#include "testing/gtest/include/gtest/gtest.h"
@ -41,8 +42,10 @@ using ::testing::Invoke;
class SequenceManagerThreadDelegate : public base::Thread::Delegate {
public:
SequenceManagerThreadDelegate() {
ui_sequence_manager_ =
base::sequence_manager::CreateUnboundSequenceManager();
ui_sequence_manager_ = base::sequence_manager::CreateUnboundSequenceManager(
base::sequence_manager::SequenceManager::Settings::Builder()
.SetPrioritySettings(internal::CreateBrowserTaskPrioritySettings())
.Build());
auto browser_ui_thread_scheduler =
BrowserUIThreadScheduler::CreateForTesting(ui_sequence_manager_.get());
@ -274,7 +277,9 @@ class BrowserThreadWithCustomSchedulerTest : public testing::Test {
: public base::test::TaskEnvironment {
public:
TaskEnvironmentWithCustomScheduler()
: base::test::TaskEnvironment(SubclassCreatesDefaultTaskRunner{}) {
: base::test::TaskEnvironment(
internal::CreateBrowserTaskPrioritySettings(),
SubclassCreatesDefaultTaskRunner{}) {
std::unique_ptr<BrowserUIThreadScheduler> browser_ui_thread_scheduler =
BrowserUIThreadScheduler::CreateForTesting(sequence_manager());
DeferredInitFromSubclass(

@ -13,6 +13,7 @@
#include "base/task/task_executor.h"
#include "base/task/task_observer.h"
#include "content/browser/scheduler/browser_task_executor.h"
#include "content/browser/scheduler/browser_task_priority.h"
#include "content/public/browser/browser_thread.h"
namespace content {
@ -57,6 +58,8 @@ BrowserIOThreadDelegate::BrowserIOThreadDelegate()
: owned_sequence_manager_(CreateUnboundSequenceManager(
SequenceManager::Settings::Builder()
.SetMessagePumpType(base::MessagePumpType::IO)
.SetPrioritySettings(
internal::CreateBrowserTaskPrioritySettings())
.Build())),
sequence_manager_(owned_sequence_manager_.get()) {
Init();

@ -18,6 +18,7 @@
#include "base/test/mock_callback.h"
#include "base/test/task_environment.h"
#include "content/browser/scheduler/browser_io_thread_delegate.h"
#include "content/browser/scheduler/browser_task_priority.h"
#include "content/browser/scheduler/browser_task_queues.h"
#include "content/browser/scheduler/browser_ui_thread_scheduler.h"
#include "content/public/browser/browser_task_traits.h"
@ -187,6 +188,7 @@ class BrowserTaskExecutorWithCustomSchedulerTest : public testing::Test {
public:
TaskEnvironmentWithCustomScheduler()
: base::test::TaskEnvironment(
internal::CreateBrowserTaskPrioritySettings(),
SubclassCreatesDefaultTaskRunner{},
base::test::TaskEnvironment::MainThreadType::UI,
base::test::TaskEnvironment::TimeSource::MOCK_TIME) {

@ -0,0 +1,56 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/scheduler/browser_task_priority.h"
#include "base/notreached.h"
#include "base/task/sequence_manager/sequence_manager.h"
#include "base/tracing/protos/chrome_track_event.pbzero.h"
namespace content::internal {
namespace {
using ProtoPriority = perfetto::protos::pbzero::SequenceManagerTask::Priority;
ProtoPriority ToProtoPriority(BrowserTaskPriority priority) {
switch (priority) {
case BrowserTaskPriority::kControlPriority:
return ProtoPriority::CONTROL_PRIORITY;
case BrowserTaskPriority::kHighestPriority:
return ProtoPriority::HIGHEST_PRIORITY;
case BrowserTaskPriority::kHighPriority:
return ProtoPriority::HIGH_PRIORITY;
case BrowserTaskPriority::kNormalPriority:
return ProtoPriority::NORMAL_PRIORITY;
case BrowserTaskPriority::kLowPriority:
return ProtoPriority::LOW_PRIORITY;
case BrowserTaskPriority::kBestEffortPriority:
return ProtoPriority::BEST_EFFORT_PRIORITY;
case BrowserTaskPriority::kPriorityCount:
NOTREACHED();
return ProtoPriority::UNKNOWN;
}
}
ProtoPriority TaskPriorityToProto(
base::sequence_manager::TaskQueue::QueuePriority priority) {
DCHECK_LT(static_cast<size_t>(priority),
static_cast<size_t>(BrowserTaskPriority::kPriorityCount));
return ToProtoPriority(static_cast<BrowserTaskPriority>(priority));
}
} // namespace
base::sequence_manager::SequenceManager::PrioritySettings
CreateBrowserTaskPrioritySettings() {
using base::sequence_manager::TaskQueue;
base::sequence_manager::SequenceManager::PrioritySettings settings(
BrowserTaskPriority::kPriorityCount,
BrowserTaskPriority::kDefaultPriority);
settings.SetProtoPriorityConverter(&TaskPriorityToProto);
return settings;
}
} // namespace content::internal

@ -0,0 +1,36 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_SCHEDULER_BROWSER_TASK_PRIORITY_H_
#define CONTENT_BROWSER_SCHEDULER_BROWSER_TASK_PRIORITY_H_
#include "base/task/sequence_manager/sequence_manager.h"
#include "base/task/sequence_manager/task_queue.h"
#include "content/common/content_export.h"
namespace content::internal {
// clang-format off
enum class BrowserTaskPriority
: base::sequence_manager::TaskQueue::QueuePriority {
// Priorities are in descending order.
kControlPriority = 0,
kHighestPriority = 1,
kHighPriority = 2,
kNormalPriority = 3,
kDefaultPriority = kNormalPriority,
kLowPriority = 4,
kBestEffortPriority = 5,
// Must be the last entry.
kPriorityCount = 6,
};
// clang-format on
base::sequence_manager::SequenceManager::PrioritySettings CONTENT_EXPORT
CreateBrowserTaskPrioritySettings();
} // namespace content::internal
#endif // CONTENT_BROWSER_SCHEDULER_BROWSER_TASK_PRIORITY_H_

@ -16,6 +16,7 @@
#include "base/task/sequence_manager/sequence_manager.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "content/browser/scheduler/browser_task_priority.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_features.h"
@ -28,7 +29,7 @@ BASE_FEATURE(kServiceWorkerStorageControlResponseUseHighPriority,
"ServiceWorkerStorageControlResponseUseHighPriority",
base::FEATURE_DISABLED_BY_DEFAULT);
using QueuePriority = ::base::sequence_manager::TaskQueue::QueuePriority;
using BrowserTaskPriority = ::content::internal::BrowserTaskPriority;
using QueueName = ::perfetto::protos::pbzero::SequenceManagerTask::QueueName;
using InsertFencePosition =
::base::sequence_manager::TaskQueue::InsertFencePosition;
@ -173,34 +174,34 @@ BrowserTaskQueues::BrowserTaskQueues(
queue_data_[static_cast<uint32_t>(QueueType::kDefault)].task_queue_;
GetBrowserTaskQueue(QueueType::kUserVisible)
->SetQueuePriority(QueuePriority::kLowPriority);
->SetQueuePriority(BrowserTaskPriority::kLowPriority);
// Best effort queue
GetBrowserTaskQueue(QueueType::kBestEffort)
->SetQueuePriority(QueuePriority::kBestEffortPriority);
->SetQueuePriority(BrowserTaskPriority::kBestEffortPriority);
// User Input queue
GetBrowserTaskQueue(QueueType::kUserInput)
->SetQueuePriority(QueuePriority::kHighestPriority);
->SetQueuePriority(BrowserTaskPriority::kHighestPriority);
GetBrowserTaskQueue(QueueType::kNavigationNetworkResponse)
->SetQueuePriority(QueuePriority::kHighPriority);
->SetQueuePriority(BrowserTaskPriority::kHighPriority);
GetBrowserTaskQueue(QueueType::kServiceWorkerStorageControlResponse)
->SetQueuePriority(QueuePriority::kHighestPriority);
->SetQueuePriority(BrowserTaskPriority::kHighestPriority);
// Control queue
control_queue_ =
sequence_manager->CreateTaskQueue(base::sequence_manager::TaskQueue::Spec(
GetControlTaskQueueName(thread_id)));
control_queue_->SetQueuePriority(QueuePriority::kControlPriority);
control_queue_->SetQueuePriority(BrowserTaskPriority::kControlPriority);
// Run all pending queue
run_all_pending_tasks_queue_ =
sequence_manager->CreateTaskQueue(base::sequence_manager::TaskQueue::Spec(
GetRunAllPendingTaskQueueName(thread_id)));
run_all_pending_tasks_queue_->SetQueuePriority(
QueuePriority::kBestEffortPriority);
BrowserTaskPriority::kBestEffortPriority);
handle_ = base::AdoptRef(new Handle(this));
}
@ -244,15 +245,17 @@ void BrowserTaskQueues::OnStartupComplete() {
}
// Update ServiceWorker task queue priority.
DCHECK_EQ(GetBrowserTaskQueue(QueueType::kServiceWorkerStorageControlResponse)
->GetQueuePriority(),
QueuePriority::kHighestPriority);
DCHECK_EQ(
static_cast<BrowserTaskPriority>(
GetBrowserTaskQueue(QueueType::kServiceWorkerStorageControlResponse)
->GetQueuePriority()),
BrowserTaskPriority::kHighestPriority);
GetBrowserTaskQueue(QueueType::kServiceWorkerStorageControlResponse)
->SetQueuePriority(
base::FeatureList::IsEnabled(
kServiceWorkerStorageControlResponseUseHighPriority)
? QueuePriority::kHighPriority
: QueuePriority::kNormalPriority);
? BrowserTaskPriority::kHighPriority
: BrowserTaskPriority::kNormalPriority);
}
void BrowserTaskQueues::EnableAllExceptBestEffortQueues() {

@ -15,6 +15,7 @@
#include "base/task/single_thread_task_runner.h"
#include "base/test/bind.h"
#include "base/test/mock_callback.h"
#include "content/browser/scheduler/browser_task_priority.h"
#include "content/public/browser/browser_thread.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@ -37,7 +38,11 @@ class BrowserTaskQueuesTest : public testing::Test {
protected:
BrowserTaskQueuesTest()
: sequence_manager_(CreateSequenceManagerOnCurrentThreadWithPump(
base::MessagePump::Create(base::MessagePumpType::DEFAULT))),
base::MessagePump::Create(base::MessagePumpType::DEFAULT),
base::sequence_manager::SequenceManager::Settings::Builder()
.SetPrioritySettings(
internal::CreateBrowserTaskPrioritySettings())
.Build())),
queues_(std::make_unique<BrowserTaskQueues>(BrowserThread::UI,
sequence_manager_.get())),
handle_(queues_->GetHandle()) {

@ -22,6 +22,7 @@
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "content/browser/scheduler/browser_task_priority.h"
#include "content/browser/scheduler/browser_task_queues.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_features.h"
@ -138,6 +139,8 @@ BrowserUIThreadScheduler::BrowserUIThreadScheduler()
base::sequence_manager::CreateUnboundSequenceManager(
base::sequence_manager::SequenceManager::Settings::Builder()
.SetMessagePumpType(base::MessagePumpType::UI)
.SetPrioritySettings(
internal::CreateBrowserTaskPrioritySettings())
.Build())),
task_queues_(BrowserThread::UI, owned_sequence_manager_.get()),
queue_data_(task_queues_.GetQueueData()),
@ -162,6 +165,8 @@ BrowserUIThreadScheduler::BrowserUIThreadScheduler(
void BrowserUIThreadScheduler::CommonSequenceManagerSetup(
base::sequence_manager::SequenceManager* sequence_manager) {
DCHECK_EQ(static_cast<size_t>(sequence_manager->GetPriorityCount()),
static_cast<size_t>(internal::BrowserTaskPriority::kPriorityCount));
sequence_manager->EnableCrashKeys("ui_scheduler_async_stack");
}

@ -20,6 +20,7 @@
#include "content/browser/browser_thread_impl.h"
#include "content/browser/scheduler/browser_io_thread_delegate.h"
#include "content/browser/scheduler/browser_task_executor.h"
#include "content/browser/scheduler/browser_task_priority.h"
#include "content/browser/scheduler/browser_ui_thread_scheduler.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
@ -116,6 +117,12 @@ void TestBrowserThread::Stop() {
real_thread_->Stop();
}
// static
base::sequence_manager::SequenceManager::PrioritySettings
BrowserTaskEnvironment::CreateBrowserTaskPrioritySettings() {
return internal::CreateBrowserTaskPrioritySettings();
}
BrowserTaskEnvironment::~BrowserTaskEnvironment() {
// This is required to ensure we run all remaining MessageLoop and
// ThreadPool tasks in an atomic step. This is a bit different than

@ -8,6 +8,7 @@
#include <memory>
#include "base/compiler_specific.h"
#include "base/task/sequence_manager/sequence_manager.h"
#include "base/test/task_environment.h"
#include "build/build_config.h"
@ -154,7 +155,8 @@ class BrowserTaskEnvironment : public base::test::TaskEnvironment {
TaskEnvironmentTraits...>::value>>
NOINLINE explicit BrowserTaskEnvironment(TaskEnvironmentTraits... traits)
: BrowserTaskEnvironment(
base::test::TaskEnvironment(
CreateTaskEnvironmentWithPriorities(
CreateBrowserTaskPrioritySettings(),
SubclassCreatesDefaultTaskRunner{},
base::trait_helpers::GetEnum<MainThreadType,
MainThreadType::UI>(traits...),
@ -174,6 +176,9 @@ class BrowserTaskEnvironment : public base::test::TaskEnvironment {
~BrowserTaskEnvironment() override;
private:
static base::sequence_manager::SequenceManager::PrioritySettings
CreateBrowserTaskPrioritySettings();
// The template constructor has to be in the header but it delegates to this
// constructor to initialize all other members out-of-line.
BrowserTaskEnvironment(base::test::TaskEnvironment&& scoped_task_environment,

@ -44,6 +44,8 @@ blink_platform_sources("scheduler") {
"common/simple_main_thread_scheduler.h",
"common/single_thread_idle_task_runner.cc",
"common/single_thread_idle_task_runner.h",
"common/task_priority.cc",
"common/task_priority.h",
"common/thread.cc",
"common/thread_cpu_throttler.cc",
"common/thread_load_tracker.cc",

@ -30,6 +30,7 @@ include_rules = [
"+base/run_loop.h",
"+base/sequence_checker.h",
"+base/task/single_thread_task_runner.h",
"+base/tracing_buildflags.h",
"+base/strings/string_number_conversions.h",
"+base/synchronization/atomic_flag.h",
"+base/synchronization/cancellation_flag.h",

@ -15,6 +15,7 @@
#include "base/time/time.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
#include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.h"
namespace blink {
@ -33,6 +34,7 @@ class AutoAdvancingVirtualTimeDomainTest : public testing::Test {
base::MessagePump::Create(base::MessagePumpType::DEFAULT),
base::sequence_manager::SequenceManager::Settings::Builder()
.SetMessagePumpType(base::MessagePumpType::DEFAULT)
.SetPrioritySettings(CreatePrioritySettings())
.Build());
scheduler_helper_ = std::make_unique<NonMainThreadSchedulerHelper>(
sequence_manager_.get(), nullptr, TaskType::kInternalTest);

@ -17,6 +17,7 @@
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/renderer/platform/scheduler/common/blink_scheduler_single_thread_task_runner.h"
#include "third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
namespace blink {
namespace scheduler {
@ -57,7 +58,7 @@ IdleHelper::IdleHelper(
// This fence will block any idle tasks from running.
idle_queue_->InsertFence(TaskQueue::InsertFencePosition::kBeginningOfTime);
idle_queue_->SetQueuePriority(TaskQueue::kBestEffortPriority);
idle_queue_->SetQueuePriority(TaskPriority::kBestEffortPriority);
}
IdleHelper::~IdleHelper() {

@ -187,8 +187,12 @@ class BaseIdleHelperTest : public testing::Test {
base::TimeDelta required_quiescence_duration_before_long_idle_period)
: test_task_runner_(base::MakeRefCounted<base::TestMockTimeTaskRunner>(
base::TestMockTimeTaskRunner::Type::kStandalone)) {
auto settings = base::sequence_manager::SequenceManager::Settings::Builder()
.SetPrioritySettings(CreatePrioritySettings())
.Build();
sequence_manager_ = base::sequence_manager::SequenceManagerForTest::Create(
nullptr, test_task_runner_, test_task_runner_->GetMockTickClock());
nullptr, test_task_runner_, test_task_runner_->GetMockTickClock(),
std::move(settings));
scheduler_helper_ = std::make_unique<NonMainThreadSchedulerHelper>(
sequence_manager_.get(), nullptr, TaskType::kInternalTest);
scheduler_helper_->AttachToCurrentThread();

@ -14,6 +14,7 @@
#include "base/test/task_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
#include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
@ -53,9 +54,12 @@ class SchedulerHelperTest : public testing::Test {
: task_environment_(
base::test::TaskEnvironment::TimeSource::MOCK_TIME,
base::test::TaskEnvironment::ThreadPoolExecutionMode::QUEUED) {
auto settings = base::sequence_manager::SequenceManager::Settings::Builder()
.SetPrioritySettings(CreatePrioritySettings())
.Build();
sequence_manager_ = base::sequence_manager::SequenceManagerForTest::Create(
nullptr, task_environment_.GetMainThreadTaskRunner(),
task_environment_.GetMockTickClock());
task_environment_.GetMockTickClock(), std::move(settings));
scheduler_helper_ = std::make_unique<NonMainThreadSchedulerHelper>(
sequence_manager_.get(), nullptr, TaskType::kInternalTest);
scheduler_helper_->AttachToCurrentThread();

@ -0,0 +1,80 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
#include "base/task/sequence_manager/sequence_manager.h"
#include "base/task/sequence_manager/task_queue.h"
#include "base/tracing/protos/chrome_track_event.pbzero.h"
namespace blink::scheduler {
namespace {
using ProtoPriority = perfetto::protos::pbzero::SequenceManagerTask::Priority;
ProtoPriority ToProtoPriority(TaskPriority priority) {
switch (priority) {
case TaskPriority::kControlPriority:
return ProtoPriority::CONTROL_PRIORITY;
case TaskPriority::kHighestPriority:
return ProtoPriority::HIGHEST_PRIORITY;
case TaskPriority::kVeryHighPriority:
return ProtoPriority::VERY_HIGH_PRIORITY;
case TaskPriority::kHighPriority:
return ProtoPriority::HIGH_PRIORITY;
case TaskPriority::kNormalPriority:
return ProtoPriority::NORMAL_PRIORITY;
case TaskPriority::kLowPriority:
return ProtoPriority::LOW_PRIORITY;
case TaskPriority::kBestEffortPriority:
return ProtoPriority::BEST_EFFORT_PRIORITY;
case TaskPriority::kPriorityCount:
return ProtoPriority::UNKNOWN;
}
}
ProtoPriority TaskPriorityToProto(
base::sequence_manager::TaskQueue::QueuePriority priority) {
DCHECK_LT(static_cast<size_t>(priority),
static_cast<size_t>(TaskPriority::kPriorityCount));
return ToProtoPriority(static_cast<TaskPriority>(priority));
}
} // namespace
base::sequence_manager::SequenceManager::PrioritySettings
CreatePrioritySettings() {
using base::sequence_manager::TaskQueue;
base::sequence_manager::SequenceManager::PrioritySettings settings(
TaskPriority::kPriorityCount, TaskPriority::kDefaultPriority);
#if BUILDFLAG(ENABLE_BASE_TRACING)
settings.SetProtoPriorityConverter(&TaskPriorityToProto);
#endif
return settings;
}
const char* TaskPriorityToString(TaskPriority priority) {
switch (priority) {
case TaskPriority::kControlPriority:
return "control";
case TaskPriority::kHighestPriority:
return "highest";
case TaskPriority::kVeryHighPriority:
return "very_high";
case TaskPriority::kHighPriority:
return "high";
case TaskPriority::kNormalPriority:
return "normal";
case TaskPriority::kLowPriority:
return "low";
case TaskPriority::kBestEffortPriority:
return "best_effort";
case TaskPriority::kPriorityCount:
NOTREACHED();
return nullptr;
}
}
} // namespace blink::scheduler

@ -0,0 +1,36 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_COMMON_TASK_PRIORITY_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_COMMON_TASK_PRIORITY_H_
#include "base/task/sequence_manager/sequence_manager.h"
#include "base/task/sequence_manager/task_queue.h"
#include "third_party/blink/renderer/platform/platform_export.h"
namespace blink::scheduler {
enum class TaskPriority : base::sequence_manager::TaskQueue::QueuePriority {
// Priorities are in descending order.
kControlPriority = 0,
kHighestPriority = 1,
kVeryHighPriority = 2,
kHighPriority = 3,
kNormalPriority = 4,
kDefaultPriority = kNormalPriority,
kLowPriority = 5,
kBestEffortPriority = 6,
// Must be the last entry.
kPriorityCount = 7,
};
base::sequence_manager::SequenceManager::PrioritySettings PLATFORM_EXPORT
CreatePrioritySettings();
const char* TaskPriorityToString(TaskPriority);
} // namespace blink::scheduler
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_COMMON_TASK_PRIORITY_H_

@ -13,6 +13,7 @@
#include "build/build_config.h"
#include "third_party/blink/public/common/input/web_input_event_attribution.h"
#include "third_party/blink/renderer/platform/scheduler/common/features.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
#include "third_party/blink/renderer/platform/scheduler/common/tracing_helper.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/public/main_thread.h"
@ -26,12 +27,12 @@ WebThreadScheduler::~WebThreadScheduler() = default;
std::unique_ptr<WebThreadScheduler>
WebThreadScheduler::CreateMainThreadScheduler(
std::unique_ptr<base::MessagePump> message_pump) {
auto settings =
base::sequence_manager::SequenceManager::Settings::Builder()
.SetMessagePumpType(base::MessagePumpType::DEFAULT)
.SetRandomisedSamplingEnabled(true)
.SetAddQueueTimeToTasks(true)
.Build();
auto settings = base::sequence_manager::SequenceManager::Settings::Builder()
.SetMessagePumpType(base::MessagePumpType::DEFAULT)
.SetRandomisedSamplingEnabled(true)
.SetAddQueueTimeToTasks(true)
.SetPrioritySettings(CreatePrioritySettings())
.Build();
auto sequence_manager =
message_pump
? base::sequence_manager::

@ -7,6 +7,7 @@
#include <memory>
#include "third_party/blink/renderer/platform/scheduler/common/features.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.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"
@ -22,9 +23,9 @@ constexpr base::TimeDelta kFindInPageMaxBudget = base::Seconds(1);
const double kFindInPageBudgetRecoveryRate = 0.25;
} // namespace
const QueuePriority
const TaskPriority
FindInPageBudgetPoolController::kFindInPageBudgetNotExhaustedPriority;
const QueuePriority
const TaskPriority
FindInPageBudgetPoolController::kFindInPageBudgetExhaustedPriority;
FindInPageBudgetPoolController::FindInPageBudgetPoolController(
@ -33,7 +34,7 @@ FindInPageBudgetPoolController::FindInPageBudgetPoolController(
best_effort_budget_experiment_enabled_(
base::FeatureList::IsEnabled(kBestEffortPriorityForFindInPage)) {
if (best_effort_budget_experiment_enabled_) {
task_priority_ = QueuePriority::kBestEffortPriority;
task_priority_ = TaskPriority::kBestEffortPriority;
} else {
task_priority_ = kFindInPageBudgetNotExhaustedPriority;
}
@ -62,9 +63,9 @@ void FindInPageBudgetPoolController::OnTaskCompleted(
bool is_exhausted =
!find_in_page_budget_pool_->CanRunTasksAt(task_timing->end_time());
QueuePriority task_priority = is_exhausted
? kFindInPageBudgetExhaustedPriority
: kFindInPageBudgetNotExhaustedPriority;
TaskPriority task_priority = is_exhausted
? kFindInPageBudgetExhaustedPriority
: kFindInPageBudgetNotExhaustedPriority;
if (task_priority != task_priority_) {
task_priority_ = task_priority;

@ -7,6 +7,7 @@
#include "base/task/sequence_manager/task_queue.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
#include "third_party/blink/renderer/platform/scheduler/common/throttling/cpu_time_budget_pool.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h"
@ -14,7 +15,6 @@ namespace blink {
namespace scheduler {
using TaskQueue = base::sequence_manager::TaskQueue;
using QueuePriority = base::sequence_manager::TaskQueue::QueuePriority;
class CPUTimeBudgetPool;
class MainThreadSchedulerImpl;
@ -22,9 +22,9 @@ class MainThreadSchedulerImpl;
class PLATFORM_EXPORT FindInPageBudgetPoolController {
public:
static constexpr auto kFindInPageBudgetNotExhaustedPriority =
QueuePriority::kVeryHighPriority;
TaskPriority::kVeryHighPriority;
static constexpr auto kFindInPageBudgetExhaustedPriority =
QueuePriority::kNormalPriority;
TaskPriority::kNormalPriority;
explicit FindInPageBudgetPoolController(MainThreadSchedulerImpl* scheduler);
~FindInPageBudgetPoolController();
@ -32,12 +32,12 @@ class PLATFORM_EXPORT FindInPageBudgetPoolController {
void OnTaskCompleted(MainThreadTaskQueue* queue,
TaskQueue::TaskTiming* task_timing);
QueuePriority CurrentTaskPriority() { return task_priority_; }
TaskPriority CurrentTaskPriority() { return task_priority_; }
private:
MainThreadSchedulerImpl* scheduler_; // Not owned.
std::unique_ptr<CPUTimeBudgetPool> find_in_page_budget_pool_;
QueuePriority task_priority_;
TaskPriority task_priority_;
const bool best_effort_budget_experiment_enabled_;
};

@ -24,6 +24,7 @@
#include "third_party/blink/renderer/platform/back_forward_cache_utils.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/task_priority.h"
#include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h"
#include "third_party/blink/renderer/platform/scheduler/common/tracing_helper.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/find_in_page_budget_pool_controller.h"
@ -867,7 +868,7 @@ bool FrameSchedulerImpl::IsExemptFromBudgetBasedThrottling() const {
return opted_out_from_aggressive_throttling();
}
TaskQueue::QueuePriority FrameSchedulerImpl::ComputePriority(
TaskPriority FrameSchedulerImpl::ComputePriority(
MainThreadTaskQueue* task_queue) const {
DCHECK(task_queue);
@ -882,15 +883,15 @@ TaskQueue::QueuePriority FrameSchedulerImpl::ComputePriority(
switch (task_queue->GetPrioritisationType()) {
case MainThreadTaskQueue::QueueTraits::PrioritisationType::
kInternalScriptContinuation:
return TaskQueue::QueuePriority::kVeryHighPriority;
return TaskPriority::kVeryHighPriority;
case MainThreadTaskQueue::QueueTraits::PrioritisationType::kBestEffort:
return TaskQueue::QueuePriority::kBestEffortPriority;
return TaskPriority::kBestEffortPriority;
case MainThreadTaskQueue::QueueTraits::PrioritisationType::
kPostMessageForwarding:
return TaskQueue::QueuePriority::kVeryHighPriority;
return TaskPriority::kVeryHighPriority;
case MainThreadTaskQueue::QueueTraits::PrioritisationType::
kInternalNavigationCancellation:
return TaskQueue::QueuePriority::kVeryHighPriority;
return TaskPriority::kVeryHighPriority;
default:
break;
}
@ -901,37 +902,37 @@ TaskQueue::QueuePriority FrameSchedulerImpl::ComputePriority(
if (task_queue->web_scheduling_priority()) {
switch (task_queue->web_scheduling_priority().value()) {
case WebSchedulingPriority::kUserBlockingPriority:
return TaskQueue::QueuePriority::kHighPriority;
return TaskPriority::kHighPriority;
case WebSchedulingPriority::kUserVisiblePriority:
return TaskQueue::QueuePriority::kNormalPriority;
return TaskPriority::kNormalPriority;
case WebSchedulingPriority::kBackgroundPriority:
return TaskQueue::QueuePriority::kLowPriority;
return TaskPriority::kLowPriority;
}
}
if (!parent_page_scheduler_) {
// Frame might be detached during its shutdown. Return a default priority
// in that case.
return TaskQueue::QueuePriority::kNormalPriority;
return TaskPriority::kNormalPriority;
}
// A hidden page with no audio.
if (parent_page_scheduler_->IsBackgrounded()) {
if (main_thread_scheduler_->scheduling_settings()
.low_priority_background_page) {
return TaskQueue::QueuePriority::kLowPriority;
return TaskPriority::kLowPriority;
}
if (main_thread_scheduler_->scheduling_settings()
.best_effort_background_page) {
return TaskQueue::QueuePriority::kBestEffortPriority;
return TaskPriority::kBestEffortPriority;
}
}
// Low priority feature enabled for hidden frame.
if (main_thread_scheduler_->scheduling_settings().low_priority_hidden_frame &&
!IsFrameVisible()) {
return TaskQueue::QueuePriority::kLowPriority;
return TaskPriority::kLowPriority;
}
bool is_subframe = GetFrameType() == FrameScheduler::FrameType::kSubframe;
@ -942,44 +943,44 @@ TaskQueue::QueuePriority FrameSchedulerImpl::ComputePriority(
// Low priority feature enabled for sub-frame.
if (main_thread_scheduler_->scheduling_settings().low_priority_subframe &&
is_subframe) {
return TaskQueue::QueuePriority::kLowPriority;
return TaskPriority::kLowPriority;
}
// Low priority feature enabled for sub-frame throttleable task queues.
if (main_thread_scheduler_->scheduling_settings()
.low_priority_subframe_throttleable &&
is_subframe && is_throttleable_task_queue) {
return TaskQueue::QueuePriority::kLowPriority;
return TaskPriority::kLowPriority;
}
// Low priority feature enabled for throttleable task queues.
if (main_thread_scheduler_->scheduling_settings().low_priority_throttleable &&
is_throttleable_task_queue) {
return TaskQueue::QueuePriority::kLowPriority;
return TaskPriority::kLowPriority;
}
// Ad frame experiment.
if (IsAdFrame()) {
if (main_thread_scheduler_->scheduling_settings().low_priority_ad_frame) {
return TaskQueue::QueuePriority::kLowPriority;
return TaskPriority::kLowPriority;
}
if (main_thread_scheduler_->scheduling_settings().best_effort_ad_frame) {
return TaskQueue::QueuePriority::kBestEffortPriority;
return TaskPriority::kBestEffortPriority;
}
}
// Frame origin type experiment.
if (IsCrossOriginToNearestMainFrame() &&
main_thread_scheduler_->scheduling_settings().low_priority_cross_origin) {
return TaskQueue::QueuePriority::kLowPriority;
return TaskPriority::kLowPriority;
}
if (task_queue->GetPrioritisationType() ==
MainThreadTaskQueue::QueueTraits::PrioritisationType::kLoadingControl) {
return main_thread_scheduler_->should_prioritize_loading_with_compositing()
? TaskQueue::QueuePriority::kVeryHighPriority
: TaskQueue::QueuePriority::kHighPriority;
? TaskPriority::kVeryHighPriority
: TaskPriority::kHighPriority;
}
if (task_queue->GetPrioritisationType() ==
@ -996,14 +997,14 @@ TaskQueue::QueuePriority FrameSchedulerImpl::ComputePriority(
if (task_queue->GetPrioritisationType() ==
MainThreadTaskQueue::QueueTraits::PrioritisationType::
kHighPriorityLocalFrame) {
return TaskQueue::QueuePriority::kHighestPriority;
return TaskPriority::kHighestPriority;
}
if (task_queue->GetPrioritisationType() ==
MainThreadTaskQueue::QueueTraits::PrioritisationType::kInput &&
base::FeatureList::IsEnabled(
::blink::features::kInputTargetClientHighPriority)) {
return TaskQueue::QueuePriority::kHighestPriority;
return TaskPriority::kHighestPriority;
}
if (task_queue->GetPrioritisationType() ==
@ -1012,11 +1013,11 @@ TaskQueue::QueuePriority FrameSchedulerImpl::ComputePriority(
// TODO(shaseley): This decision should probably be based on Agent
// visibility. Consider changing this before shipping anything.
return parent_page_scheduler_->IsPageVisible()
? TaskQueue::QueuePriority::kHighPriority
: TaskQueue::QueuePriority::kNormalPriority;
? TaskPriority::kHighPriority
: TaskPriority::kNormalPriority;
}
return TaskQueue::QueuePriority::kNormalPriority;
return TaskPriority::kNormalPriority;
}
std::unique_ptr<blink::mojom::blink::PauseSubresourceLoadingHandle>

@ -22,6 +22,7 @@
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scheduler/common/back_forward_cache_disabling_feature_tracker.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
#include "third_party/blink/renderer/platform/scheduler/common/tracing_helper.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_origin_type.h"
@ -165,8 +166,7 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
// Computes the priority of |task_queue| if it is associated to this frame
// scheduler. Note that the main thread's policy should be upto date to
// compute the correct priority.
base::sequence_manager::TaskQueue::QueuePriority ComputePriority(
MainThreadTaskQueue* task_queue) const;
TaskPriority ComputePriority(MainThreadTaskQueue* task_queue) const;
ukm::SourceId GetUkmSourceId() override;
ukm::UkmRecorder* GetUkmRecorder();
@ -328,9 +328,7 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
BackForwardCacheDisablingFeatureTracker
back_forward_cache_disabling_feature_tracker_;
base::sequence_manager::TaskQueue::QueuePriority
default_loading_task_priority_ =
base::sequence_manager::TaskQueue::QueuePriority::kNormalPriority;
TaskPriority default_loading_task_priority_ = TaskPriority::kNormalPriority;
// These are the states of the Page.
// They should be accessed via GetPageScheduler()->SetPageState().

@ -34,6 +34,7 @@
#include "third_party/blink/public/platform/scheduler/web_agent_group_scheduler.h"
#include "third_party/blink/public/platform/web_runtime_features.h"
#include "third_party/blink/renderer/platform/scheduler/common/features.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.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_task_queue.h"
@ -234,7 +235,10 @@ class FrameSchedulerImplTest : public testing::Test {
scheduler_ = std::make_unique<MainThreadSchedulerImpl>(
base::sequence_manager::SequenceManagerForTest::Create(
nullptr, task_environment_.GetMainThreadTaskRunner(),
task_environment_.GetMockTickClock()));
task_environment_.GetMockTickClock(),
base::sequence_manager::SequenceManager::Settings::Builder()
.SetPrioritySettings(CreatePrioritySettings())
.Build()));
agent_group_scheduler_ = scheduler_->CreateAgentGroupScheduler();
page_scheduler_ =
CreatePageScheduler(nullptr, scheduler_.get(), *agent_group_scheduler_);
@ -1414,19 +1418,19 @@ TEST_F(InputHighPriorityFrameSchedulerImplTest,
NormalPriorityInputBlockingTaskQueue) {
page_scheduler_->SetPageVisible(false);
EXPECT_EQ(InputBlockingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
page_scheduler_->SetPageVisible(true);
EXPECT_EQ(InputBlockingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
}
TEST_F(FrameSchedulerImplTest, HighestPriorityInputBlockingTaskQueue) {
page_scheduler_->SetPageVisible(false);
EXPECT_EQ(InputBlockingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kHighestPriority);
TaskPriority::kHighestPriority);
page_scheduler_->SetPageVisible(true);
EXPECT_EQ(InputBlockingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kHighestPriority);
TaskPriority::kHighestPriority);
}
class LowPriorityBackgroundPageExperimentTest : public FrameSchedulerImplTest {
@ -1437,47 +1441,46 @@ class LowPriorityBackgroundPageExperimentTest : public FrameSchedulerImplTest {
TEST_F(LowPriorityBackgroundPageExperimentTest, FrameQueuesPriorities) {
page_scheduler_->SetPageVisible(false);
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(), TaskPriority::kLowPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
page_scheduler_->AudioStateChanged(true);
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kHighPriority);
TaskPriority::kHighPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
page_scheduler_->AudioStateChanged(false);
page_scheduler_->SetPageVisible(true);
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kHighPriority);
TaskPriority::kHighPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
}
class BestEffortPriorityBackgroundPageExperimentTest
@ -1490,46 +1493,46 @@ class BestEffortPriorityBackgroundPageExperimentTest
TEST_F(BestEffortPriorityBackgroundPageExperimentTest, FrameQueuesPriorities) {
page_scheduler_->SetPageVisible(false);
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kBestEffortPriority);
TaskPriority::kBestEffortPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kBestEffortPriority);
TaskPriority::kBestEffortPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kBestEffortPriority);
TaskPriority::kBestEffortPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kBestEffortPriority);
TaskPriority::kBestEffortPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kBestEffortPriority);
TaskPriority::kBestEffortPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kBestEffortPriority);
TaskPriority::kBestEffortPriority);
page_scheduler_->AudioStateChanged(true);
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kHighPriority);
TaskPriority::kHighPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
page_scheduler_->AudioStateChanged(false);
page_scheduler_->SetPageVisible(true);
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kHighPriority);
TaskPriority::kHighPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
}
class LowPriorityHiddenFrameExperimentTest : public FrameSchedulerImplTest {
@ -1541,33 +1544,32 @@ class LowPriorityHiddenFrameExperimentTest : public FrameSchedulerImplTest {
TEST_F(LowPriorityHiddenFrameExperimentTest, FrameQueuesPriorities) {
// Hidden Frame Task Queues.
frame_scheduler_->SetFrameVisible(false);
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(), TaskPriority::kLowPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
// Visible Frame Task Queues.
frame_scheduler_->SetFrameVisible(true);
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kHighPriority);
TaskPriority::kHighPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
}
class LowPrioritySubFrameExperimentTest : public FrameSchedulerImplTest {
@ -1578,18 +1580,17 @@ class LowPrioritySubFrameExperimentTest : public FrameSchedulerImplTest {
TEST_F(LowPrioritySubFrameExperimentTest, FrameQueuesPriorities) {
// Sub-Frame Task Queues.
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(), TaskPriority::kLowPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
frame_scheduler_ =
CreateFrameScheduler(page_scheduler_.get(), nullptr,
@ -1598,17 +1599,17 @@ TEST_F(LowPrioritySubFrameExperimentTest, FrameQueuesPriorities) {
// Main Frame Task Queues.
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kHighPriority);
TaskPriority::kHighPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
}
class LowPrioritySubFrameThrottleableTaskExperimentTest
@ -1622,17 +1623,17 @@ TEST_F(LowPrioritySubFrameThrottleableTaskExperimentTest,
FrameQueuesPriorities) {
// Sub-Frame Task Queues.
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kHighPriority);
TaskPriority::kHighPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
frame_scheduler_ =
CreateFrameScheduler(page_scheduler_.get(), nullptr,
@ -1641,17 +1642,17 @@ TEST_F(LowPrioritySubFrameThrottleableTaskExperimentTest,
// Main Frame Task Queues.
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kHighPriority);
TaskPriority::kHighPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
}
class LowPriorityThrottleableTaskExperimentTest
@ -1664,17 +1665,17 @@ class LowPriorityThrottleableTaskExperimentTest
TEST_F(LowPriorityThrottleableTaskExperimentTest, FrameQueuesPriorities) {
// Sub-Frame Task Queues.
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kHighPriority);
TaskPriority::kHighPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
frame_scheduler_ =
CreateFrameScheduler(page_scheduler_.get(), nullptr,
@ -1683,17 +1684,17 @@ TEST_F(LowPriorityThrottleableTaskExperimentTest, FrameQueuesPriorities) {
// Main Frame Task Queues.
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kHighPriority);
TaskPriority::kHighPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
}
class LowPriorityAdFrameExperimentTest : public FrameSchedulerImplTest {
@ -1706,51 +1707,50 @@ TEST_F(LowPriorityAdFrameExperimentTest, FrameQueuesPriorities) {
EXPECT_FALSE(frame_scheduler_->IsAdFrame());
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kHighPriority);
TaskPriority::kHighPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
frame_scheduler_->SetIsAdFrame(true);
EXPECT_TRUE(frame_scheduler_->IsAdFrame());
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(), TaskPriority::kLowPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
frame_scheduler_->SetIsAdFrame(false);
EXPECT_FALSE(frame_scheduler_->IsAdFrame());
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kHighPriority);
TaskPriority::kHighPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
}
class BestEffortPriorityAdFrameExperimentTest : public FrameSchedulerImplTest {
@ -1763,50 +1763,50 @@ TEST_F(BestEffortPriorityAdFrameExperimentTest, FrameQueuesPriorities) {
EXPECT_FALSE(frame_scheduler_->IsAdFrame());
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kHighPriority);
TaskPriority::kHighPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
frame_scheduler_->SetIsAdFrame(true);
EXPECT_TRUE(frame_scheduler_->IsAdFrame());
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kBestEffortPriority);
TaskPriority::kBestEffortPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kBestEffortPriority);
TaskPriority::kBestEffortPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kBestEffortPriority);
TaskPriority::kBestEffortPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kBestEffortPriority);
TaskPriority::kBestEffortPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kBestEffortPriority);
TaskPriority::kBestEffortPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kBestEffortPriority);
TaskPriority::kBestEffortPriority);
frame_scheduler_->SetIsAdFrame(false);
EXPECT_FALSE(frame_scheduler_->IsAdFrame());
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kHighPriority);
TaskPriority::kHighPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
}
class LowPriorityCrossOriginTaskExperimentTest : public FrameSchedulerImplTest {
@ -1820,33 +1820,32 @@ TEST_F(LowPriorityCrossOriginTaskExperimentTest, FrameQueuesPriorities) {
// Same Origin Task Queues.
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kHighPriority);
TaskPriority::kHighPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
TaskPriority::kNormalPriority);
frame_scheduler_->SetCrossOriginToNearestMainFrame(true);
EXPECT_TRUE(frame_scheduler_->IsCrossOriginToNearestMainFrame());
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
EXPECT_EQ(LoadingTaskQueue()->GetQueuePriority(), TaskPriority::kLowPriority);
EXPECT_EQ(LoadingControlTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
EXPECT_EQ(DeferrableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
EXPECT_EQ(ThrottleableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
EXPECT_EQ(PausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
EXPECT_EQ(UnpausableTaskQueue()->GetQueuePriority(),
TaskQueue::QueuePriority::kLowPriority);
TaskPriority::kLowPriority);
}
TEST_F(FrameSchedulerImplTest, TaskTypeToTaskQueueMapping) {
@ -1906,8 +1905,7 @@ TEST_F(FrameSchedulerImplDatabaseAccessWithoutHighPriority, QueueTraits) {
auto da_queue = GetTaskQueue(TaskType::kDatabaseAccess);
EXPECT_EQ(da_queue->GetQueueTraits().prioritisation_type,
MainThreadTaskQueue::QueueTraits::PrioritisationType::kRegular);
EXPECT_EQ(da_queue->GetQueuePriority(),
TaskQueue::QueuePriority::kNormalPriority);
EXPECT_EQ(da_queue->GetQueuePriority(), TaskPriority::kNormalPriority);
}
class FrameSchedulerImplDatabaseAccessWithHighPriority
@ -1922,8 +1920,7 @@ TEST_F(FrameSchedulerImplDatabaseAccessWithHighPriority, QueueTraits) {
EXPECT_EQ(da_queue->GetQueueTraits().prioritisation_type,
MainThreadTaskQueue::QueueTraits::PrioritisationType::
kExperimentalDatabase);
EXPECT_EQ(da_queue->GetQueuePriority(),
TaskQueue::QueuePriority::kHighPriority);
EXPECT_EQ(da_queue->GetQueuePriority(), TaskPriority::kHighPriority);
}
TEST_F(FrameSchedulerImplDatabaseAccessWithHighPriority, RunOrder) {
@ -1948,8 +1945,7 @@ TEST_F(FrameSchedulerImplDatabaseAccessWithHighPriority,
TEST_F(FrameSchedulerImplTest, ContentCaptureHasIdleTaskQueue) {
auto task_queue = GetTaskQueue(TaskType::kInternalContentCapture);
EXPECT_EQ(TaskQueue::QueuePriority::kBestEffortPriority,
task_queue->GetQueuePriority());
EXPECT_EQ(TaskPriority::kBestEffortPriority, task_queue->GetQueuePriority());
}
TEST_F(FrameSchedulerImplTest, ComputePriorityForDetachedFrame) {
@ -1963,8 +1959,7 @@ TEST_F(FrameSchedulerImplTest,
LowPriorityScriptExecutionHasBestEffortPriority) {
auto task_queue = GetTaskQueue(TaskType::kLowPriorityScriptExecution);
EXPECT_EQ(TaskQueue::QueuePriority::kBestEffortPriority,
task_queue->GetQueuePriority());
EXPECT_EQ(TaskPriority::kBestEffortPriority, task_queue->GetQueuePriority());
}
namespace {
@ -2384,7 +2379,10 @@ class MockMainThreadScheduler : public MainThreadSchedulerImpl {
base::sequence_manager::SequenceManagerForTest::Create(
nullptr,
task_environment.GetMainThreadTaskRunner(),
task_environment.GetMockTickClock())) {}
task_environment.GetMockTickClock(),
base::sequence_manager::SequenceManager::Settings::Builder()
.SetPrioritySettings(CreatePrioritySettings())
.Build())) {}
MOCK_METHOD(void, OnMainFramePaint, ());
};
@ -3331,8 +3329,7 @@ TEST_F(FrameSchedulerImplThrottleForegroundTimersEnabledTest,
TEST_F(FrameSchedulerImplTest, PostMessageForwardingHasVeryHighPriority) {
auto task_queue = GetTaskQueue(TaskType::kInternalPostMessageForwarding);
EXPECT_EQ(TaskQueue::QueuePriority::kVeryHighPriority,
task_queue->GetQueuePriority());
EXPECT_EQ(TaskPriority::kVeryHighPriority, task_queue->GetQueuePriority());
}
class FrameSchedulerImplDeleterTaskRunnerEnabledTest

@ -16,6 +16,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.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_task_queue.h"
@ -45,10 +46,13 @@ class FrameTaskQueueControllerTest : public testing::Test,
~FrameTaskQueueControllerTest() override = default;
void SetUp() override {
auto settings = base::sequence_manager::SequenceManager::Settings::Builder()
.SetPrioritySettings(CreatePrioritySettings())
.Build();
scheduler_ = std::make_unique<MainThreadSchedulerImpl>(
base::sequence_manager::SequenceManagerForTest::Create(
nullptr, task_environment_.GetMainThreadTaskRunner(),
task_environment_.GetMockTickClock()));
task_environment_.GetMockTickClock(), std::move(settings)));
agent_group_scheduler_ = scheduler_->CreateAgentGroupScheduler();
page_scheduler_ = agent_group_scheduler_->CreatePageScheduler(nullptr);
frame_scheduler_ = page_scheduler_->CreateFrameScheduler(

@ -17,6 +17,7 @@
#include "base/time/time.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h"
namespace blink {
@ -33,9 +34,12 @@ class IdleTimeEstimatorTest : public testing::Test {
~IdleTimeEstimatorTest() override = default;
void SetUp() override {
auto settings = base::sequence_manager::SequenceManager::Settings::Builder()
.SetPrioritySettings(CreatePrioritySettings())
.Build();
manager_ = base::sequence_manager::SequenceManagerForTest::Create(
nullptr, task_environment_.GetMainThreadTaskRunner(),
task_environment_.GetMockTickClock());
task_environment_.GetMockTickClock(), std::move(settings));
estimator_ = std::make_unique<IdleTimeEstimator>(
task_environment_.GetMockTickClock(), 10, 50);
compositor_task_queue_1_ = NewTaskQueue();

@ -165,8 +165,8 @@ void MainThreadMetricsHelper::RecordTaskMetrics(
if (queue && base::TimeTicks::IsHighResolution()) {
base::TimeDelta elapsed =
task_timing.start_time() - task.GetDesiredExecutionTime();
queueing_delay_histograms_[queue->GetQueuePriority()].CountMicroseconds(
elapsed);
queueing_delay_histograms_[static_cast<size_t>(queue->GetQueuePriority())]
.CountMicroseconds(elapsed);
}
// Don't log the metrics to evaluate impact of CPU reduction.

@ -14,6 +14,7 @@
#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scheduler/common/metrics_helper.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
#include "third_party/blink/renderer/platform/scheduler/common/thread_load_tracker.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/use_case.h"
@ -97,9 +98,9 @@ class PLATFORM_EXPORT MainThreadMetricsHelper : public MetricsHelper {
TaskDurationPerTaskTypeMetricReporter
input_handling_per_task_type_duration_reporter_;
static_assert(TaskQueue::kQueuePriorityCount == 7);
CustomCountHistogram
queueing_delay_histograms_[TaskQueue::kQueuePriorityCount];
static_assert(static_cast<size_t>(TaskPriority::kPriorityCount) == 7);
CustomCountHistogram queueing_delay_histograms_[static_cast<size_t>(
TaskPriority::kPriorityCount)];
scheduling_metrics::TotalDurationMetricReporter total_task_time_reporter_;

@ -14,6 +14,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/page/launching_process_state.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h"
@ -50,10 +51,13 @@ class MainThreadMetricsHelperTest : public testing::Test {
{features::
kPurgeRendererMemoryWhenBackgrounded} /* disabled_features */);
histogram_tester_ = std::make_unique<base::HistogramTester>();
auto settings = base::sequence_manager::SequenceManager::Settings::Builder()
.SetPrioritySettings(CreatePrioritySettings())
.Build();
scheduler_ = std::make_unique<MainThreadSchedulerImpl>(
base::sequence_manager::SequenceManagerForTest::Create(
nullptr, task_environment_.GetMainThreadTaskRunner(),
task_environment_.GetMockTickClock()));
task_environment_.GetMockTickClock(), std::move(settings)));
metrics_helper_ = &scheduler_->main_thread_only().metrics_helper;
}

@ -7,6 +7,7 @@
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/perf/perf_result_reporter.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
#include "third_party/blink/renderer/platform/testing/scoped_scheduler_overrider.h"
@ -37,6 +38,7 @@ class MainThreadPerfTest : public testing::Test {
base::sequence_manager::CreateSequenceManagerOnCurrentThreadWithPump(
base::MessagePump::Create(base::MessagePumpType::DEFAULT),
base::sequence_manager::SequenceManager::Settings::Builder()
.SetPrioritySettings(CreatePrioritySettings())
.Build()));
scheduler_overrider_ = std::make_unique<ScopedSchedulerOverrider>(
scheduler_.get(), scheduler_->DefaultTaskRunner());

@ -5,6 +5,7 @@
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.h"
#include "base/task/single_thread_task_runner.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h"
namespace blink {
@ -25,7 +26,7 @@ MainThreadSchedulerHelper::MainThreadSchedulerHelper(
NewTaskQueue(MainThreadTaskQueue::QueueCreationParams(
MainThreadTaskQueue::QueueType::kControl)
.SetShouldNotifyObservers(false))) {
control_task_queue_->SetQueuePriority(TaskQueue::kControlPriority);
control_task_queue_->SetQueuePriority(TaskPriority::kControlPriority);
InitDefaultTaskRunner(default_task_queue_->CreateTaskRunner(
TaskType::kMainThreadTaskQueueDefault));

@ -48,6 +48,7 @@
#include "third_party/blink/renderer/platform/scheduler/common/auto_advancing_virtual_time_domain.h"
#include "third_party/blink/renderer/platform/scheduler/common/features.h"
#include "third_party/blink/renderer/platform/scheduler/common/process_state.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
#include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
@ -84,8 +85,8 @@ const int64_t kSecondsPerMinute = 60;
constexpr base::TimeDelta kDefaultPrioritizeCompositingAfterDelay =
base::Milliseconds(100);
constexpr TaskQueue::QueuePriority kPrioritizeCompositingAfterDelayPriority =
TaskQueue::QueuePriority::kVeryHighPriority;
constexpr TaskPriority kPrioritizeCompositingAfterDelayPriority =
TaskPriority::kVeryHighPriority;
v8::RAILMode RAILModeToV8RAILMode(RAILMode rail_mode) {
switch (rail_mode) {
@ -169,10 +170,10 @@ const char* OptionalTaskDescriptionToString(
}
const char* OptionalTaskPriorityToString(
absl::optional<TaskQueue::QueuePriority> priority) {
absl::optional<TaskPriority> priority) {
if (!priority)
return nullptr;
return TaskQueue::PriorityToString(priority.value());
return TaskPriorityToString(*priority);
}
bool IsBlockingEvent(const blink::WebInputEvent& web_input_event) {
@ -206,23 +207,21 @@ const char* InputEventStateToString(
}
}
TaskQueue::QueuePriority
GetPriorityFromCompositorTQPolicyDuringThreadedScrolling(
TaskPriority GetPriorityFromCompositorTQPolicyDuringThreadedScrolling(
CompositorTQPolicyDuringThreadedScroll policy) {
switch (policy) {
case CompositorTQPolicyDuringThreadedScroll::kLowPriorityAlways:
case CompositorTQPolicyDuringThreadedScroll::kLowPriorityWithAntiStarvation:
return TaskQueue::QueuePriority::kLowPriority;
return TaskPriority::kLowPriority;
case CompositorTQPolicyDuringThreadedScroll::
kNormalPriorityWithAntiStarvation:
return TaskQueue::QueuePriority::kNormalPriority;
return TaskPriority::kNormalPriority;
case CompositorTQPolicyDuringThreadedScroll::kVeryHighPriorityAlways:
return TaskQueue::QueuePriority::kVeryHighPriority;
return TaskPriority::kVeryHighPriority;
}
}
TaskQueue::QueuePriority MaxPriority(TaskQueue::QueuePriority priority1,
TaskQueue::QueuePriority priority2) {
TaskPriority MaxPriority(TaskPriority priority1, TaskPriority priority2) {
return std::min(priority1, priority2);
}
@ -468,10 +467,10 @@ MainThreadSchedulerImpl::MainThreadOnly::MainThreadOnly(
&main_thread_scheduler_impl->tracing_controller_,
YesNoStateToString),
main_thread_compositing_is_fast(false),
compositor_priority(TaskQueue::QueuePriority::kNormalPriority,
compositor_priority(TaskPriority::kNormalPriority,
"Scheduler.CompositorPriority",
&main_thread_scheduler_impl->tracing_controller_,
TaskQueue::PriorityToString),
TaskPriorityToString),
last_frame_time(now),
should_prioritize_compositor_task_queue_after_delay(false),
have_seen_a_frame(false),
@ -1785,7 +1784,7 @@ void MainThreadSchedulerImpl::OnVirtualTimeEnabled() {
helper_.NewTaskQueue(MainThreadTaskQueue::QueueCreationParams(
MainThreadTaskQueue::QueueType::kControl));
virtual_time_control_task_queue_->SetQueuePriority(
TaskQueue::kControlPriority);
TaskPriority::kControlPriority);
ForceUpdatePolicy();
@ -2361,9 +2360,8 @@ void MainThreadSchedulerImpl::OnTaskStarted(
: absl::nullopt};
main_thread_only().task_priority_for_tracing =
queue
? absl::optional<TaskQueue::QueuePriority>(queue->GetQueuePriority())
: absl::nullopt;
queue ? absl::optional<TaskPriority>(queue->GetQueuePriority())
: absl::nullopt;
}
void MainThreadSchedulerImpl::OnTaskCompleted(
@ -2503,7 +2501,7 @@ UkmRecordingStatus MainThreadSchedulerImpl::RecordTaskUkmImpl(
return UkmRecordingStatus::kSuccess;
}
TaskQueue::QueuePriority MainThreadSchedulerImpl::ComputePriority(
TaskPriority MainThreadSchedulerImpl::ComputePriority(
MainThreadTaskQueue* task_queue) const {
DCHECK(task_queue);
@ -2519,14 +2517,14 @@ TaskQueue::QueuePriority MainThreadSchedulerImpl::ComputePriority(
case MainThreadTaskQueue::QueueTraits::PrioritisationType::kCompositor:
return main_thread_only().compositor_priority;
case MainThreadTaskQueue::QueueTraits::PrioritisationType::kInput:
return TaskQueue::QueuePriority::kHighestPriority;
return TaskPriority::kHighestPriority;
case MainThreadTaskQueue::QueueTraits::PrioritisationType::kBestEffort:
return TaskQueue::QueuePriority::kBestEffortPriority;
return TaskPriority::kBestEffortPriority;
case MainThreadTaskQueue::QueueTraits::PrioritisationType::kRegular:
return TaskQueue::QueuePriority::kNormalPriority;
return TaskPriority::kNormalPriority;
default:
NOTREACHED();
return TaskQueue::QueuePriority::kNormalPriority;
return TaskPriority::kNormalPriority;
}
}
@ -2581,18 +2579,17 @@ MainThreadSchedulerImpl::scheduling_settings() const {
return scheduling_settings_;
}
TaskQueue::QueuePriority MainThreadSchedulerImpl::ComputeCompositorPriority()
const {
TaskPriority MainThreadSchedulerImpl::ComputeCompositorPriority() const {
if (main_thread_only().prioritize_compositing_after_input) {
// Return the highest priority here otherwise consecutive heavy inputs (e.g.
// typing) will starve rendering.
return TaskQueue::QueuePriority::kHighestPriority;
return TaskPriority::kHighestPriority;
} else if (scheduling_settings_
.prioritize_compositing_and_loading_during_early_loading &&
current_use_case() == UseCase::kEarlyLoading) {
return TaskQueue::QueuePriority::kHighPriority;
return TaskPriority::kHighPriority;
} else {
absl::optional<TaskQueue::QueuePriority> computed_compositor_priority =
absl::optional<TaskPriority> computed_compositor_priority =
ComputeCompositorPriorityFromUseCase();
// The default behavior for compositor gestures like compositor-driven
// scrolling is to deprioritize compositor TQ tasks (low priority) and not
@ -2620,12 +2617,11 @@ TaskQueue::QueuePriority MainThreadSchedulerImpl::ComputeCompositorPriority()
return kPrioritizeCompositingAfterDelayPriority;
}
}
return TaskQueue::QueuePriority::kNormalPriority;
return TaskPriority::kNormalPriority;
}
void MainThreadSchedulerImpl::UpdateCompositorTaskQueuePriority() {
TaskQueue::QueuePriority old_compositor_priority =
main_thread_only().compositor_priority;
TaskPriority old_compositor_priority = main_thread_only().compositor_priority;
main_thread_only().compositor_priority = ComputeCompositorPriority();
if (old_compositor_priority == main_thread_only().compositor_priority)
@ -2695,12 +2691,12 @@ void MainThreadSchedulerImpl::
}
}
absl::optional<TaskQueue::QueuePriority>
absl::optional<TaskPriority>
MainThreadSchedulerImpl::ComputeCompositorPriorityFromUseCase() const {
switch (current_use_case()) {
case UseCase::kCompositorGesture:
if (main_thread_only().blocking_input_expected_soon)
return TaskQueue::QueuePriority::kHighestPriority;
return TaskPriority::kHighestPriority;
// What we really want to do is priorize loading tasks, but that doesn't
// seem to be safe. Instead we do that by proxy by deprioritizing
// compositor tasks. This should be safe since we've already gone to the
@ -2723,7 +2719,7 @@ MainThreadSchedulerImpl::ComputeCompositorPriorityFromUseCase() const {
// block expensive tasks because we don't know whether they were integral
// to the page's functionality or not.
if (main_thread_only().main_thread_compositing_is_fast)
return TaskQueue::QueuePriority::kHighestPriority;
return TaskPriority::kHighestPriority;
return absl::nullopt;
case UseCase::kMainThreadGesture:
@ -2732,7 +2728,7 @@ MainThreadSchedulerImpl::ComputeCompositorPriorityFromUseCase() const {
// by the main thread. Since we know the established gesture type, we can
// be a little more aggressive about prioritizing compositing and input
// handling over other tasks.
return TaskQueue::QueuePriority::kHighestPriority;
return TaskPriority::kHighestPriority;
case UseCase::kNone:
case UseCase::kEarlyLoading:

@ -31,6 +31,7 @@
#include "third_party/blink/renderer/platform/scheduler/common/features.h"
#include "third_party/blink/renderer/platform/scheduler/common/idle_helper.h"
#include "third_party/blink/renderer/platform/scheduler/common/pollable_thread_safe_flag.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
#include "third_party/blink/renderer/platform/scheduler/common/thread_scheduler_base.h"
#include "third_party/blink/renderer/platform/scheduler/common/tracing_helper.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/deadline_task_runner.h"
@ -317,8 +318,7 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
// Note that the main's thread policy should be upto date to compute
// the correct priority.
base::sequence_manager::TaskQueue::QueuePriority ComputePriority(
MainThreadTaskQueue* task_queue) const;
TaskPriority ComputePriority(MainThreadTaskQueue* task_queue) const;
// Test helpers.
MainThreadSchedulerHelper* GetSchedulerHelperForTesting();
@ -367,7 +367,7 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
base::WeakPtr<MainThreadSchedulerImpl> GetWeakPtr();
base::sequence_manager::TaskQueue::QueuePriority compositor_priority() const {
TaskPriority compositor_priority() const {
return main_thread_only().compositor_priority;
}
@ -380,7 +380,7 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
return main_thread_only().main_thread_compositing_is_fast;
}
QueuePriority find_in_page_priority() const {
TaskPriority find_in_page_priority() const {
return main_thread_only().current_policy.find_in_page_priority();
}
@ -506,11 +506,8 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
return should_pause_task_queues_for_android_webview_;
}
base::sequence_manager::TaskQueue::QueuePriority& find_in_page_priority() {
return find_in_page_priority_;
}
base::sequence_manager::TaskQueue::QueuePriority find_in_page_priority()
const {
TaskPriority& find_in_page_priority() { return find_in_page_priority_; }
TaskPriority find_in_page_priority() const {
return find_in_page_priority_;
}
@ -545,7 +542,7 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
bool should_pause_task_queues_{false};
bool should_pause_task_queues_for_android_webview_{false};
base::sequence_manager::TaskQueue::QueuePriority find_in_page_priority_{
TaskPriority find_in_page_priority_{
FindInPageBudgetPoolController::kFindInPageBudgetNotExhaustedPriority};
UseCase use_case_{UseCase::kNone};
@ -674,7 +671,7 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
// Computes compositor priority based on various experiments and
// the use case. Defaults to kNormalPriority.
TaskQueue::QueuePriority ComputeCompositorPriority() const;
TaskPriority ComputeCompositorPriority() const;
// Used to update the compositor priority on the main thread.
void UpdateCompositorTaskQueuePriority();
@ -687,8 +684,7 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
// Computes the priority for compositing based on the current use case.
// Returns nullopt if the use case does not need to set the priority.
absl::optional<TaskQueue::QueuePriority>
ComputeCompositorPriorityFromUseCase() const;
absl::optional<TaskPriority> ComputeCompositorPriorityFromUseCase() const;
static void RunIdleTask(Thread::IdleTask, base::TimeTicks deadline);
@ -826,9 +822,8 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
TraceableState<absl::optional<TaskDescriptionForTracing>,
TracingCategory::kInfo>
task_description_for_tracing; // Don't use except for tracing.
TraceableState<
absl::optional<base::sequence_manager::TaskQueue::QueuePriority>,
TracingCategory::kInfo>
TraceableState<absl::optional<TaskPriority>,
TracingCategory::kInfo>
task_priority_for_tracing; // Only used for tracing.
// Holds task queues that are currently running.
@ -853,8 +848,7 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
// kNormalPriority and is updated via UpdateCompositorTaskQueuePriority().
// After 100ms with nothing running from this queue, the compositor will
// be set to kVeryHighPriority until a frame is run.
TraceableState<TaskQueue::QueuePriority, TracingCategory::kDefault>
compositor_priority;
TraceableState<TaskPriority, TracingCategory::kDefault> compositor_priority;
base::TimeTicks last_frame_time;
bool should_prioritize_compositor_task_queue_after_delay;
bool have_seen_a_frame;

@ -38,6 +38,7 @@
#include "third_party/blink/public/platform/web_input_event_result.h"
#include "third_party/blink/renderer/platform/scheduler/common/auto_advancing_virtual_time_domain.h"
#include "third_party/blink/renderer/platform/scheduler/common/features.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
#include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/find_in_page_budget_pool_controller.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
@ -423,6 +424,7 @@ class MainThreadSchedulerImplTest : public testing::Test {
nullptr, test_task_runner_, test_task_runner_->GetMockTickClock(),
base::sequence_manager::SequenceManager::Settings::Builder()
.SetRandomisedSamplingEnabled(true)
.SetPrioritySettings(CreatePrioritySettings())
.Build())));
EXPECT_EQ(ForceUpdatePolicyAndGetCurrentUseCase(), UseCase::kNone);
@ -2862,7 +2864,7 @@ TEST_F(MainThreadSchedulerImplTest, SYNCHRONIZED_GESTURE_CompositingExpensive) {
// Throttleable tasks should not have been starved by the expensive compositor
// tasks.
EXPECT_EQ(TaskQueue::kNormalPriority,
EXPECT_EQ(TaskPriority::kNormalPriority,
compositor_task_queue()->GetQueuePriority());
EXPECT_EQ(1000u, run_order.size());
}
@ -2902,7 +2904,7 @@ TEST_F(MainThreadSchedulerImplTest, MAIN_THREAD_CUSTOM_INPUT_HANDLING) {
// Throttleable tasks should not have been starved by the expensive compositor
// tasks.
EXPECT_EQ(TaskQueue::kNormalPriority,
EXPECT_EQ(TaskPriority::kNormalPriority,
compositor_task_queue()->GetQueuePriority());
EXPECT_EQ(1000u, run_order.size());
}
@ -2940,7 +2942,7 @@ TEST_F(MainThreadSchedulerImplTest, MAIN_THREAD_GESTURE) {
EXPECT_EQ(UseCase::kMainThreadGesture, CurrentUseCase()) << "i = " << i;
}
EXPECT_EQ(TaskQueue::kHighestPriority,
EXPECT_EQ(TaskPriority::kHighestPriority,
compositor_task_queue()->GetQueuePriority());
EXPECT_EQ(279u, run_order.size());
}
@ -3392,6 +3394,7 @@ class MainThreadSchedulerImplWithInitalVirtualTimeTest
test_task_runner_->GetMockTickClock(),
base::sequence_manager::SequenceManager::Settings::Builder()
.SetRandomisedSamplingEnabled(true)
.SetPrioritySettings(CreatePrioritySettings())
.Build()));
main_thread_scheduler->EnableVirtualTime(
/* initial_time= */ base::Time::FromJsTime(1000000.0));
@ -3569,7 +3572,7 @@ TEST_F(BestEffortPriorityForFindInPageExperimentTest,
PostTestTasks(&run_order, "F1 D1 F2 D2 F3 D3");
EnableIdleTasks();
EXPECT_EQ(scheduler_->find_in_page_priority(),
QueuePriority::kBestEffortPriority);
TaskPriority::kBestEffortPriority);
base::RunLoop().RunUntilIdle();
// Find-in-page tasks have "best-effort" priority, so they will be done after
// the default tasks (which have normal priority).

@ -17,6 +17,7 @@
#include "net/base/request_priority.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/blink/renderer/platform/scheduler/common/blink_scheduler_single_thread_task_runner.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.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/agent_group_scheduler_impl.h"
@ -24,14 +25,11 @@
#include "third_party/blink/renderer/platform/scheduler/public/web_scheduling_priority.h"
#include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h"
namespace base {
namespace sequence_manager {
namespace base::sequence_manager {
class SequenceManager;
}
} // namespace base
} // namespace base::sequence_manager
namespace blink {
namespace scheduler {
namespace blink::scheduler {
using TaskQueue = base::sequence_manager::TaskQueue;
@ -476,11 +474,12 @@ class PLATFORM_EXPORT MainThreadTaskQueue
void SetWakeUpBudgetPool(WakeUpBudgetPool* wake_up_budget_pool);
WakeUpBudgetPool* GetWakeUpBudgetPool() const { return wake_up_budget_pool_; }
void SetQueuePriority(TaskQueue::QueuePriority priority) {
void SetQueuePriority(TaskPriority priority) {
task_queue_->SetQueuePriority(priority);
}
TaskQueue::QueuePriority GetQueuePriority() const {
return task_queue_->GetQueuePriority();
TaskPriority GetQueuePriority() const {
return static_cast<TaskPriority>(task_queue_->GetQueuePriority());
}
bool IsQueueEnabled() const { return task_queue_->IsQueueEnabled(); }
@ -572,7 +571,6 @@ class PLATFORM_EXPORT MainThreadTaskQueue
base::WeakPtrFactory<MainThreadTaskQueue> weak_ptr_factory_{this};
};
} // namespace scheduler
} // namespace blink
} // namespace blink::scheduler
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_MAIN_THREAD_TASK_QUEUE_H_

@ -20,6 +20,7 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
#include "third_party/blink/renderer/platform/testing/scoped_scheduler_overrider.h"
@ -56,6 +57,7 @@ class MainThreadTest : public testing::Test {
base::MessagePump::Create(base::MessagePumpType::DEFAULT),
base::sequence_manager::SequenceManager::Settings::Builder()
.SetTickClock(&clock_)
.SetPrioritySettings(CreatePrioritySettings())
.Build()));
scheduler_overrider_ = std::make_unique<ScopedSchedulerOverrider>(
scheduler_.get(), scheduler_->DefaultTaskRunner());

@ -22,6 +22,7 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
@ -108,7 +109,10 @@ class PageSchedulerImplTest : public testing::Test {
test_task_runner_->AdvanceMockTickClock(base::Milliseconds(5));
scheduler_ = std::make_unique<MainThreadSchedulerImpl>(
base::sequence_manager::SequenceManagerForTest::Create(
nullptr, test_task_runner_, test_task_runner_->GetMockTickClock()));
nullptr, test_task_runner_, test_task_runner_->GetMockTickClock(),
base::sequence_manager::SequenceManager::Settings::Builder()
.SetPrioritySettings(CreatePrioritySettings())
.Build()));
agent_group_scheduler_ = scheduler_->CreateAgentGroupScheduler();
page_scheduler_delegate_ = std::make_unique<MockPageSchedulerDelegate>();
page_scheduler_ =

@ -7,7 +7,7 @@ package base.sequence_manager;
message SequenceManagerTestDescription {
// NEXT ID = 2
// This should be consistent with TaskQueue::QueuePriority.
// This should be consistent with blink::scheduler::TaskPriority.
enum QueuePriority {
// NEXT ID = 7

@ -4,6 +4,7 @@
#include "base/task/sequence_manager/test/test_task_queue.h"
#include "base/task/single_thread_task_runner.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
#include "third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_pool_manager.h"
namespace base {
@ -11,28 +12,30 @@ namespace sequence_manager {
namespace {
TaskQueue::QueuePriority ToTaskQueuePriority(
blink::scheduler::TaskPriority ToTaskQueuePriority(
SequenceManagerTestDescription::QueuePriority priority) {
static_assert(TaskQueue::kQueuePriorityCount == 7,
"Number of task queue priorities has changed in "
"TaskQueue::QueuePriority.");
using blink::scheduler::TaskPriority;
static_assert(static_cast<int>(TaskPriority::kPriorityCount) == 7,
"Number of task priorities has changed in "
"blink::scheduler::TaskPriority.");
switch (priority) {
case SequenceManagerTestDescription::BEST_EFFORT:
return TaskQueue::kBestEffortPriority;
return TaskPriority::kBestEffortPriority;
case SequenceManagerTestDescription::LOW:
return TaskQueue::kLowPriority;
return TaskPriority::kLowPriority;
case SequenceManagerTestDescription::UNDEFINED:
case SequenceManagerTestDescription::NORMAL:
return TaskQueue::kNormalPriority;
return TaskPriority::kNormalPriority;
case SequenceManagerTestDescription::HIGH:
return TaskQueue::kHighPriority;
return TaskPriority::kHighPriority;
case SequenceManagerTestDescription::VERY_HIGH:
return TaskQueue::kVeryHighPriority;
return TaskPriority::kVeryHighPriority;
case SequenceManagerTestDescription::HIGHEST:
return TaskQueue::kHighestPriority;
return TaskPriority::kHighestPriority;
case SequenceManagerTestDescription::CONTROL:
return TaskQueue::kControlPriority;
return TaskPriority::kControlPriority;
}
}
@ -55,7 +58,10 @@ ThreadManager::ThreadManager(base::TimeTicks initial_time,
manager_ = SequenceManagerForTest::Create(
nullptr, SingleThreadTaskRunner::GetCurrentDefault(),
test_task_runner_->GetMockTickClock());
test_task_runner_->GetMockTickClock(),
SequenceManager::Settings::Builder()
.SetPrioritySettings(::blink::scheduler::CreatePrioritySettings())
.Build());
TaskQueue::Spec spec = TaskQueue::Spec(QueueName::DEFAULT_TQ);
task_queues_.emplace_back(MakeRefCounted<TaskQueueWithVoters>(

@ -21,6 +21,7 @@
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h"
#include "third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
#include "third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_proxy.h"
#include "third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h"
@ -107,6 +108,7 @@ NonMainThreadImpl::SimpleThreadImpl::SimpleThreadImpl(
base::sequence_manager::SequenceManager::Settings::Builder()
.SetMessagePumpType(base::MessagePumpType::DEFAULT)
.SetRandomisedSamplingEnabled(true)
.SetPrioritySettings(CreatePrioritySettings())
.Build());
internal_task_queue_ = sequence_manager_->CreateTaskQueue(
base::sequence_manager::TaskQueue::Spec(

@ -6,6 +6,7 @@
#include "base/task/single_thread_task_runner.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
#include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_task_queue.h"
namespace blink {
@ -26,10 +27,10 @@ NonMainThreadSchedulerHelper::NonMainThreadSchedulerHelper(
input_task_queue_(
NewTaskQueueInternal(TaskQueue::Spec(QueueName::SUBTHREAD_INPUT_TQ))),
control_task_queue_(
NewTaskQueueInternal(TaskQueue::Spec(QueueName::SUBTHREAD_CONTROL_TQ)
.SetShouldNotifyObservers(false))) {
control_task_queue_->SetQueuePriority(TaskQueue::kControlPriority);
input_task_queue_->SetQueuePriority(TaskQueue::kHighestPriority);
NewTaskQueue(TaskQueue::Spec(QueueName::SUBTHREAD_CONTROL_TQ)
.SetShouldNotifyObservers(false))) {
control_task_queue_->SetQueuePriority(TaskPriority::kControlPriority);
input_task_queue_->SetQueuePriority(TaskPriority::kHighestPriority);
InitDefaultTaskRunner(
default_task_queue_->CreateTaskRunner(default_task_type));

@ -10,6 +10,7 @@
#include "base/task/single_thread_task_runner.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/renderer/platform/scheduler/common/blink_scheduler_single_thread_task_runner.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
#include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h"
#include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_base.h"
@ -103,13 +104,13 @@ void NonMainThreadTaskQueue::OnWebSchedulingPriorityChanged() {
DCHECK(web_scheduling_priority_);
switch (web_scheduling_priority_.value()) {
case WebSchedulingPriority::kUserBlockingPriority:
task_queue_->SetQueuePriority(TaskQueue::QueuePriority::kHighPriority);
task_queue_->SetQueuePriority(TaskPriority::kHighPriority);
return;
case WebSchedulingPriority::kUserVisiblePriority:
task_queue_->SetQueuePriority(TaskQueue::QueuePriority::kNormalPriority);
task_queue_->SetQueuePriority(TaskPriority::kNormalPriority);
return;
case WebSchedulingPriority::kBackgroundPriority:
task_queue_->SetQueuePriority(TaskQueue::QueuePriority::kLowPriority);
task_queue_->SetQueuePriority(TaskPriority::kLowPriority);
return;
}
}

@ -13,6 +13,7 @@
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scheduler/common/blink_scheduler_single_thread_task_runner.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
#include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h"
#include "third_party/blink/renderer/platform/scheduler/public/web_scheduling_priority.h"
@ -54,11 +55,12 @@ class PLATFORM_EXPORT NonMainThreadTaskQueue
void IncreaseThrottleRefCount();
void DecreaseThrottleRefCount();
void SetQueuePriority(TaskQueue::QueuePriority priority) {
void SetQueuePriority(TaskPriority priority) {
task_queue_->SetQueuePriority(priority);
}
TaskQueue::QueuePriority GetQueuePriority() const {
return task_queue_->GetQueuePriority();
TaskPriority GetQueuePriority() const {
return static_cast<TaskPriority>(task_queue_->GetQueuePriority());
}
std::unique_ptr<TaskQueue::QueueEnabledVoter> CreateQueueEnabledVoter() {

@ -17,6 +17,7 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
#include "third_party/blink/renderer/platform/scheduler/common/throttling/cpu_time_budget_pool.h"
#include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h"
@ -120,7 +121,10 @@ class WorkerSchedulerImplTest : public testing::Test {
base::sequence_manager::SequenceManagerForTest::Create(
nullptr,
mock_task_runner_,
mock_task_runner_->GetMockTickClock())),
mock_task_runner_->GetMockTickClock(),
base::sequence_manager::SequenceManager::Settings::Builder()
.SetPrioritySettings(CreatePrioritySettings())
.Build())),
scheduler_(new WorkerThreadSchedulerForTest(ThreadType::kTestThread,
sequence_manager_.get(),
nullptr /* proxy */)) {

@ -12,6 +12,7 @@
#include "base/test/task_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.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/page_scheduler_impl.h"
@ -127,7 +128,10 @@ class WorkerSchedulerProxyTest : public testing::Test {
base::sequence_manager::SequenceManagerForTest::Create(
nullptr,
task_environment_.GetMainThreadTaskRunner(),
task_environment_.GetMockTickClock()))),
task_environment_.GetMockTickClock(),
base::sequence_manager::SequenceManager::Settings::Builder()
.SetPrioritySettings(CreatePrioritySettings())
.Build()))),
agent_group_scheduler_(
main_thread_scheduler_->CreateAgentGroupScheduler()),
page_scheduler_(agent_group_scheduler_->CreatePageScheduler(nullptr)),

@ -15,6 +15,7 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/scheduler/common/process_state.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
#include "third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/test/recording_task_time_observer.h"
@ -146,7 +147,10 @@ class WorkerThreadSchedulerTest : public testing::Test {
base::sequence_manager::SequenceManagerForTest::Create(
nullptr,
task_environment_.GetMainThreadTaskRunner(),
task_environment_.GetMockTickClock())),
task_environment_.GetMockTickClock(),
base::sequence_manager::SequenceManager::Settings::Builder()
.SetPrioritySettings(CreatePrioritySettings())
.Build())),
scheduler_(new WorkerThreadSchedulerForTest(
sequence_manager_.get(),
task_environment_.GetMockTickClock(),
@ -492,7 +496,10 @@ class WorkerThreadSchedulerWithProxyTest : public testing::Test {
base::sequence_manager::SequenceManagerForTest::Create(
nullptr,
task_environment_.GetMainThreadTaskRunner(),
task_environment_.GetMockTickClock())) {
task_environment_.GetMockTickClock(),
base::sequence_manager::SequenceManager::Settings::Builder()
.SetPrioritySettings(CreatePrioritySettings())
.Build())) {
frame_scheduler_delegate_ =
std::make_unique<FrameSchedulerDelegateWithUkmSourceId>(42);
frame_scheduler_ = FakeFrameScheduler::Builder()

@ -7,6 +7,7 @@
#include "base/functional/bind.h"
#include "base/task/sequence_manager/test/sequence_manager_for_test.h"
#include "base/test/test_mock_time_task_runner.h"
#include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
#include "third_party/blink/renderer/platform/wtf/wtf.h"
@ -18,9 +19,13 @@ TestingPlatformSupportWithMockScheduler::
base::TestMockTimeTaskRunner::Type::kStandalone)) {
DCHECK(IsMainThread());
test_task_runner_->AdvanceMockTickClock(base::Seconds(1));
auto settings = base::sequence_manager::SequenceManager::Settings::Builder()
.SetPrioritySettings(scheduler::CreatePrioritySettings())
.Build();
std::unique_ptr<base::sequence_manager::SequenceManagerForTest>
sequence_manager = base::sequence_manager::SequenceManagerForTest::Create(
nullptr, test_task_runner_, test_task_runner_->GetMockTickClock());
nullptr, test_task_runner_, test_task_runner_->GetMockTickClock(),
std::move(settings));
sequence_manager_ = sequence_manager.get();
scheduler_ = std::make_unique<scheduler::MainThreadSchedulerImpl>(