BLI: support transferring ownership of buffers between linear allocators
This can be useful when e.g. each thread has its own `LinearAllocator`, but in the end they are combined into one.
This commit is contained in:
@@ -211,6 +211,25 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
|
||||
this->provide_buffer(aligned_buffer.ptr(), Size);
|
||||
}
|
||||
|
||||
/**
|
||||
* This allocator takes ownership of the buffers owned by `other`. Therefor, when `other` is
|
||||
* destructed, memory allocated using it is not freed.
|
||||
*
|
||||
* Note that the caller is responsible for making sure that buffers passed into #provide_buffer
|
||||
* of `other` live at least as long as this allocator.
|
||||
*/
|
||||
void transfer_ownership_from(LinearAllocator<> &other)
|
||||
{
|
||||
owned_buffers_.extend(other.owned_buffers_);
|
||||
#ifdef BLI_DEBUG_LINEAR_ALLOCATOR_SIZE
|
||||
user_requested_size_ += other.user_requested_size_;
|
||||
owned_allocation_size_ += other.owned_allocation_size_;
|
||||
#endif
|
||||
other.owned_buffers_.clear();
|
||||
std::destroy_at(&other);
|
||||
new (&other) LinearAllocator<>();
|
||||
}
|
||||
|
||||
private:
|
||||
void allocate_new_buffer(int64_t min_allocation_size, int64_t min_alignment)
|
||||
{
|
||||
|
||||
@@ -149,4 +149,23 @@ TEST(linear_allocator, ConstructArray)
|
||||
}
|
||||
}
|
||||
|
||||
TEST(linear_allocator, TransferOwnership)
|
||||
{
|
||||
LinearAllocator<> main_allocator;
|
||||
MutableSpan<int> values;
|
||||
|
||||
/* Allocate a large buffer that is likely to be given back to the system when freed. This test
|
||||
* essentially only fails by crashing with a segfault. */
|
||||
const int size = 1'000'000;
|
||||
const int value = 42;
|
||||
const int index = 500'000;
|
||||
{
|
||||
LinearAllocator<> nested_allocator;
|
||||
values = nested_allocator.allocate_array<int>(size);
|
||||
values[index] = value;
|
||||
main_allocator.transfer_ownership_from(nested_allocator);
|
||||
}
|
||||
EXPECT_EQ(values[index], value);
|
||||
}
|
||||
|
||||
} // namespace blender::tests
|
||||
|
||||
Reference in New Issue
Block a user