1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-05 12:10:55 +00:00

Optimize thread pools by avoiding needless locks and unlocks of the task_mutex.

This commit is contained in:
Lukas Tenbrink
2025-03-16 15:12:58 +01:00
parent b377562b52
commit 9d30732c5b

View File

@@ -186,28 +186,36 @@ void WorkerThreadPool::_thread_function(void *p_user) {
while (true) { while (true) {
Task *task_to_process = nullptr; Task *task_to_process = nullptr;
{ {
// Create the lock outside the inner loop so it isn't needlessly unlocked and relocked
// when no task was found to process, and the loop is re-entered.
MutexLock lock(thread_data->pool->task_mutex); MutexLock lock(thread_data->pool->task_mutex);
while (true) {
bool exit = thread_data->pool->_handle_runlevel(thread_data, lock); bool exit = thread_data->pool->_handle_runlevel(thread_data, lock);
if (unlikely(exit)) { if (unlikely(exit)) {
break; return;
} }
thread_data->signaled = false; thread_data->signaled = false;
if (thread_data->pool->task_queue.first()) { if (!thread_data->pool->task_queue.first()) {
// There wasn't a task available yet.
// Let's wait for the next notification, then recheck.
thread_data->cond_var.wait(lock);
continue;
}
// Got a task to process! Remove it from the queue, then break into the task handling section.
task_to_process = thread_data->pool->task_queue.first()->self(); task_to_process = thread_data->pool->task_queue.first()->self();
thread_data->pool->task_queue.remove(thread_data->pool->task_queue.first()); thread_data->pool->task_queue.remove(thread_data->pool->task_queue.first());
} else { break;
thread_data->cond_var.wait(lock);
} }
} }
if (task_to_process) { DEV_ASSERT(task_to_process);
thread_data->pool->_process_task(task_to_process); thread_data->pool->_process_task(task_to_process);
} }
} }
}
void WorkerThreadPool::_post_tasks(Task **p_tasks, uint32_t p_count, bool p_high_priority, MutexLock<BinaryMutex> &p_lock) { void WorkerThreadPool::_post_tasks(Task **p_tasks, uint32_t p_count, bool p_high_priority, MutexLock<BinaryMutex> &p_lock) {
// Fall back to processing on the calling thread if there are no worker threads. // Fall back to processing on the calling thread if there are no worker threads.