tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 7267ee8b9a4f4632607186ff33f711ba671ae5b1
parent bac754a046f857fada39f1a12adf3c8a7627a1d8
Author: Jens Stutte <jstutte@mozilla.com>
Date:   Mon,  3 Nov 2025 14:08:41 +0000

Bug 1997924 - Avoid memory allocations in ProcessUpdatedPriorityModifier. r=bas

We can leverage std::set's extract / insert to avoid allocations when updating task priorities.
It is assumed that this is always better, also for a small number of tasks.

Differential Revision: https://phabricator.services.mozilla.com/D269142

Diffstat:
Mxpcom/threads/TaskController.cpp | 32++++++++++++++------------------
Mxpcom/threads/TaskController.h | 5+++--
2 files changed, 17 insertions(+), 20 deletions(-)

diff --git a/xpcom/threads/TaskController.cpp b/xpcom/threads/TaskController.cpp @@ -1494,26 +1494,22 @@ void TaskController::ProcessUpdatedPriorityModifier(TaskManager* aManager) { int32_t modifier = aManager->mCurrentPriorityModifier; - std::vector<RefPtr<Task>> storedTasks; - // Find all relevant tasks. - for (auto iter = mMainThreadTasks.begin(); iter != mMainThreadTasks.end();) { - if ((*iter)->mTaskManager == aManager) { - storedTasks.push_back(*iter); - iter = mMainThreadTasks.erase(iter); - } else { - iter++; + // Find all relevant task nodes and move them to a temporary set with the + // new priority modifier. + PrioritySortedTasks managerTasks; + auto cur = mMainThreadTasks.begin(); + while (cur != mMainThreadTasks.end()) { + // Keep a valid iterator before potentially extracting the current task. + auto next = std::next(cur); + if (cur->get()->mTaskManager == aManager) { + auto task = mMainThreadTasks.extract(cur); + task.value()->mPriorityModifier = modifier; + managerTasks.insert(std::move(task)); } + cur = std::move(next); } - - // Reinsert found tasks with their new priorities. - for (RefPtr<Task>& ref : storedTasks) { - // Kept alive at first by the vector and then by mMainThreadTasks. - Task* task = ref; - task->mPriorityModifier = modifier; - auto insertion = mMainThreadTasks.insert(std::move(ref)); - MOZ_ASSERT(insertion.second); - task->mIterator = insertion.first; - } + // Merge the temporary set back to the main set. + mMainThreadTasks.merge(std::move(managerTasks)); } } // namespace mozilla diff --git a/xpcom/threads/TaskController.h b/xpcom/threads/TaskController.h @@ -431,8 +431,9 @@ class TaskController { std::stack<RefPtr<Task>> mCurrentTasksMT; // A list of all tasks ordered by priority. - std::set<RefPtr<Task>, Task::PriorityCompare> mThreadableTasks; - std::set<RefPtr<Task>, Task::PriorityCompare> mMainThreadTasks; + using PrioritySortedTasks = std::set<RefPtr<Task>, Task::PriorityCompare>; + PrioritySortedTasks mThreadableTasks; + PrioritySortedTasks mMainThreadTasks; // TaskManagers currently active. // We can use a raw pointer since tasks always hold on to their TaskManager.