xref: /aosp_15_r20/external/pigweed/pw_allocator/bump_allocator_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 #include "pw_allocator/bump_allocator.h"
16 
17 #include <cstring>
18 
19 #include "lib/stdcompat/bit.h"
20 #include "pw_unit_test/framework.h"
21 
22 namespace {
23 
24 // Test fixtures.
25 
26 using ::pw::allocator::BumpAllocator;
27 using ::pw::allocator::Layout;
28 
29 class DestroyCounter final {
30  public:
DestroyCounter(size_t * counter)31   DestroyCounter(size_t* counter) : counter_(counter) {}
~DestroyCounter()32   ~DestroyCounter() { *counter_ += 1; }
33 
34  private:
35   size_t* counter_;
36 };
37 
38 // Unit tests.
39 
TEST(BumpAllocatorTest,ExplicitlyInit)40 TEST(BumpAllocatorTest, ExplicitlyInit) {
41   alignas(16) std::array<std::byte, 256> buffer;
42   BumpAllocator allocator;
43   allocator.Init(buffer);
44 }
45 
TEST(BumpAllocatorTest,AllocateValid)46 TEST(BumpAllocatorTest, AllocateValid) {
47   alignas(16) std::array<std::byte, 256> buffer;
48   BumpAllocator allocator(buffer);
49   void* ptr = allocator.Allocate(Layout(64, 16));
50   ASSERT_NE(ptr, nullptr);
51 }
52 
TEST(BumpAllocatorTest,AllocateAligned)53 TEST(BumpAllocatorTest, AllocateAligned) {
54   alignas(16) std::array<std::byte, 256> buffer;
55   BumpAllocator allocator(buffer);
56   void* ptr = allocator.Allocate(Layout(1, 1));
57   ASSERT_NE(ptr, nullptr);
58 
59   // Last pointer was aligned, so next won't automatically be.
60   ptr = allocator.Allocate(Layout(8, 32));
61   ASSERT_NE(ptr, nullptr);
62   EXPECT_EQ(cpp20::bit_cast<uintptr_t>(ptr) % 32, 0U);
63 }
64 
TEST(BumpAllocatorTest,AllocateFailsWhenExhausted)65 TEST(BumpAllocatorTest, AllocateFailsWhenExhausted) {
66   alignas(16) std::array<std::byte, 256> buffer;
67   BumpAllocator allocator(buffer);
68   void* ptr = allocator.Allocate(Layout(256, 16));
69   ASSERT_NE(ptr, nullptr);
70   ptr = allocator.Allocate(Layout(1, 1));
71   EXPECT_EQ(ptr, nullptr);
72 }
73 
TEST(BumpAllocatorTest,DeallocateDoesNothing)74 TEST(BumpAllocatorTest, DeallocateDoesNothing) {
75   alignas(16) std::array<std::byte, 256> buffer;
76   BumpAllocator allocator(buffer);
77   void* ptr = allocator.Allocate(Layout(256, 16));
78   ASSERT_NE(ptr, nullptr);
79   allocator.Deallocate(ptr);
80   ptr = allocator.Allocate(Layout(1, 1));
81   EXPECT_EQ(ptr, nullptr);
82 }
83 
TEST(BumpAllocatorTest,NewDoesNotDestroy)84 TEST(BumpAllocatorTest, NewDoesNotDestroy) {
85   alignas(16) std::array<std::byte, 256> buffer;
86   size_t counter = 0;
87   {
88     BumpAllocator allocator(buffer);
89     DestroyCounter* dc1 = allocator.New<DestroyCounter>(&counter);
90     EXPECT_EQ(counter, 0U);
91     allocator.Delete(dc1);
92   }
93   EXPECT_EQ(counter, 0U);
94 }
95 
TEST(BumpAllocatorTest,DeleteDoesNothing)96 TEST(BumpAllocatorTest, DeleteDoesNothing) {
97   alignas(16) std::array<std::byte, 256> buffer;
98   size_t counter = 0;
99   BumpAllocator allocator(buffer);
100   DestroyCounter* dc1 = allocator.New<DestroyCounter>(&counter);
101   EXPECT_EQ(counter, 0U);
102   allocator.Delete(dc1);
103   EXPECT_EQ(counter, 0U);
104 }
105 
TEST(BumpAllocatorTest,NewOwnedDestroys)106 TEST(BumpAllocatorTest, NewOwnedDestroys) {
107   alignas(16) std::array<std::byte, 256> buffer;
108   size_t counter = 0;
109   {
110     BumpAllocator allocator(buffer);
111     allocator.NewOwned<DestroyCounter>(&counter);
112     EXPECT_EQ(counter, 0U);
113   }
114   EXPECT_EQ(counter, 1U);
115 }
116 
TEST(BumpAllocatorTest,MakeUniqueDoesNotDestroy)117 TEST(BumpAllocatorTest, MakeUniqueDoesNotDestroy) {
118   alignas(16) std::array<std::byte, 256> buffer;
119   size_t counter = 0;
120   {
121     BumpAllocator allocator(buffer);
122     allocator.MakeUnique<DestroyCounter>(&counter).get();
123     EXPECT_EQ(counter, 0U);
124   }
125   EXPECT_EQ(counter, 0U);
126 }
127 
TEST(BumpAllocatorTest,MakeUniqueOwnedDestroys)128 TEST(BumpAllocatorTest, MakeUniqueOwnedDestroys) {
129   alignas(16) std::array<std::byte, 256> buffer;
130   size_t counter = 0;
131   {
132     BumpAllocator allocator(buffer);
133     allocator.MakeUniqueOwned<DestroyCounter>(&counter).get();
134     EXPECT_EQ(counter, 0U);
135   }
136   EXPECT_EQ(counter, 1U);
137 }
138 
139 }  // namespace
140