[Bf-blender-cvs] [6f79e526656] functions: Initial support for custom allocators for containers
Jacques Lucke
noreply at git.blender.org
Mon Aug 19 18:41:50 CEST 2019
Commit: 6f79e526656a5a433c2056c353ff97c9e53eadbf
Author: Jacques Lucke
Date: Mon Aug 19 18:18:20 2019 +0200
Branches: functions
https://developer.blender.org/rB6f79e526656a5a433c2056c353ff97c9e53eadbf
Initial support for custom allocators for containers
===================================================================
A source/blender/blenlib/BLI_allocator.hpp
A source/blender/blenlib/BLI_array.hpp
M source/blender/blenlib/BLI_map.hpp
M source/blender/blenlib/BLI_memory.hpp
M source/blender/blenlib/BLI_open_addressing.hpp
M source/blender/blenlib/BLI_set.hpp
M source/blender/blenlib/BLI_set_vector.hpp
M source/blender/blenlib/BLI_stack.hpp
M source/blender/blenlib/BLI_temporary_allocator.h
D source/blender/blenlib/BLI_temporary_allocator.hpp
M source/blender/blenlib/BLI_vector.hpp
M source/blender/blenlib/CMakeLists.txt
M source/blender/blenlib/intern/BLI_temporary_allocator.cpp
M source/blender/functions/backends/cpp/cpp_type_info.hpp
M source/blender/simulations/bparticles/action_interface.hpp
M source/blender/simulations/bparticles/particle_function.cpp
M source/blender/simulations/bparticles/particle_function.hpp
M source/blender/simulations/bparticles/particle_function_builder.cpp
M source/blender/simulations/bparticles/simulate.cpp
M source/blender/windowmanager/intern/wm_init_exit.c
D tests/gtests/blenlib/BLI_temporary_allocator_test.cc
M tests/gtests/blenlib/CMakeLists.txt
===================================================================
diff --git a/source/blender/blenlib/BLI_allocator.hpp b/source/blender/blenlib/BLI_allocator.hpp
new file mode 100644
index 00000000000..89378ff2c40
--- /dev/null
+++ b/source/blender/blenlib/BLI_allocator.hpp
@@ -0,0 +1,69 @@
+#pragma once
+
+#include <stdlib.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_temporary_allocator.h"
+
+namespace BLI {
+
+class GuardedAllocator {
+ public:
+ void *allocate(uint size, const char *name)
+ {
+ return MEM_mallocN(size, name);
+ }
+
+ void *allocate_aligned(uint size, uint alignment, const char *name)
+ {
+ alignment = std::max<uint>(alignment, 8);
+ return MEM_mallocN_aligned(size, alignment, name);
+ }
+
+ void deallocate(void *ptr)
+ {
+ MEM_freeN(ptr);
+ }
+};
+
+class RawAllocator {
+ public:
+ void *allocate(uint size, const char *UNUSED(name))
+ {
+ return malloc(size);
+ }
+
+ void *allocate_aligned(uint size, uint alignment, const char *UNUSED(name))
+ {
+ return aligned_alloc(alignment, size);
+ }
+
+ void deallocate(void *ptr)
+ {
+ free(ptr);
+ }
+};
+
+class TemporaryAllocator {
+ public:
+ void *allocate(uint size, const char *UNUSED(name))
+ {
+ return BLI_temporary_allocate(size);
+ }
+
+ void *allocate_aligned(uint size, uint alignment, const char *UNUSED(name))
+ {
+ BLI_assert(alignment <= 64);
+ UNUSED_VARS_NDEBUG(alignment);
+ return BLI_temporary_allocate(size);
+ }
+
+ void deallocate(void *ptr)
+ {
+ BLI_temporary_deallocate(ptr);
+ }
+};
+
+} // namespace BLI
diff --git a/source/blender/blenlib/BLI_array.hpp b/source/blender/blenlib/BLI_array.hpp
new file mode 100644
index 00000000000..2e299de76dd
--- /dev/null
+++ b/source/blender/blenlib/BLI_array.hpp
@@ -0,0 +1,134 @@
+#pragma once
+
+#include "BLI_utildefines.h"
+#include "BLI_allocator.hpp"
+#include "BLI_array_ref.hpp"
+#include "BLI_memory.hpp"
+
+namespace BLI {
+
+template<typename T, typename Allocator = GuardedAllocator> class Array {
+ private:
+ T *m_data;
+ uint m_size;
+ Allocator m_allocator;
+
+ public:
+ Array()
+ {
+ m_data = nullptr;
+ m_size = 0;
+ }
+
+ explicit Array(uint size)
+ {
+ m_data = this->allocate(size);
+ m_size = size;
+
+ for (uint i = 0; i < m_size; i++) {
+ new (m_data + i) T();
+ }
+ }
+
+ Array(const Array &other)
+ {
+ m_size = 0;
+ m_allocator = other.m_allocator;
+
+ if (m_size == 0) {
+ m_data = nullptr;
+ return;
+ }
+ else {
+ m_data = this->allocate(m_size);
+ copy_n(other.begin(), m_size, m_data);
+ }
+ }
+
+ Array(Array &&other)
+ {
+ m_data = other.m_data;
+ m_size = other.m_size;
+ m_allocator = other.m_allocator;
+
+ other.m_data = nullptr;
+ other.m_size = 0;
+ }
+
+ ~Array()
+ {
+ destruct_n(m_data, m_size);
+ if (m_data != nullptr) {
+ m_allocator.deallocate((void *)m_data);
+ }
+ }
+
+ Array &operator=(const Array &other)
+ {
+ if (this == &other) {
+ return *this;
+ }
+
+ this->~Array();
+ new (this) Array(other);
+ return *this;
+ }
+
+ Array &operator=(Array &&other)
+ {
+ if (this == &other) {
+ return *this;
+ }
+
+ this->~Array();
+ new (this) Array(std::move(other));
+ return *this;
+ }
+
+ operator ArrayRef<T>() const
+ {
+ return ArrayRef<T>(m_data, m_size);
+ }
+
+ T &operator[](uint index)
+ {
+ BLI_assert(index < m_size);
+ return m_data[index];
+ }
+
+ uint size() const
+ {
+ return m_size;
+ }
+
+ void fill(const T &value)
+ {
+ ArrayRef<T>(*this).fill(value);
+ }
+
+ void fill_indices(ArrayRef<uint> indices, const T &value)
+ {
+ ArrayRef<T>(*this).fill_indices(indices, value);
+ }
+
+ T *begin()
+ {
+ return m_data;
+ }
+
+ T *end()
+ {
+ return m_data + m_size;
+ }
+
+ private:
+ T *allocate(uint size)
+ {
+ return (T *)m_allocator.allocate_aligned(
+ size * sizeof(T), std::alignment_of<T>::value, __func__);
+ }
+};
+
+template<typename T> using TemporaryArray = Array<T, TemporaryAllocator>;
+
+} // namespace BLI
diff --git a/source/blender/blenlib/BLI_map.hpp b/source/blender/blenlib/BLI_map.hpp
index e39b9e69e2a..0a2024d5d0c 100644
--- a/source/blender/blenlib/BLI_map.hpp
+++ b/source/blender/blenlib/BLI_map.hpp
@@ -30,7 +30,7 @@
namespace BLI {
-template<typename KeyT, typename ValueT> class Map {
+template<typename KeyT, typename ValueT, typename Allocator = GuardedAllocator> class Map {
private:
static constexpr uint32_t OFFSET_MASK = 3;
static constexpr uint8_t IS_EMPTY = 0;
@@ -143,7 +143,8 @@ template<typename KeyT, typename ValueT> class Map {
}
};
- OpenAddressingArray<Item> m_array;
+ using ArrayType = OpenAddressingArray<Item, 1, Allocator>;
+ ArrayType m_array;
public:
Map() = default;
@@ -497,7 +498,7 @@ template<typename KeyT, typename ValueT> class Map {
void grow(uint32_t min_usable_slots)
{
- OpenAddressingArray<Item> new_array = m_array.init_reserved(min_usable_slots);
+ ArrayType new_array = m_array.init_reserved(min_usable_slots);
for (Item &old_item : m_array) {
for (uint32_t offset = 0; offset < 4; offset++) {
if (old_item.status(offset) == IS_SET) {
@@ -508,7 +509,7 @@ template<typename KeyT, typename ValueT> class Map {
m_array = std::move(new_array);
}
- void add_after_grow(KeyT &key, ValueT &value, OpenAddressingArray<Item> &new_array)
+ void add_after_grow(KeyT &key, ValueT &value, ArrayType &new_array)
{
ITER_SLOTS_BEGIN (key, new_array, , item, offset) {
if (item.status(offset) == IS_EMPTY) {
diff --git a/source/blender/blenlib/BLI_memory.hpp b/source/blender/blenlib/BLI_memory.hpp
index 4943ded779f..5fe427e02b8 100644
--- a/source/blender/blenlib/BLI_memory.hpp
+++ b/source/blender/blenlib/BLI_memory.hpp
@@ -17,7 +17,7 @@ template<typename T> void destruct(T *ptr)
ptr->~T();
}
-template<typename T> void descruct_n(T *ptr, uint n)
+template<typename T> void destruct_n(T *ptr, uint n)
{
for (uint i = 0; i < n; i++) {
ptr[i].~T();
@@ -43,7 +43,7 @@ template<typename T> void uninitialized_relocate(T *src, T *dst)
template<typename T> void uninitialized_relocate_n(T *src, uint n, T *dst)
{
uninitialized_move_n(src, n, dst);
- descruct_n(src, n);
+ destruct_n(src, n);
}
template<typename T> void relocate(T *src, T *dst)
@@ -55,7 +55,7 @@ template<typename T> void relocate(T *src, T *dst)
template<typename T> void relocate_n(T *src, uint n, T *dst)
{
move_n(src, n, dst);
- descruct_n(src, n);
+ destruct_n(src, n);
}
} // namespace BLI
diff --git a/source/blender/blenlib/BLI_open_addressing.hpp b/source/blender/blenlib/BLI_open_addressing.hpp
index 73c13bff53a..9ce63603469 100644
--- a/source/blender/blenlib/BLI_open_addressing.hpp
+++ b/source/blender/blenlib/BLI_open_addressing.hpp
@@ -3,11 +3,12 @@
#include "BLI_utildefines.h"
#include "BLI_memory.hpp"
#include "BLI_math_base.h"
-#include "MEM_guardedalloc.h"
+#include "BLI_allocator.hpp"
namespace BLI {
-template<typename Item, uint32_t ItemsInSmallStorage = 1> class OpenAddressingArray {
+template<typename Item, uint32_t ItemsInSmallStorage = 1, typename Allocator = GuardedAllocator>
+class OpenAddressingArray {
private:
static constexpr auto slots_per_item = Item::slots_per_item;
@@ -18,6 +19,7 @@ template<typename Item, uint32_t ItemsInSmallStorage = 1> class OpenAddressingAr
uint32_t m_slots_set_or_dummy;
uint32_t m_slots_dummy;
uint32_t m_slot_mask;
+ Allocator m_allocator;
char m_local_storage[sizeof(Item) * ItemsInSmallStorage];
public:
@@ -34,7 +36,8 @@ template<typename Item, uint32_t ItemsInSmallStorage = 1> class OpenAddressingAr
m_items = this->small_storage();
}
else {
- m_items = reinterpret_cast<Item *>(MEM_malloc_arrayN(m_item_amount, sizeof(Item), __func__));
+ m_items = (Item *)m_allocator.allocate_aligned(
+ sizeof(Item) * m_item_amount, std::alignment_of<Item>::value, __func__);
}
for (uint32_t i = 0; i < m_item_amount; i++) {
@@ -49,7 +52,7 @@ template<typename Item, uint32_t ItemsInSmallStorage = 1> class OpenAddressingAr
m_items[i].~Item();
}
if (!this->is_in_small_storage()) {
- MEM_freeN(static_cast<void *>(m_items));
+ m_allocator.deallocate((void *)m_items);
}
}
}
@@ -67,7 +70,8 @@ template<typename Item, uint32_t ItemsInSmallStorage = 1> class OpenAddressingAr
m_items = this->small_storage();
}
else {
- m_items = static_cast<Item *>(MEM_malloc_arrayN(m_item_amount, sizeof(Item), __func__));
+ m_items = (Item *)m_allocator.allocate_aligned(
+ sizeof(Item) * m_item_amount, std::alignment_of<Item>::value, __func__);
}
uninitialized_copy_n(other.m_items, m_item_amount, m_items);
diff --git a/source/blender/blenlib/BLI_set.hpp b/source/blender/blenlib/BLI_set.hpp
index 8fc00690cc5..1c66ca7616b 100644
--- a/source/blender/blenlib/BLI_set.hpp
+++ b/source/blender/blenlib/BLI_set.hpp
@@ -6,7 +6,7 @@
namespace BLI {
-template<typename T> class Set {
+template<typename T, typename Allocator = GuardedAllocator> class Set {
private:
static constexpr uint32_t OFFSET_MASK = 3;
static constexpr uint8_t IS_EMPTY = 0;
@@ -111,7 +111,8 @@ template<typename T> class Set {
}
};
- OpenAddressingArray<Item> m_array = OpenAddressingArray<Item>();
+ using ArrayType = OpenAddressingArray<Item, 1, Allocator>;
+ ArrayType m_array = OpenAddressingArray<Item>();
public:
Set() = default;
@@ -362,7 +363,7 @@ template<typename T> class Set {
void grow(uint32_t min_usable_slots)
{
// std::cout << "Grow at " << m_array.slots_set() << '/' << m_array.slots_total() << '\n';
- OpenAddressingArray<Item> new_array = m_array.init_reserved(min_usable_slots);
+ ArrayType new_array = m_array.init_reserved(min_usable_slots);
for (Item &old_item : m_array) {
for (uint8_t offset = 0; offset < 4; offset++) {
@@ -375,7 +376,7 @@ template<typename T> class Set {
m_array = std::move(new_array);
}
- void add_after_grow(T &old_value, OpenAddressingArray<Item> &new_array)
+ void add_after_grow(T &old_value, ArrayType &
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list