WorkerThreadPool: Avoid most runtime allocations

Just a little optimization.

**NOTE:**
With `RID_Owner` we could replace each pair of `PagedAllocator` and
`HashMap`-of-ids-to-pointers. However, that would force us to expose
`RID` as the task/group id, instead of `int`, which would break the
API. Too bad. Let's wait until Godot 5.0.
This commit is contained in:
Pedro J. Estébanez 2023-12-28 19:31:28 +01:00
parent ae418f9469
commit a731774813
3 changed files with 34 additions and 15 deletions

View File

@ -613,13 +613,14 @@ void WorkerThreadPool::finish() {
return;
}
task_mutex.lock();
SelfList<Task> *E = low_priority_task_queue.first();
while (E) {
print_error("Task waiting was never re-claimed: " + E->self()->description);
E = E->next();
{
MutexLock lock(task_mutex);
SelfList<Task> *E = low_priority_task_queue.first();
while (E) {
print_error("Task waiting was never re-claimed: " + E->self()->description);
E = E->next();
}
}
task_mutex.unlock();
{
MutexLock lock(task_mutex);
@ -632,6 +633,13 @@ void WorkerThreadPool::finish() {
data.thread.wait_to_finish();
}
{
MutexLock lock(task_mutex);
for (KeyValue<TaskID, Task *> &E : tasks) {
task_allocator.free(E.value);
}
}
threads.clear();
}

View File

@ -95,8 +95,11 @@ private:
task_elem(this) {}
};
PagedAllocator<Task> task_allocator;
PagedAllocator<Group> group_allocator;
static const uint32_t TASKS_PAGE_SIZE = 1024;
static const uint32_t GROUPS_PAGE_SIZE = 256;
PagedAllocator<Task, false, TASKS_PAGE_SIZE> task_allocator;
PagedAllocator<Group, false, GROUPS_PAGE_SIZE> group_allocator;
SelfList<Task>::List low_priority_task_queue;
SelfList<Task>::List task_queue;
@ -117,8 +120,20 @@ private:
bool exit_threads = false;
HashMap<Thread::ID, int> thread_ids;
HashMap<TaskID, Task *> tasks;
HashMap<GroupID, Group *> groups;
HashMap<
TaskID,
Task *,
HashMapHasherDefault,
HashMapComparatorDefault<TaskID>,
PagedAllocator<HashMapElement<TaskID, Task *>, false, TASKS_PAGE_SIZE>>
tasks;
HashMap<
GroupID,
Group *,
HashMapHasherDefault,
HashMapComparatorDefault<GroupID>,
PagedAllocator<HashMapElement<GroupID, Group *>, false, GROUPS_PAGE_SIZE>>
groups;
uint32_t max_low_priority_threads = 0;
uint32_t low_priority_threads_used = 0;

View File

@ -40,7 +40,7 @@
#include <type_traits>
#include <typeinfo>
template <class T, bool thread_safe = false>
template <class T, bool thread_safe = false, uint32_t DEFAULT_PAGE_SIZE = 4096>
class PagedAllocator {
T **page_pool = nullptr;
T ***available_pool = nullptr;
@ -53,10 +53,6 @@ class PagedAllocator {
SpinLock spin_lock;
public:
enum {
DEFAULT_PAGE_SIZE = 4096
};
template <class... Args>
T *alloc(Args &&...p_args) {
if (thread_safe) {