Add missing thread safety to PagedAllocator
This commit is contained in:
parent
cf8ad12b56
commit
341b95871c
2 changed files with 44 additions and 11 deletions
|
@ -36,15 +36,15 @@
|
|||
#include <atomic>
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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<T>::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();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue