Cleanups and codestyle for the godot4 containers that I added in unmodified yesterday.

This commit is contained in:
Relintai 2023-01-16 22:09:32 +01:00
parent 0a79f38843
commit d999f63cbd
4 changed files with 41 additions and 25 deletions

View File

@ -31,8 +31,8 @@
#ifndef BIN_SORTED_ARRAY_H
#define BIN_SORTED_ARRAY_H
#include "core/templates/local_vector.h"
#include "core/templates/paged_array.h"
#include "core/containers/local_vector.h"
#include "core/containers/paged_array.h"
template <class T>
class BinSortedArray {

View File

@ -35,8 +35,6 @@
#include "core/os/spin_lock.h"
#include "core/typedefs.h"
#include <type_traits>
// PagedArray is used mainly for filling a very large array from multiple threads efficiently and without causing major fragmentation
// PageArrayPool manages central page allocation in a thread safe matter
@ -199,7 +197,7 @@ public:
uint32_t page = count >> page_size_shift;
uint32_t offset = count & page_size_mask;
if (!std::is_trivially_constructible<T>::value) {
if (!__has_trivial_constructor(T)) {
memnew_placement(&page_data[page][offset], T(p_value));
} else {
page_data[page][offset] = p_value;
@ -211,7 +209,7 @@ public:
_FORCE_INLINE_ void pop_back() {
ERR_FAIL_COND(count == 0);
if (!std::is_trivially_destructible<T>::value) {
if (!__has_trivial_destructor(T)) {
uint32_t page = (count - 1) >> page_size_shift;
uint32_t offset = (count - 1) & page_size_mask;
page_data[page][offset].~T();
@ -228,7 +226,7 @@ public:
void clear() {
//destruct if needed
if (!std::is_trivially_destructible<T>::value) {
if (!__has_trivial_destructor(T)) {
for (uint64_t i = 0; i < count; i++) {
uint32_t page = i >> page_size_shift;
uint32_t offset = i & page_size_mask;
@ -311,13 +309,13 @@ public:
uint32_t to_copy = MIN(page_size - new_remainder, remainder);
for (uint32_t i = 0; i < to_copy; i++) {
if (!std::is_trivially_constructible<T>::value) {
if (!__has_trivial_constructor(T)) {
memnew_placement(&dst_page[i + new_remainder], T(remainder_page[i + remainder - to_copy]));
} else {
dst_page[i + new_remainder] = remainder_page[i + remainder - to_copy];
}
if (!std::is_trivially_destructible<T>::value) {
if (!__has_trivial_destructor(T)) {
remainder_page[i + remainder - to_copy].~T();
}
}

View File

@ -57,33 +57,41 @@ class SafeList {
// to the previous list item in time that was also logically deleted.
std::atomic<SafeListNode *> graveyard_next = nullptr;
std::function<void(T)> deletion_fn = [](T t) { return; };
void (*deletion_fn)(T t);
T val;
static void default_deletion_fn(T) {}
SafeListNode() {
next = NULL;
graveyard_next = NULL;
deletion_fn = default_deletion_fn;
}
};
static_assert(std::atomic<T>::is_always_lock_free);
std::atomic<SafeListNode *> head;
std::atomic<SafeListNode *> graveyard_head;
std::atomic<SafeListNode *> head = nullptr;
std::atomic<SafeListNode *> graveyard_head = nullptr;
std::atomic_uint active_iterator_count = 0;
std::atomic<uint32_t> active_iterator_count;
public:
class Iterator {
friend class SafeList;
SafeListNode *cursor = nullptr;
SafeList *list = nullptr;
SafeListNode *cursor;
SafeList *list;
Iterator(SafeListNode *p_cursor, SafeList *p_list) :
cursor(p_cursor), list(p_list) {
Iterator(SafeListNode *p_cursor, SafeList *p_list) {
cursor = p_cursor;
list = p_list;
list->active_iterator_count++;
}
public:
Iterator(const Iterator &p_other) :
cursor(p_other.cursor), list(p_other.list) {
Iterator(const Iterator &p_other) {
cursor = p_other.cursor;
list = p_other.list;
list->active_iterator_count++;
}
@ -197,13 +205,14 @@ public:
}
Iterator end() {
return Iterator(nullptr, this);
return Iterator(NULL, this);
}
// Calling this will cause zero to many deallocations.
bool maybe_cleanup() {
SafeListNode *cursor = nullptr;
SafeListNode *new_graveyard_head = nullptr;
SafeListNode *cursor = NULL;
SafeListNode *new_graveyard_head = NULL;
do {
// The access order here is theoretically important.
cursor = graveyard_head.load();
@ -215,6 +224,7 @@ public:
// Any iterator created after this point will never point to a deleted node.
// Swap it out with the current graveyard head.
} while (!graveyard_head.compare_exchange_strong(/* expected= */ cursor, /* new= */ new_graveyard_head));
// Our graveyard list is now unreachable by any active iterators,
// detached from the main graveyard head and ready for deletion.
while (cursor) {
@ -223,9 +233,17 @@ public:
tmp->deletion_fn(tmp->val);
memdelete_allocator<SafeListNode, A>(tmp);
}
return true;
}
SafeList() {
head = NULL;
graveyard_head = NULL;
active_iterator_count = 0;
}
~SafeList() {
#ifdef DEBUG_ENABLED
if (!maybe_cleanup()) {

View File

@ -31,7 +31,7 @@
#ifndef SEARCH_ARRAY_H
#define SEARCH_ARRAY_H
#include <core/templates/sort_array.h>
#include "sort_array.h"
template <class T, class Comparator = _DefaultComparator<T>>
class SearchArray {