[Bf-blender-cvs] [55032077303] functions: use scoped array allocations to simplify memory management

Jacques Lucke noreply at git.blender.org
Mon Jul 8 17:56:37 CEST 2019


Commit: 55032077303ae137d3c2b1a1accde48b4edd5c0e
Author: Jacques Lucke
Date:   Mon Jul 8 11:00:41 2019 +0200
Branches: functions
https://developer.blender.org/rB55032077303ae137d3c2b1a1accde48b4edd5c0e

use scoped array allocations to simplify memory management

===================================================================

M	source/blender/blenlib/BLI_fixed_array_allocator.hpp
M	source/blender/simulations/bparticles/simulate.cpp

===================================================================

diff --git a/source/blender/blenlib/BLI_fixed_array_allocator.hpp b/source/blender/blenlib/BLI_fixed_array_allocator.hpp
index 810886bba37..a1471f44840 100644
--- a/source/blender/blenlib/BLI_fixed_array_allocator.hpp
+++ b/source/blender/blenlib/BLI_fixed_array_allocator.hpp
@@ -62,6 +62,57 @@ class FixedArrayAllocator {
     return this->deallocate_array(ptr, sizeof(T));
   }
 
+  template<typename T> class ScopedAllocation {
+   private:
+    FixedArrayAllocator &m_allocator;
+    void *m_ptr;
+    uint m_element_size;
+
+   public:
+    ScopedAllocation(FixedArrayAllocator &allocator, T *ptr, uint element_size)
+        : m_allocator(allocator), m_ptr(ptr), m_element_size(element_size)
+    {
+    }
+
+    ScopedAllocation(ScopedAllocation &other) = delete;
+    ScopedAllocation(ScopedAllocation &&other)
+        : m_allocator(other.m_allocator), m_ptr(other.m_ptr), m_element_size(other.m_element_size)
+    {
+      other.m_ptr = nullptr;
+    }
+
+    ScopedAllocation &operator=(ScopedAllocation &other) = delete;
+    ScopedAllocation &operator=(ScopedAllocation &&other)
+    {
+      this->~ScopedAllocation();
+      new (this) ScopedAllocation(std::move(other));
+      return *this;
+    }
+
+    ~ScopedAllocation()
+    {
+      if (m_ptr != nullptr) {
+        m_allocator.deallocate_array(m_ptr, m_element_size);
+      }
+    }
+
+    operator T *() const
+    {
+      return (T *)m_ptr;
+    }
+  };
+
+  ScopedAllocation<void> allocate_array_scoped(uint element_size)
+  {
+    return ScopedAllocation<void>(*this, this->allocate_array(element_size), element_size);
+  }
+
+  template<typename T> ScopedAllocation<T> allocate_array_scoped()
+  {
+    return ScopedAllocation<T>(*this, this->allocate_array<T>(), sizeof(T));
+  }
+
+ private:
   SmallStack<void *> &stack_for_element_size(uint element_size)
   {
     BLI_assert(element_size > 0);
diff --git a/source/blender/simulations/bparticles/simulate.cpp b/source/blender/simulations/bparticles/simulate.cpp
index dcbe8652800..46dea387b7b 100644
--- a/source/blender/simulations/bparticles/simulate.cpp
+++ b/source/blender/simulations/bparticles/simulate.cpp
@@ -234,10 +234,10 @@ BLI_NOINLINE static void simulate_to_next_event(FixedArrayAllocator &array_alloc
   uint amount = particles.size();
 
   BLI_assert(array_allocator.array_size() >= amount);
-  int *next_event_indices_array = array_allocator.allocate_array<int>();
-  float *time_factors_to_next_event_array = array_allocator.allocate_array<float>();
-  uint *indices_with_event_array = array_allocator.allocate_array<uint>();
-  uint *particle_indices_with_event_array = array_allocator.allocate_array<uint>();
+  auto next_event_indices_array = array_allocator.allocate_array_scoped<int>();
+  auto time_factors_to_next_event_array = array_allocator.allocate_array_scoped<float>();
+  auto indices_with_event_array = array_allocator.allocate_array_scoped<uint>();
+  auto particle_indices_with_event_array = array_allocator.allocate_array_scoped<uint>();
 
   VectorAdaptor<int> next_event_indices(next_event_indices_array, amount, amount);
   VectorAdaptor<float> time_factors_to_next_event(
@@ -246,7 +246,7 @@ BLI_NOINLINE static void simulate_to_next_event(FixedArrayAllocator &array_alloc
   VectorAdaptor<uint> particle_indices_with_event(particle_indices_with_event_array, amount);
 
   uint max_event_storage_size = std::max(get_max_event_storage_size(events), 1u);
-  void *event_storage_array = array_allocator.allocate_array(max_event_storage_size);
+  auto event_storage_array = array_allocator.allocate_array_scoped(max_event_storage_size);
   EventStorage event_storage(event_storage_array, max_event_storage_size);
 
   find_next_event_per_particle(particles,
@@ -295,12 +295,6 @@ BLI_NOINLINE static void simulate_to_next_event(FixedArrayAllocator &array_alloc
                             particles.attributes().get_byte("Kill State"),
                             r_unfinished_particle_indices,
                             r_remaining_durations);
-
-  array_allocator.deallocate_array(next_event_indices_array);
-  array_allocator.deallocate_array(time_factors_to_next_event_array);
-  array_allocator.deallocate_array(indices_with_event_array);
-  array_allocator.deallocate_array(particle_indices_with_event_array);
-  array_allocator.deallocate_array(event_storage_array, max_event_storage_size);
 }
 
 BLI_NOINLINE static void simulate_with_max_n_events(
@@ -315,10 +309,10 @@ BLI_NOINLINE static void simulate_with_max_n_events(
     VectorAdaptor<uint> &r_unfinished_particle_indices)
 {
   BLI_assert(array_allocator.array_size() >= block.active_amount());
-  uint *indices_A = array_allocator.allocate_array<uint>();
-  uint *indices_B = array_allocator.allocate_array<uint>();
-  float *durations_A = array_allocator.allocate_array<float>();
-  float *durations_B = array_allocator.allocate_array<float>();
+  auto indices_A = array_allocator.allocate_array_scoped<uint>();
+  auto indices_B = array_allocator.allocate_array_scoped<uint>();
+  auto durations_A = array_allocator.allocate_array_scoped<float>();
+  auto durations_B = array_allocator.allocate_array_scoped<float>();
 
   /* Handle first event separately to be able to use the static number range. */
   uint amount_left = block.active_amount();
@@ -364,11 +358,6 @@ BLI_NOINLINE static void simulate_with_max_n_events(
   for (uint i = 0; i < amount_left; i++) {
     r_unfinished_particle_indices.append(indices_A[i]);
   }
-
-  array_allocator.deallocate_array(indices_A);
-  array_allocator.deallocate_array(indices_B);
-  array_allocator.deallocate_array(durations_A);
-  array_allocator.deallocate_array(durations_B);
 }
 
 BLI_NOINLINE static void add_float3_arrays(ArrayRef<float3> base, ArrayRef<float3> values)



More information about the Bf-blender-cvs mailing list