summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro J. Estébanez <pedrojrulez@gmail.com>2019-10-20 21:31:21 +0200
committerPedro J. Estébanez <pedrojrulez@gmail.com>2020-02-11 12:04:41 +0100
commite38ae8d7e4407722e1b8d2b7caf49052f2f9174b (patch)
treea873a70b693f541fd835111fcda6bffcbc08bdf0
parenta8e14bee58ea3a7404eabc3687cb11ef778497a3 (diff)
Fix bugs in `RID_Alloc`
- Replace unintended `%` with `&` - `get_owned_list()`: make thread-safe and fix logic - Apply same logic fix to the destructor Previously, the determination of owned RIDs was wrong. For instance, it could skip owned items or include duplicates in the list. Avoids the engine crashing at exit.
-rw-r--r--core/rid_owner.h25
1 files changed, 17 insertions, 8 deletions
diff --git a/core/rid_owner.h b/core/rid_owner.h
index 26807e9a5e..ece8c6211b 100644
--- a/core/rid_owner.h
+++ b/core/rid_owner.h
@@ -85,7 +85,7 @@ public:
T *ptr = &chunks[free_chunk][free_element];
memnew_placement(ptr, T(p_value));
- uint32_t validator = (uint32_t)(_gen_id() % 0xFFFFFFFF);
+ uint32_t validator = (uint32_t)(_gen_id() & 0xFFFFFFFF);
uint64_t id = validator;
id <<= 32;
id |= free_index;
@@ -234,10 +234,17 @@ public:
}
void get_owned_list(List<RID> *p_owned) {
- for (size_t i = 0; i < alloc_count; i++) {
- uint64_t idx = free_list_chunks[i / elements_in_chunk][i % elements_in_chunk];
- uint64_t validator = validator_chunks[idx / elements_in_chunk][idx % elements_in_chunk];
- p_owned->push_back(_make_from_id((validator << 32) | idx));
+ if (THREAD_SAFE) {
+ spin_lock.lock();
+ }
+ for (size_t i = 0; i < max_alloc; i++) {
+ uint64_t validator = validator_chunks[i / elements_in_chunk][i % elements_in_chunk];
+ if (validator != 0xFFFFFFFF) {
+ p_owned->push_back(_make_from_id((validator << 32) | i));
+ }
+ }
+ if (THREAD_SAFE) {
+ spin_lock.unlock();
}
}
@@ -264,9 +271,11 @@ public:
print_error("ERROR: " + itos(alloc_count) + " RID allocations of type '" + typeid(T).name() + "' were leaked at exit.");
}
- for (uint32_t i = 0; i < alloc_count; i++) {
- uint64_t idx = free_list_chunks[i / elements_in_chunk][i % elements_in_chunk];
- chunks[idx / elements_in_chunk][idx % elements_in_chunk].~T();
+ for (size_t i = 0; i < max_alloc; i++) {
+ uint64_t validator = validator_chunks[i / elements_in_chunk][i % elements_in_chunk];
+ if (validator != 0xFFFFFFFF) {
+ chunks[i / elements_in_chunk][i % elements_in_chunk].~T();
+ }
}
}