diff options
author | Jacques Lucke <mail@jlucke.com> | 2020-02-10 15:54:57 +0300 |
---|---|---|
committer | Jacques Lucke <mail@jlucke.com> | 2020-02-10 16:09:01 +0300 |
commit | 68cc982dcb7c1063a96f7ec9b7ccb95da4919d6b (patch) | |
tree | 9d2076363b54cb6b6da96064453ac3499a5f65c8 /source/blender/blenlib/intern | |
parent | 76208a5670bc9d70f99f22a3c49463959461b5c1 (diff) |
BLI: improve various C++ data structures
The changes come from the `functions` branch, where I'm using
these structures a lot.
This also includes a new `BLI::Optional<T>` type, which is similar
to `std::Optional<T>` which can be used when Blender starts using
C++17.
Diffstat (limited to 'source/blender/blenlib/intern')
-rw-r--r-- | source/blender/blenlib/intern/BLI_index_range.cc | 4 | ||||
-rw-r--r-- | source/blender/blenlib/intern/BLI_temporary_allocator.cc | 115 |
2 files changed, 2 insertions, 117 deletions
diff --git a/source/blender/blenlib/intern/BLI_index_range.cc b/source/blender/blenlib/intern/BLI_index_range.cc index fde4dcf6d41..6421eb0794b 100644 --- a/source/blender/blenlib/intern/BLI_index_range.cc +++ b/source/blender/blenlib/intern/BLI_index_range.cc @@ -24,7 +24,7 @@ namespace BLI { -static Vector<Array<uint, RawAllocator>, 1, RawAllocator> arrays; +static Vector<Array<uint, 0, RawAllocator>, 1, RawAllocator> arrays; static uint current_array_size = 0; static uint *current_array = nullptr; static std::mutex current_array_mutex; @@ -44,7 +44,7 @@ ArrayRef<uint> IndexRange::as_array_ref() const } uint new_size = std::max<uint>(1000, power_of_2_max_u(min_required_size)); - Array<uint, RawAllocator> new_array(new_size); + Array<uint, 0, RawAllocator> new_array(new_size); for (uint i = 0; i < new_size; i++) { new_array[i] = i; } diff --git a/source/blender/blenlib/intern/BLI_temporary_allocator.cc b/source/blender/blenlib/intern/BLI_temporary_allocator.cc deleted file mode 100644 index b145e65530d..00000000000 --- a/source/blender/blenlib/intern/BLI_temporary_allocator.cc +++ /dev/null @@ -1,115 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include <mutex> -#include <stack> - -#include "BLI_temporary_allocator.h" -#include "BLI_stack_cxx.h" - -using namespace BLI; - -constexpr uint ALIGNMENT = BLI_TEMPORARY_BUFFER_ALIGNMENT; -constexpr uint SMALL_BUFFER_SIZE = 64 * 1024; -constexpr uintptr_t ALIGNMENT_MASK = ~(uintptr_t)(ALIGNMENT - 1); - -enum TemporaryBufferType { - Small, - Large, -}; - -struct MemHead { - void *raw_ptr; - TemporaryBufferType type; -}; - -static MemHead &get_memhead(void *aligned_ptr) -{ - return *((MemHead *)aligned_ptr - 1); -} - -static void *raw_allocate(uint size) -{ - uint total_allocation_size = size + ALIGNMENT + sizeof(MemHead); - - uintptr_t raw_ptr = (uintptr_t)malloc(total_allocation_size); - uintptr_t aligned_ptr = (raw_ptr + ALIGNMENT + sizeof(MemHead)) & ALIGNMENT_MASK; - - MemHead &memhead = get_memhead((void *)aligned_ptr); - memhead.raw_ptr = (void *)raw_ptr; - return (void *)aligned_ptr; -} - -static void raw_deallocate(void *ptr) -{ - BLI_assert(((uintptr_t)ptr & ~ALIGNMENT_MASK) == 0); - MemHead &memhead = get_memhead(ptr); - void *raw_ptr = memhead.raw_ptr; - free(raw_ptr); -} - -struct ThreadLocalBuffers { - uint allocated_amount = 0; - Stack<void *, 32, RawAllocator> buffers; - - ~ThreadLocalBuffers() - { - for (void *ptr : buffers) { - raw_deallocate(ptr); - } - } -}; - -static thread_local ThreadLocalBuffers local_storage; - -void *BLI_temporary_allocate(uint size) -{ - /* The total amount of allocated buffers using this allocator should be limited by a constant. If - * it grows unbounded, there is likely a memory leak somewhere. */ - BLI_assert(local_storage.allocated_amount < 100); - - if (size <= SMALL_BUFFER_SIZE) { - auto &buffers = local_storage.buffers; - if (buffers.empty()) { - void *ptr = raw_allocate(SMALL_BUFFER_SIZE); - MemHead &memhead = get_memhead(ptr); - memhead.type = TemporaryBufferType::Small; - local_storage.allocated_amount++; - return ptr; - } - else { - return buffers.pop(); - } - } - else { - void *ptr = raw_allocate(size); - MemHead &memhead = get_memhead(ptr); - memhead.type = TemporaryBufferType::Large; - return ptr; - } -} - -void BLI_temporary_deallocate(void *buffer) -{ - MemHead &memhead = get_memhead(buffer); - if (memhead.type == TemporaryBufferType::Small) { - auto &buffers = local_storage.buffers; - buffers.push(buffer); - } - else { - raw_deallocate(buffer); - } -} |