summaryrefslogtreecommitdiffstats
path: root/core/object/worker_thread_pool.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/object/worker_thread_pool.cpp')
-rw-r--r--core/object/worker_thread_pool.cpp60
1 files changed, 22 insertions, 38 deletions
diff --git a/core/object/worker_thread_pool.cpp b/core/object/worker_thread_pool.cpp
index 155d963a2b..7fd43c4094 100644
--- a/core/object/worker_thread_pool.cpp
+++ b/core/object/worker_thread_pool.cpp
@@ -32,6 +32,7 @@
#include "core/object/script_language.h"
#include "core/os/os.h"
+#include "core/os/safe_binary_mutex.h"
#include "core/os/thread_safe.h"
WorkerThreadPool::Task *const WorkerThreadPool::ThreadData::YIELDING = (Task *)1;
@@ -46,7 +47,7 @@ void WorkerThreadPool::Task::free_template_userdata() {
WorkerThreadPool *WorkerThreadPool::singleton = nullptr;
#ifdef THREADS_ENABLED
-thread_local uintptr_t WorkerThreadPool::unlockable_mutexes[MAX_UNLOCKABLE_MUTEXES] = {};
+thread_local WorkerThreadPool::UnlockableLocks WorkerThreadPool::unlockable_locks[MAX_UNLOCKABLE_LOCKS];
#endif
void WorkerThreadPool::_process_task(Task *p_task) {
@@ -428,13 +429,9 @@ Error WorkerThreadPool::wait_for_task_completion(TaskID p_task_id) {
void WorkerThreadPool::_lock_unlockable_mutexes() {
#ifdef THREADS_ENABLED
- for (uint32_t i = 0; i < MAX_UNLOCKABLE_MUTEXES; i++) {
- if (unlockable_mutexes[i]) {
- if ((((uintptr_t)unlockable_mutexes[i]) & 1) == 0) {
- ((Mutex *)unlockable_mutexes[i])->lock();
- } else {
- ((BinaryMutex *)(unlockable_mutexes[i] & ~1))->lock();
- }
+ for (uint32_t i = 0; i < MAX_UNLOCKABLE_LOCKS; i++) {
+ if (unlockable_locks[i].ulock) {
+ unlockable_locks[i].ulock->lock();
}
}
#endif
@@ -442,13 +439,9 @@ void WorkerThreadPool::_lock_unlockable_mutexes() {
void WorkerThreadPool::_unlock_unlockable_mutexes() {
#ifdef THREADS_ENABLED
- for (uint32_t i = 0; i < MAX_UNLOCKABLE_MUTEXES; i++) {
- if (unlockable_mutexes[i]) {
- if ((((uintptr_t)unlockable_mutexes[i]) & 1) == 0) {
- ((Mutex *)unlockable_mutexes[i])->unlock();
- } else {
- ((BinaryMutex *)(unlockable_mutexes[i] & ~1))->unlock();
- }
+ for (uint32_t i = 0; i < MAX_UNLOCKABLE_LOCKS; i++) {
+ if (unlockable_locks[i].ulock) {
+ unlockable_locks[i].ulock->unlock();
}
}
#endif
@@ -675,37 +668,28 @@ WorkerThreadPool::TaskID WorkerThreadPool::get_caller_task_id() {
}
#ifdef THREADS_ENABLED
-uint32_t WorkerThreadPool::thread_enter_unlock_allowance_zone(Mutex *p_mutex) {
- return _thread_enter_unlock_allowance_zone(p_mutex, false);
-}
-
-uint32_t WorkerThreadPool::thread_enter_unlock_allowance_zone(BinaryMutex *p_mutex) {
- return _thread_enter_unlock_allowance_zone(p_mutex, true);
-}
-
-uint32_t WorkerThreadPool::_thread_enter_unlock_allowance_zone(void *p_mutex, bool p_is_binary) {
- for (uint32_t i = 0; i < MAX_UNLOCKABLE_MUTEXES; i++) {
- if (unlikely((unlockable_mutexes[i] & ~1) == (uintptr_t)p_mutex)) {
+uint32_t WorkerThreadPool::_thread_enter_unlock_allowance_zone(THREADING_NAMESPACE::unique_lock<THREADING_NAMESPACE::mutex> &p_ulock) {
+ for (uint32_t i = 0; i < MAX_UNLOCKABLE_LOCKS; i++) {
+ DEV_ASSERT((bool)unlockable_locks[i].ulock == (bool)unlockable_locks[i].rc);
+ if (unlockable_locks[i].ulock == &p_ulock) {
// Already registered in the current thread.
- return UINT32_MAX;
- }
- if (!unlockable_mutexes[i]) {
- unlockable_mutexes[i] = (uintptr_t)p_mutex;
- if (p_is_binary) {
- unlockable_mutexes[i] |= 1;
- }
+ unlockable_locks[i].rc++;
+ return i;
+ } else if (!unlockable_locks[i].ulock) {
+ unlockable_locks[i].ulock = &p_ulock;
+ unlockable_locks[i].rc = 1;
return i;
}
}
- ERR_FAIL_V_MSG(UINT32_MAX, "No more unlockable mutex slots available. Engine bug.");
+ ERR_FAIL_V_MSG(UINT32_MAX, "No more unlockable lock slots available. Engine bug.");
}
void WorkerThreadPool::thread_exit_unlock_allowance_zone(uint32_t p_zone_id) {
- if (p_zone_id == UINT32_MAX) {
- return;
+ DEV_ASSERT(unlockable_locks[p_zone_id].ulock && unlockable_locks[p_zone_id].rc);
+ unlockable_locks[p_zone_id].rc--;
+ if (unlockable_locks[p_zone_id].rc == 0) {
+ unlockable_locks[p_zone_id].ulock = nullptr;
}
- DEV_ASSERT(unlockable_mutexes[p_zone_id]);
- unlockable_mutexes[p_zone_id] = 0;
}
#endif