Bug 1839102 - Use enum class for Task kind. r=bas

Differential Revision: https://phabricator.services.mozilla.com/D182980
This commit is contained in:
Tooru Fujisawa 2023-07-26 02:26:15 +00:00
Родитель 7c30e82179
Коммит b7229fa6d8
5 изменённых файлов: 52 добавлений и 33 удалений

Просмотреть файл

@ -137,9 +137,9 @@ bool DecodePool::IsShuttingDown() const { return mShuttingDown; }
class DecodingTask final : public Task {
public:
explicit DecodingTask(RefPtr<IDecodingTask>&& aTask)
: Task(false, aTask->Priority() == TaskPriority::eLow
? EventQueuePriority::Normal
: EventQueuePriority::RenderBlocking),
: Task(Kind::OffMainThreadOnly, aTask->Priority() == TaskPriority::eLow
? EventQueuePriority::Normal
: EventQueuePriority::RenderBlocking),
mTask(aTask) {}
bool Run() override {

Просмотреть файл

@ -1184,7 +1184,8 @@ class HelperThreadTaskHandler : public Task {
JS::RunHelperThreadTask();
return true;
}
explicit HelperThreadTaskHandler() : Task(false, EventQueuePriority::Normal) {
explicit HelperThreadTaskHandler()
: Task(Kind::OffMainThreadOnly, EventQueuePriority::Normal) {
// Bug 1703185: Currently all tasks are run at the same priority.
}

Просмотреть файл

@ -31,7 +31,7 @@ already_AddRefed<IdleTaskRunner> IdleTaskRunner::Create(
class IdleTaskRunnerTask : public Task {
public:
explicit IdleTaskRunnerTask(IdleTaskRunner* aRunner)
: Task(true, EventQueuePriority::Idle),
: Task(Kind::MainThreadOnly, EventQueuePriority::Idle),
mRunner(aRunner),
mRequestInterrupt(aRunner->mRequestInterrupt) {
SetManager(TaskController::Get()->GetIdleTaskManager());

Просмотреть файл

@ -331,7 +331,8 @@ void TaskController::RunPoolThread() {
task = nextTask;
}
if (task->IsMainThreadOnly() || task->mInProgress) {
if (task->GetKind() == Task::Kind::MainThreadOnly ||
task->mInProgress) {
continue;
}
@ -416,7 +417,7 @@ void TaskController::RunPoolThread() {
void TaskController::AddTask(already_AddRefed<Task>&& aTask) {
RefPtr<Task> task(aTask);
if (!task->IsMainThreadOnly()) {
if (task->GetKind() == Task::Kind::OffMainThreadOnly) {
MutexAutoLock lock(mPoolInitializationMutex);
if (!mThreadPoolInitialized) {
InitializeThreadPool();
@ -453,10 +454,13 @@ void TaskController::AddTask(already_AddRefed<Task>&& aTask) {
std::pair<std::set<RefPtr<Task>, Task::PriorityCompare>::iterator, bool>
insertion;
if (task->IsMainThreadOnly()) {
insertion = mMainThreadTasks.insert(std::move(task));
} else {
insertion = mThreadableTasks.insert(std::move(task));
switch (task->GetKind()) {
case Task::Kind::MainThreadOnly:
insertion = mMainThreadTasks.insert(std::move(task));
break;
case Task::Kind::OffMainThreadOnly:
insertion = mThreadableTasks.insert(std::move(task));
break;
}
(*insertion.first)->mIterator = insertion.first;
MOZ_ASSERT(insertion.second);
@ -527,7 +531,7 @@ void TaskController::ProcessPendingMTTask(bool aMayWait) {
void TaskController::ReprioritizeTask(Task* aTask, uint32_t aPriority) {
MutexAutoLock lock(mGraphMutex);
std::set<RefPtr<Task>, Task::PriorityCompare>* queue = &mMainThreadTasks;
if (!aTask->IsMainThreadOnly()) {
if (aTask->GetKind() == Task::Kind::OffMainThreadOnly) {
queue = &mThreadableTasks;
}
@ -548,8 +552,8 @@ void TaskController::ReprioritizeTask(Task* aTask, uint32_t aPriority) {
class RunnableTask : public Task {
public:
RunnableTask(already_AddRefed<nsIRunnable>&& aRunnable, int32_t aPriority,
bool aMainThread = true)
: Task(aMainThread, aPriority), mRunnable(aRunnable) {}
Kind aKind)
: Task(aKind, aPriority), mRunnable(aRunnable) {}
virtual bool Run() override {
mRunnable->Run();
@ -587,7 +591,8 @@ class RunnableTask : public Task {
void TaskController::DispatchRunnable(already_AddRefed<nsIRunnable>&& aRunnable,
uint32_t aPriority,
TaskManager* aManager) {
RefPtr<RunnableTask> task = new RunnableTask(std::move(aRunnable), aPriority);
RefPtr<RunnableTask> task = new RunnableTask(std::move(aRunnable), aPriority,
Task::Kind::MainThreadOnly);
task->SetManager(aManager);
TaskController::Get()->AddTask(task.forget());
@ -812,7 +817,8 @@ bool TaskController::DoExecuteNextTaskOnlyMainThreadInternal(
task = GetFinalDependency(task);
if (!task->IsMainThreadOnly() || task->mInProgress ||
if (task->GetKind() == Task::Kind::OffMainThreadOnly ||
task->mInProgress ||
(task->mTaskManager && task->mTaskManager->mCurrentSuspended)) {
continue;
}
@ -958,7 +964,7 @@ void TaskController::MaybeInterruptTask(Task* aTask) {
Task* firstDependency = aTask->mDependencies.begin()->get();
if (aTask->GetPriority() <= firstDependency->GetPriority() &&
!firstDependency->mCompleted &&
aTask->IsMainThreadOnly() == firstDependency->IsMainThreadOnly()) {
aTask->GetKind() == firstDependency->GetKind()) {
// This task has the same or a higher priority as one of its dependencies,
// never any need to interrupt.
return;
@ -972,7 +978,7 @@ void TaskController::MaybeInterruptTask(Task* aTask) {
return;
}
if (aTask->IsMainThreadOnly()) {
if (aTask->GetKind() == Task::Kind::MainThreadOnly) {
mMayHaveMainThreadTask = true;
EnsureMainThreadTasksScheduled();
@ -983,7 +989,7 @@ void TaskController::MaybeInterruptTask(Task* aTask) {
// We could go through the steps above here and interrupt an off main
// thread task in case it has a lower priority.
if (!finalDependency->IsMainThreadOnly()) {
if (finalDependency->GetKind() == Task::Kind::OffMainThreadOnly) {
return;
}

Просмотреть файл

@ -111,16 +111,31 @@ class TaskManager {
};
// A Task is the the base class for any unit of work that may be scheduled.
//
// Subclasses may specify their priority and whether they should be bound to
// the Gecko Main thread. When not bound to the main thread tasks may be
// executed on any available thread (including the main thread), but they may
// also be executed in parallel to any other task they do not have a dependency
// relationship with. Tasks will be run in order of object creation.
// either the Gecko Main thread or off main thread. When not bound to the main
// thread tasks may be executed on any available thread excluding the main
// thread, but they may also be executed in parallel to any other task they do
// not have a dependency relationship with.
//
// Tasks will be run in order of object creation.
class Task {
public:
enum class Kind : uint8_t {
// This task should be executed on any available thread excluding the Gecko
// Main thread.
OffMainThreadOnly,
// This task should be executed on the Gecko Main thread.
MainThreadOnly
// NOTE: "any available thread including the main thread" option is not
// supported (See bug 1839102).
};
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Task)
bool IsMainThreadOnly() { return mMainThreadOnly; }
Kind GetKind() { return mKind; }
// This returns the current task priority with its modifier applied.
uint32_t GetPriority() { return mPriority + mPriorityModifier; }
@ -148,7 +163,7 @@ class Task {
// This sets the TaskManager for the current task. Calling this after the
// task has been added to the TaskController results in undefined behavior.
void SetManager(TaskManager* aManager) {
MOZ_ASSERT(mMainThreadOnly);
MOZ_ASSERT(mKind == Kind::MainThreadOnly);
MOZ_ASSERT(!mIsInGraph);
mTaskManager = aManager;
}
@ -178,15 +193,12 @@ class Task {
#endif
protected:
Task(bool aMainThreadOnly,
Task(Kind aKind,
uint32_t aPriority = static_cast<uint32_t>(kDefaultPriorityValue))
: mMainThreadOnly(aMainThreadOnly),
mSeqNo(sCurrentTaskSeqNo++),
mPriority(aPriority) {}
: mKind(aKind), mSeqNo(sCurrentTaskSeqNo++), mPriority(aPriority) {}
Task(bool aMainThreadOnly,
EventQueuePriority aPriority = kDefaultPriorityValue)
: mMainThreadOnly(aMainThreadOnly),
Task(Kind aKind, EventQueuePriority aPriority = kDefaultPriorityValue)
: mKind(aKind),
mSeqNo(sCurrentTaskSeqNo++),
mPriority(static_cast<uint32_t>(aPriority)) {}
@ -220,7 +232,7 @@ class Task {
RefPtr<TaskManager> mTaskManager;
// Access to these variables is protected by the GraphMutex.
bool mMainThreadOnly;
Kind mKind;
bool mCompleted = false;
bool mInProgress = false;
#ifdef DEBUG