[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