diff options
Diffstat (limited to 'core/templates')
-rw-r--r-- | core/templates/list.h | 2 | ||||
-rw-r--r-- | core/templates/local_vector.h | 5 | ||||
-rw-r--r-- | core/templates/map.h | 2 | ||||
-rw-r--r-- | core/templates/oa_hash_map.h | 1 | ||||
-rw-r--r-- | core/templates/pooled_list.h | 95 | ||||
-rw-r--r-- | core/templates/safe_refcount.h | 1 | ||||
-rw-r--r-- | core/templates/thread_work_pool.h | 11 | ||||
-rw-r--r-- | core/templates/vector.h | 16 |
8 files changed, 121 insertions, 12 deletions
diff --git a/core/templates/list.h b/core/templates/list.h index eaf1dbb4a0..010e35eed8 100644 --- a/core/templates/list.h +++ b/core/templates/list.h @@ -492,7 +492,7 @@ public: _data->last = p_I; } - void invert() { + void reverse() { int s = size() / 2; Element *F = front(); Element *B = back(); diff --git a/core/templates/local_vector.h b/core/templates/local_vector.h index ffd17b7ee9..5f22e08eb8 100644 --- a/core/templates/local_vector.h +++ b/core/templates/local_vector.h @@ -32,7 +32,6 @@ #define LOCAL_VECTOR_H #include "core/error/error_macros.h" -#include "core/os/copymem.h" #include "core/os/memory.h" #include "core/templates/sort_array.h" #include "core/templates/vector.h" @@ -216,7 +215,7 @@ public: Vector<T> ret; ret.resize(size()); T *w = ret.ptrw(); - copymem(w, data, sizeof(T) * count); + memcpy(w, data, sizeof(T) * count); return ret; } @@ -224,7 +223,7 @@ public: Vector<uint8_t> ret; ret.resize(count * sizeof(T)); uint8_t *w = ret.ptrw(); - copymem(w, data, sizeof(T) * count); + memcpy(w, data, sizeof(T) * count); return ret; } diff --git a/core/templates/map.h b/core/templates/map.h index 51a237472d..7dfee13d2c 100644 --- a/core/templates/map.h +++ b/core/templates/map.h @@ -32,7 +32,7 @@ #define MAP_H #include "core/error/error_macros.h" -#include "core/templates/set.h" +#include "core/os/memory.h" // based on the very nice implementation of rb-trees by: // https://web.archive.org/web/20120507164830/http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html diff --git a/core/templates/oa_hash_map.h b/core/templates/oa_hash_map.h index 1d4176eb10..2c7c64cd78 100644 --- a/core/templates/oa_hash_map.h +++ b/core/templates/oa_hash_map.h @@ -32,7 +32,6 @@ #define OA_HASH_MAP_H #include "core/math/math_funcs.h" -#include "core/os/copymem.h" #include "core/os/memory.h" #include "core/templates/hashfuncs.h" diff --git a/core/templates/pooled_list.h b/core/templates/pooled_list.h new file mode 100644 index 0000000000..b4a6d2d1dd --- /dev/null +++ b/core/templates/pooled_list.h @@ -0,0 +1,95 @@ +/*************************************************************************/ +/* pooled_list.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#pragma once + +// Simple template to provide a pool with O(1) allocate and free. +// The freelist could alternatively be a linked list placed within the unused elements +// to use less memory, however a separate freelist is probably more cache friendly. + +// NOTE : Take great care when using this with non POD types. The construction and destruction +// is done in the LocalVector, NOT as part of the pool. So requesting a new item does not guarantee +// a constructor is run, and free does not guarantee a destructor. +// You should generally handle clearing +// an item explicitly after a request, as it may contain 'leftovers'. +// This is by design for fastest use in the BVH. If you want a more general pool +// that does call constructors / destructors on request / free, this should probably be +// a separate template. + +#include "core/templates/local_vector.h" + +template <class T, bool force_trivial = false> +class PooledList { + LocalVector<T, uint32_t, force_trivial> list; + LocalVector<uint32_t, uint32_t, true> freelist; + + // not all list members are necessarily used + int _used_size; + +public: + PooledList() { + _used_size = 0; + } + + int estimate_memory_use() const { + return (list.size() * sizeof(T)) + (freelist.size() * sizeof(uint32_t)); + } + + const T &operator[](uint32_t p_index) const { + return list[p_index]; + } + T &operator[](uint32_t p_index) { + return list[p_index]; + } + + int size() const { return _used_size; } + + T *request(uint32_t &r_id) { + _used_size++; + + if (freelist.size()) { + // pop from freelist + int new_size = freelist.size() - 1; + r_id = freelist[new_size]; + freelist.resize(new_size); + return &list[r_id]; + } + + r_id = list.size(); + list.resize(r_id + 1); + return &list[r_id]; + } + void free(const uint32_t &p_id) { + // should not be on free list already + CRASH_COND(p_id >= list.size()); + freelist.push_back(p_id); + _used_size--; + } +}; diff --git a/core/templates/safe_refcount.h b/core/templates/safe_refcount.h index 91a34ecd54..e9e5695f80 100644 --- a/core/templates/safe_refcount.h +++ b/core/templates/safe_refcount.h @@ -36,6 +36,7 @@ #if !defined(NO_THREADS) #include <atomic> +#include <type_traits> // Design goals for these classes: // - No automatic conversions or arithmetic operators, diff --git a/core/templates/thread_work_pool.h b/core/templates/thread_work_pool.h index 19ab1dda3a..9f7a692cc5 100644 --- a/core/templates/thread_work_pool.h +++ b/core/templates/thread_work_pool.h @@ -83,7 +83,7 @@ public: ERR_FAIL_COND(!threads); //never initialized ERR_FAIL_COND(current_work != nullptr); - index.store(0); + index.store(0, std::memory_order_release); Work<C, M, U> *w = memnew((Work<C, M, U>)); w->instance = p_instance; @@ -104,8 +104,15 @@ public: return current_work != nullptr; } + bool is_done_dispatching() const { + ERR_FAIL_COND_V(current_work == nullptr, false); + return index.load(std::memory_order_acquire) >= current_work->max_elements; + } + uint32_t get_work_index() const { - return index; + ERR_FAIL_COND_V(current_work == nullptr, 0); + uint32_t idx = index.load(std::memory_order_acquire); + return MIN(idx, current_work->max_elements); } void end_work() { diff --git a/core/templates/vector.h b/core/templates/vector.h index 6a8902707c..dae8874a87 100644 --- a/core/templates/vector.h +++ b/core/templates/vector.h @@ -38,7 +38,6 @@ */ #include "core/error/error_macros.h" -#include "core/os/copymem.h" #include "core/os/memory.h" #include "core/templates/cowdata.h" #include "core/templates/sort_array.h" @@ -66,6 +65,7 @@ private: public: bool push_back(T p_elem); _FORCE_INLINE_ bool append(const T &p_elem) { return push_back(p_elem); } //alias + void fill(T p_elem); void remove(int p_index) { _cowdata.remove(p_index); } void erase(const T &p_val) { @@ -74,7 +74,7 @@ public: remove(idx); } } - void invert(); + void reverse(); _FORCE_INLINE_ T *ptrw() { return _cowdata.ptrw(); } _FORCE_INLINE_ const T *ptr() const { return _cowdata.ptr(); } @@ -134,7 +134,7 @@ public: Vector<uint8_t> to_byte_array() const { Vector<uint8_t> ret; ret.resize(size() * sizeof(T)); - copymem(ret.ptrw(), ptr(), sizeof(T) * size()); + memcpy(ret.ptrw(), ptr(), sizeof(T) * size()); return ret; } @@ -194,7 +194,7 @@ public: }; template <class T> -void Vector<T>::invert() { +void Vector<T>::reverse() { for (int i = 0; i < size() / 2; i++) { T *p = ptrw(); SWAP(p[i], p[size() - i - 1]); @@ -223,4 +223,12 @@ bool Vector<T>::push_back(T p_elem) { return false; } +template <class T> +void Vector<T>::fill(T p_elem) { + T *p = ptrw(); + for (int i = 0; i < size(); i++) { + p[i] = p_elem; + } +} + #endif // VECTOR_H |