• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "pw_unit_test/framework.h"
20 
21 namespace {
22 
23 // Test fixtures.
24 
25 using ::pw::allocator::BumpAllocator;
26 using ::pw::allocator::Layout;
27 
28 class DestroyCounter final {
29  public:
DestroyCounter(size_t * counter)30   DestroyCounter(size_t* counter) : counter_(counter) {}
~DestroyCounter()31   ~DestroyCounter() { *counter_ += 1; }
32 
33  private:
34   size_t* counter_;
35 };
36 
37 // Unit tests.
38 
TEST(BumpAllocatorTest,ExplicitlyInit)39 TEST(BumpAllocatorTest, ExplicitlyInit) {
40   alignas(16) std::array<std::byte, 256> buffer;
41   BumpAllocator allocator;
42   allocator.Init(buffer);
43 }
44 
TEST(BumpAllocatorTest,AllocateValid)45 TEST(BumpAllocatorTest, AllocateValid) {
46   alignas(16) std::array<std::byte, 256> buffer;
47   BumpAllocator allocator(buffer);
48   void* ptr = allocator.Allocate(Layout(64, 16));
49   ASSERT_NE(ptr, nullptr);
50 }
51 
TEST(BumpAllocatorTest,AllocateAligned)52 TEST(BumpAllocatorTest, AllocateAligned) {
53   alignas(16) std::array<std::byte, 256> buffer;
54   BumpAllocator allocator(buffer);
55   void* ptr = allocator.Allocate(Layout(1, 1));
56   ASSERT_NE(ptr, nullptr);
57 
58   // Last pointer was aligned, so next won't automatically be.
59   ptr = allocator.Allocate(Layout(8, 32));
60   ASSERT_NE(ptr, nullptr);
61   EXPECT_EQ(reinterpret_cast<uintptr_t>(ptr) % 32, 0U);
62 }
63 
TEST(BumpAllocatorTest,AllocateFailsWhenExhausted)64 TEST(BumpAllocatorTest, AllocateFailsWhenExhausted) {
65   alignas(16) std::array<std::byte, 256> buffer;
66   BumpAllocator allocator(buffer);
67   void* ptr = allocator.Allocate(Layout(256, 16));
68   ASSERT_NE(ptr, nullptr);
69   ptr = allocator.Allocate(Layout(1, 1));
70   EXPECT_EQ(ptr, nullptr);
71 }
72 
TEST(BumpAllocatorTest,DeallocateDoesNothing)73 TEST(BumpAllocatorTest, DeallocateDoesNothing) {
74   alignas(16) std::array<std::byte, 256> buffer;
75   BumpAllocator allocator(buffer);
76   void* ptr = allocator.Allocate(Layout(256, 16));
77   ASSERT_NE(ptr, nullptr);
78   allocator.Deallocate(ptr);
79   ptr = allocator.Allocate(Layout(1, 1));
80   EXPECT_EQ(ptr, nullptr);
81 }
82 
TEST(BumpAllocatorTest,NewDoesNotDestroy)83 TEST(BumpAllocatorTest, NewDoesNotDestroy) {
84   alignas(16) std::array<std::byte, 256> buffer;
85   size_t counter = 0;
86   {
87     BumpAllocator allocator(buffer);
88     DestroyCounter* dc1 = allocator.New<DestroyCounter>(&counter);
89     EXPECT_EQ(counter, 0U);
90     allocator.Delete(dc1);
91   }
92   EXPECT_EQ(counter, 0U);
93 }
94 
TEST(BumpAllocatorTest,DeleteDoesNothing)95 TEST(BumpAllocatorTest, DeleteDoesNothing) {
96   alignas(16) std::array<std::byte, 256> buffer;
97   size_t counter = 0;
98   BumpAllocator allocator(buffer);
99   DestroyCounter* dc1 = allocator.New<DestroyCounter>(&counter);
100   EXPECT_EQ(counter, 0U);
101   allocator.Delete(dc1);
102   EXPECT_EQ(counter, 0U);
103 }
104 
TEST(BumpAllocatorTest,NewOwnedDestroys)105 TEST(BumpAllocatorTest, NewOwnedDestroys) {
106   alignas(16) std::array<std::byte, 256> buffer;
107   size_t counter = 0;
108   {
109     BumpAllocator allocator(buffer);
110     allocator.NewOwned<DestroyCounter>(&counter);
111     EXPECT_EQ(counter, 0U);
112   }
113   EXPECT_EQ(counter, 1U);
114 }
115 
TEST(BumpAllocatorTest,MakeUniqueDoesNotDestroy)116 TEST(BumpAllocatorTest, MakeUniqueDoesNotDestroy) {
117   alignas(16) std::array<std::byte, 256> buffer;
118   size_t counter = 0;
119   {
120     BumpAllocator allocator(buffer);
121     allocator.MakeUnique<DestroyCounter>(&counter).get();
122     EXPECT_EQ(counter, 0U);
123   }
124   EXPECT_EQ(counter, 0U);
125 }
126 
TEST(BumpAllocatorTest,MakeUniqueOwnedDestroys)127 TEST(BumpAllocatorTest, MakeUniqueOwnedDestroys) {
128   alignas(16) std::array<std::byte, 256> buffer;
129   size_t counter = 0;
130   {
131     BumpAllocator allocator(buffer);
132     allocator.MakeUniqueOwned<DestroyCounter>(&counter).get();
133     EXPECT_EQ(counter, 0U);
134   }
135   EXPECT_EQ(counter, 1U);
136 }
137 
138 }  // namespace
139