• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 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_malloc/malloc.h"
16 
17 #include <cstdint>
18 
19 #include "pw_unit_test/framework.h"
20 
21 namespace {
22 
23 class MallocTest : public ::testing::Test {
24  protected:
SetUp()25   void SetUp() override { pw::malloc::InitSystemAllocator(heap_); }
26 
27  private:
28   std::array<std::byte, 1024> heap_;
29 };
30 
TEST_F(MallocTest,MallocFree)31 TEST_F(MallocTest, MallocFree) {
32   constexpr size_t kSize = 256;
33   auto& system_metrics = pw::malloc::GetSystemMetrics();
34   EXPECT_EQ(system_metrics.allocated_bytes.value(), 0U);
35 
36   void* ptr = malloc(kSize);
37   ASSERT_NE(ptr, nullptr);
38   EXPECT_EQ(system_metrics.requested_bytes.value(), kSize);
39 
40   free(ptr);
41   EXPECT_EQ(system_metrics.allocated_bytes.value(), 0U);
42 }
43 
TEST_F(MallocTest,NewDelete)44 TEST_F(MallocTest, NewDelete) {
45   constexpr size_t kSize = 256;
46   auto& system_metrics = pw::malloc::GetSystemMetrics();
47   EXPECT_EQ(system_metrics.allocated_bytes.value(), 0U);
48 
49   auto* ptr = new std::array<std::byte, kSize>();
50   ASSERT_NE(ptr, nullptr);
51   EXPECT_GE(system_metrics.allocated_bytes.value(), kSize);
52 
53   delete (ptr);
54   EXPECT_EQ(system_metrics.allocated_bytes.value(), 0U);
55 }
56 
TEST_F(MallocTest,CallocFree)57 TEST_F(MallocTest, CallocFree) {
58   constexpr size_t kNum = 4;
59   constexpr size_t kSize = 64;
60   auto& system_metrics = pw::malloc::GetSystemMetrics();
61   EXPECT_EQ(system_metrics.allocated_bytes.value(), 0U);
62 
63   void* ptr = calloc(kNum, kSize);
64   ASSERT_NE(ptr, nullptr);
65   EXPECT_EQ(system_metrics.requested_bytes.value(), kNum * kSize);
66 
67   free(ptr);
68   EXPECT_EQ(system_metrics.allocated_bytes.value(), 0U);
69 }
70 
TEST_F(MallocTest,ReallocFree)71 TEST_F(MallocTest, ReallocFree) {
72   constexpr size_t kSize = 256;
73   auto& system_metrics = pw::malloc::GetSystemMetrics();
74   EXPECT_EQ(system_metrics.allocated_bytes.value(), 0U);
75 
76   void* ptr = realloc(nullptr, kSize);
77   ASSERT_NE(ptr, nullptr);
78   EXPECT_EQ(system_metrics.requested_bytes.value(), kSize);
79 
80   free(ptr);
81   EXPECT_EQ(system_metrics.allocated_bytes.value(), 0U);
82 }
83 
TEST_F(MallocTest,MallocReallocFree)84 TEST_F(MallocTest, MallocReallocFree) {
85   constexpr size_t kSize1 = 256;
86   constexpr size_t kSize2 = 512;
87   auto& system_metrics = pw::malloc::GetSystemMetrics();
88   EXPECT_EQ(system_metrics.allocated_bytes.value(), 0U);
89 
90   void* ptr = malloc(kSize1);
91   ASSERT_NE(ptr, nullptr);
92   EXPECT_EQ(system_metrics.requested_bytes.value(), kSize1);
93   std::memset(ptr, 1, kSize1);
94 
95   void* new_ptr = realloc(ptr, kSize2);
96   ASSERT_NE(ptr, nullptr);
97   EXPECT_EQ(system_metrics.requested_bytes.value(), kSize2);
98 
99   // Using `new_ptr` prevents the call to `realloc from being optimized away.
100   auto* bytes = std::launder(reinterpret_cast<uint8_t*>(new_ptr));
101   for (size_t i = 0; i < kSize1; ++i) {
102     EXPECT_EQ(bytes[i], 1U);
103   }
104 
105   free(new_ptr);
106   EXPECT_EQ(system_metrics.allocated_bytes.value(), 0U);
107 }
108 
109 }  // namespace
110