1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-21 14:57:09 +00:00

Merge pull request #112657 from stuartcarnie/rid_alloc_owns_lockfree

Core: Switch `RID_Alloc::owns` to lock-free
This commit is contained in:
Thaddeus Crews
2025-11-12 11:24:14 -06:00

View File

@@ -310,16 +310,24 @@ public:
} }
_FORCE_INLINE_ bool owns(const RID &p_rid) const { _FORCE_INLINE_ bool owns(const RID &p_rid) const {
if (p_rid == RID()) {
return false;
}
if constexpr (THREAD_SAFE) { if constexpr (THREAD_SAFE) {
mutex.lock(); SYNC_ACQUIRE;
} }
uint64_t id = p_rid.get_id(); uint64_t id = p_rid.get_id();
uint32_t idx = uint32_t(id & 0xFFFFFFFF); uint32_t idx = uint32_t(id & 0xFFFFFFFF);
if (unlikely(idx >= max_alloc)) { uint32_t ma;
if constexpr (THREAD_SAFE) { if constexpr (THREAD_SAFE) {
mutex.unlock(); ma = ((std::atomic<uint32_t> *)&max_alloc)->load(std::memory_order_relaxed);
} else {
ma = max_alloc;
} }
if (unlikely(idx >= ma)) {
return false; return false;
} }
@@ -328,10 +336,29 @@ public:
uint32_t validator = uint32_t(id >> 32); uint32_t validator = uint32_t(id >> 32);
bool owned = (chunks[idx_chunk][idx_element].validator & 0x7FFFFFFF) == validator; if constexpr (THREAD_SAFE) {
#ifdef TSAN_ENABLED
__tsan_acquire(&chunks[idx_chunk]); // We know not a race in practice.
__tsan_acquire(&chunks[idx_chunk][idx_element]); // We know not a race in practice.
#endif
}
Chunk &c = chunks[idx_chunk][idx_element];
if constexpr (THREAD_SAFE) { if constexpr (THREAD_SAFE) {
mutex.unlock(); #ifdef TSAN_ENABLED
__tsan_release(&chunks[idx_chunk]);
__tsan_release(&chunks[idx_chunk][idx_element]);
__tsan_acquire(&c.validator); // We know not a race in practice.
#endif
}
bool owned = (c.validator & 0x7FFFFFFF) == validator;
if constexpr (THREAD_SAFE) {
#ifdef TSAN_ENABLED
__tsan_release(&c.validator);
#endif
} }
return owned; return owned;