Blender  V3.3
BLI_linear_allocator_test.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0 */
2 
4 #include "BLI_rand.hh"
5 #include "BLI_strict_flags.h"
6 #include "testing/testing.h"
7 
8 namespace blender::tests {
9 
10 static bool is_aligned(void *ptr, uint alignment)
11 {
12  BLI_assert(is_power_of_2_i(static_cast<int>(alignment)));
13  return (POINTER_AS_UINT(ptr) & (alignment - 1)) == 0;
14 }
15 
16 TEST(linear_allocator, AllocationAlignment)
17 {
18  LinearAllocator<> allocator;
19 
20  EXPECT_TRUE(is_aligned(allocator.allocate(10, 4), 4));
21  EXPECT_TRUE(is_aligned(allocator.allocate(10, 4), 4));
22  EXPECT_TRUE(is_aligned(allocator.allocate(10, 4), 4));
23  EXPECT_TRUE(is_aligned(allocator.allocate(10, 8), 8));
24  EXPECT_TRUE(is_aligned(allocator.allocate(10, 4), 4));
25  EXPECT_TRUE(is_aligned(allocator.allocate(10, 16), 16));
26  EXPECT_TRUE(is_aligned(allocator.allocate(10, 4), 4));
27  EXPECT_TRUE(is_aligned(allocator.allocate(10, 64), 64));
28  EXPECT_TRUE(is_aligned(allocator.allocate(10, 64), 64));
29  EXPECT_TRUE(is_aligned(allocator.allocate(10, 8), 8));
30  EXPECT_TRUE(is_aligned(allocator.allocate(10, 128), 128));
31 }
32 
33 TEST(linear_allocator, PackedAllocation)
34 {
35  LinearAllocator<> allocator;
37  allocator.provide_buffer(buffer);
38 
39  uintptr_t ptr1 = (uintptr_t)allocator.allocate(10, 4); /* 0 - 10 */
40  uintptr_t ptr2 = (uintptr_t)allocator.allocate(10, 4); /* 12 - 22 */
41  uintptr_t ptr3 = (uintptr_t)allocator.allocate(8, 32); /* 32 - 40 */
42  uintptr_t ptr4 = (uintptr_t)allocator.allocate(16, 8); /* 40 - 56 */
43  uintptr_t ptr5 = (uintptr_t)allocator.allocate(1, 8); /* 56 - 57 */
44  uintptr_t ptr6 = (uintptr_t)allocator.allocate(1, 4); /* 60 - 61 */
45  uintptr_t ptr7 = (uintptr_t)allocator.allocate(1, 1); /* 61 - 62 */
46 
47  EXPECT_EQ(ptr2 - ptr1, 12); /* 12 - 0 = 12 */
48  EXPECT_EQ(ptr3 - ptr2, 20); /* 32 - 12 = 20 */
49  EXPECT_EQ(ptr4 - ptr3, 8); /* 40 - 32 = 8 */
50  EXPECT_EQ(ptr5 - ptr4, 16); /* 56 - 40 = 16 */
51  EXPECT_EQ(ptr6 - ptr5, 4); /* 60 - 56 = 4 */
52  EXPECT_EQ(ptr7 - ptr6, 1); /* 61 - 60 = 1 */
53 }
54 
55 TEST(linear_allocator, CopyString)
56 {
57  LinearAllocator<> allocator;
59  allocator.provide_buffer(buffer);
60 
61  StringRefNull ref1 = allocator.copy_string("Hello");
62  StringRefNull ref2 = allocator.copy_string("World");
63 
64  EXPECT_EQ(ref1, "Hello");
65  EXPECT_EQ(ref2, "World");
66  EXPECT_EQ(ref2.data() - ref1.data(), 6);
67 }
68 
69 TEST(linear_allocator, AllocateArray)
70 {
71  LinearAllocator<> allocator;
72 
73  MutableSpan<int> span = allocator.allocate_array<int>(5);
74  EXPECT_EQ(span.size(), 5);
75 }
76 
77 TEST(linear_allocator, Construct)
78 {
79  LinearAllocator<> allocator;
80 
81  std::array<int, 5> values = {1, 2, 3, 4, 5};
82  Vector<int> *vector = allocator.construct<Vector<int>>(values).release();
83  EXPECT_EQ(vector->size(), 5);
84  EXPECT_EQ((*vector)[3], 4);
85  vector->~Vector();
86 }
87 
88 TEST(linear_allocator, ConstructElementsAndPointerArray)
89 {
90  LinearAllocator<> allocator;
91 
92  std::array<int, 7> values = {1, 2, 3, 4, 5, 6, 7};
94  5, values);
95 
96  EXPECT_EQ(vectors.size(), 5);
97  EXPECT_EQ(vectors[3]->size(), 7);
98  EXPECT_EQ((*vectors[2])[5], 6);
99 
100  for (Vector<int> *vector : vectors) {
101  vector->~Vector();
102  }
103 }
104 
105 TEST(linear_allocator, ConstructArrayCopy)
106 {
107  LinearAllocator<> allocator;
108 
109  Vector<int> values = {1, 2, 3};
110  MutableSpan<int> span1 = allocator.construct_array_copy(values.as_span());
111  MutableSpan<int> span2 = allocator.construct_array_copy(values.as_span());
112  EXPECT_NE(span1.data(), span2.data());
113  EXPECT_EQ(span1.size(), 3);
114  EXPECT_EQ(span2.size(), 3);
115  EXPECT_EQ(span1[1], 2);
116  EXPECT_EQ(span2[2], 3);
117 }
118 
119 TEST(linear_allocator, AllocateLarge)
120 {
121  LinearAllocator<> allocator;
122  void *buffer1 = allocator.allocate(1024 * 1024, 8);
123  void *buffer2 = allocator.allocate(1024 * 1024, 8);
124  EXPECT_NE(buffer1, buffer2);
125 }
126 
127 TEST(linear_allocator, ManyAllocations)
128 {
129  LinearAllocator<> allocator;
131  for (int i = 0; i < 1000; i++) {
132  int size = rng.get_int32(10000);
133  int alignment = 1 << (rng.get_int32(7));
134  void *buffer = allocator.allocate(size, alignment);
135  EXPECT_NE(buffer, nullptr);
136  }
137 }
138 
139 TEST(linear_allocator, ConstructArray)
140 {
141  LinearAllocator<> allocator;
142  MutableSpan<std::string> strings = allocator.construct_array<std::string>(4, "hello");
143  EXPECT_EQ(strings[0], "hello");
144  EXPECT_EQ(strings[1], "hello");
145  EXPECT_EQ(strings[2], "hello");
146  EXPECT_EQ(strings[3], "hello");
147  for (std::string &string : strings) {
148  string.~basic_string();
149  }
150 }
151 
152 } // namespace blender::tests
#define BLI_assert(a)
Definition: BLI_assert.h:46
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
MINLINE int is_power_of_2_i(int n)
Strict compiler flags for areas of code we want to ensure don't do conversions without us knowing abo...
unsigned int uint
Definition: BLI_sys_types.h:67
#define POINTER_AS_UINT(i)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
MutableSpan< T > construct_array_copy(Span< T > src)
StringRefNull copy_string(StringRef str)
Span< T * > construct_elements_and_pointer_array(int64_t n, Args &&...args)
void provide_buffer(void *buffer, uint size)
MutableSpan< T > allocate_array(int64_t size)
destruct_ptr< T > construct(Args &&...args)
void * allocate(const int64_t size, const int64_t alignment)
MutableSpan< T > construct_array(int64_t size, Args &&...args)
constexpr int64_t size() const
Definition: BLI_span.hh:511
constexpr T * data() const
Definition: BLI_span.hh:548
constexpr int64_t size() const
Definition: BLI_span.hh:240
constexpr const char * data() const
Span< T > as_span() const
Definition: BLI_vector.hh:325
ccl_global float * buffer
static bool is_aligned(void *ptr, uint alignment)
TEST(any, DefaultConstructor)
Definition: BLI_any_test.cc:10
_W64 unsigned int uintptr_t
Definition: stdint.h:119
PointerRNA * ptr
Definition: wm_files.c:3480