Merge pull request #76755 from RandomShaper/fix_allocator_thsafe
Add missing thread safety to PagedAllocator
This commit is contained in:
commit
58ea42e4ab
2 changed files with 44 additions and 11 deletions
|
@ -36,15 +36,15 @@
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
class SpinLock {
|
class SpinLock {
|
||||||
std::atomic_flag locked = ATOMIC_FLAG_INIT;
|
mutable std::atomic_flag locked = ATOMIC_FLAG_INIT;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
_ALWAYS_INLINE_ void lock() {
|
_ALWAYS_INLINE_ void lock() const {
|
||||||
while (locked.test_and_set(std::memory_order_acquire)) {
|
while (locked.test_and_set(std::memory_order_acquire)) {
|
||||||
// Continue.
|
// Continue.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ALWAYS_INLINE_ void unlock() {
|
_ALWAYS_INLINE_ void unlock() const {
|
||||||
locked.clear(std::memory_order_release);
|
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) {
|
if (!p_allow_unfreed || !std::is_trivially_destructible<T>::value) {
|
||||||
ERR_FAIL_COND(allocs_available < pages_allocated * page_size);
|
ERR_FAIL_COND(allocs_available < pages_allocated * page_size);
|
||||||
}
|
}
|
||||||
|
@ -116,16 +117,41 @@ public:
|
||||||
allocs_available = 0;
|
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 {
|
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) {
|
void configure(uint32_t p_page_size) {
|
||||||
|
if (thread_safe) {
|
||||||
|
spin_lock.lock();
|
||||||
|
}
|
||||||
ERR_FAIL_COND(page_pool != nullptr); //sanity check
|
ERR_FAIL_COND(page_pool != nullptr); //sanity check
|
||||||
ERR_FAIL_COND(p_page_size == 0);
|
ERR_FAIL_COND(p_page_size == 0);
|
||||||
page_size = nearest_power_of_2_templated(p_page_size);
|
page_size = nearest_power_of_2_templated(p_page_size);
|
||||||
page_mask = page_size - 1;
|
page_mask = page_size - 1;
|
||||||
page_shift = get_shift_from_power_of_2(page_size);
|
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.
|
// Power of 2 recommended because of alignment with OS page sizes.
|
||||||
|
@ -135,13 +161,20 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
~PagedAllocator() {
|
~PagedAllocator() {
|
||||||
if (allocs_available < pages_allocated * page_size) {
|
if (thread_safe) {
|
||||||
|
spin_lock.lock();
|
||||||
|
}
|
||||||
|
bool leaked = allocs_available < pages_allocated * page_size;
|
||||||
|
if (leaked) {
|
||||||
if (CoreGlobals::leak_reporting_enabled) {
|
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()));
|
ERR_PRINT(String("Pages in use exist at exit in PagedAllocator: ") + String(typeid(T).name()));
|
||||||
}
|
}
|
||||||
return;
|
} else {
|
||||||
|
_reset(false);
|
||||||
|
}
|
||||||
|
if (thread_safe) {
|
||||||
|
spin_lock.unlock();
|
||||||
}
|
}
|
||||||
reset();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue