From 341b95871cdbffe8861735b507f12fab363bc469 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Fri, 5 May 2023 19:55:29 +0200 Subject: [PATCH] Add missing thread safety to PagedAllocator --- core/os/spin_lock.h | 6 ++-- core/templates/paged_allocator.h | 49 ++++++++++++++++++++++++++------ 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/core/os/spin_lock.h b/core/os/spin_lock.h index 409154dbb56..93ea782b60e 100644 --- a/core/os/spin_lock.h +++ b/core/os/spin_lock.h @@ -36,15 +36,15 @@ #include class SpinLock { - std::atomic_flag locked = ATOMIC_FLAG_INIT; + mutable std::atomic_flag locked = ATOMIC_FLAG_INIT; public: - _ALWAYS_INLINE_ void lock() { + _ALWAYS_INLINE_ void lock() const { while (locked.test_and_set(std::memory_order_acquire)) { // Continue. } } - _ALWAYS_INLINE_ void unlock() { + _ALWAYS_INLINE_ void unlock() const { locked.clear(std::memory_order_release); } }; diff --git a/core/templates/paged_allocator.h b/core/templates/paged_allocator.h index 1cd71ec16cd..deb29377711 100644 --- a/core/templates/paged_allocator.h +++ b/core/templates/paged_allocator.h @@ -99,7 +99,8 @@ public: } } - void reset(bool p_allow_unfreed = false) { +private: + void _reset(bool p_allow_unfreed) { if (!p_allow_unfreed || !std::is_trivially_destructible::value) { ERR_FAIL_COND(allocs_available < pages_allocated * page_size); } @@ -116,16 +117,41 @@ public: allocs_available = 0; } } + +public: + void reset(bool p_allow_unfreed = false) { + if (thread_safe) { + spin_lock.lock(); + } + _reset(p_allow_unfreed); + if (thread_safe) { + spin_lock.unlock(); + } + } + bool is_configured() const { - return page_size > 0; + if (thread_safe) { + spin_lock.lock(); + } + bool result = page_size > 0; + if (thread_safe) { + spin_lock.unlock(); + } + return result; } void configure(uint32_t p_page_size) { + if (thread_safe) { + spin_lock.lock(); + } ERR_FAIL_COND(page_pool != nullptr); //sanity check ERR_FAIL_COND(p_page_size == 0); page_size = nearest_power_of_2_templated(p_page_size); page_mask = page_size - 1; page_shift = get_shift_from_power_of_2(page_size); + if (thread_safe) { + spin_lock.unlock(); + } } // Power of 2 recommended because of alignment with OS page sizes. @@ -135,13 +161,20 @@ public: } ~PagedAllocator() { - if (allocs_available < pages_allocated * page_size) { - if (CoreGlobals::leak_reporting_enabled) { - ERR_FAIL_COND_MSG(allocs_available < pages_allocated * page_size, String("Pages in use exist at exit in PagedAllocator: ") + String(typeid(T).name())); - } - return; + if (thread_safe) { + spin_lock.lock(); + } + bool leaked = allocs_available < pages_allocated * page_size; + if (leaked) { + if (CoreGlobals::leak_reporting_enabled) { + ERR_PRINT(String("Pages in use exist at exit in PagedAllocator: ") + String(typeid(T).name())); + } + } else { + _reset(false); + } + if (thread_safe) { + spin_lock.unlock(); } - reset(); } };