1 /**
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://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,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "mem/arena.h"
17 #include "mem/pool_manager.h"
18 #include "mem/mem.h"
19 #include "mem/mem_config.h"
20 #include "mem/mmap_mem_pool-inl.h"
21
22 #include "gtest/gtest.h"
23 #include "utils/logger.h"
24
25 namespace panda {
26
27 class ArenaTest : public testing::Test {
28 public:
ArenaTest()29 ArenaTest()
30 {
31 panda::mem::MemConfig::Initialize(0, 16_MB, 0, 0);
32 PoolManager::Initialize();
33 }
34
~ArenaTest()35 ~ArenaTest()
36 {
37 PoolManager::Finalize();
38 panda::mem::MemConfig::Finalize();
39 }
40
41 protected:
42 static constexpr size_t ARENA_SIZE = 1_MB;
43
44 template <class ArenaT>
CreateArena(size_t size)45 ArenaT *CreateArena(size_t size)
46 {
47 return PoolManager::GetMmapMemPool()->AllocArena<ArenaT>(size, SpaceType::SPACE_TYPE_INTERNAL,
48 AllocatorType::ARENA_ALLOCATOR);
49 }
50
51 template <class ArenaT>
GetOccupiedAndFreeSizeTestImplementation(size_t arena_size, size_t alloc_size)52 void GetOccupiedAndFreeSizeTestImplementation(size_t arena_size, size_t alloc_size)
53 {
54 ASSERT_TRUE(arena_size != 0);
55 ASSERT_TRUE(alloc_size != 0);
56 ArenaT *arena = CreateArena<ArenaT>(arena_size);
57 size_t old_free_size = arena->GetFreeSize();
58 ASSERT_TRUE(arena->Alloc(alloc_size) != nullptr);
59 ASSERT_TRUE(arena->GetOccupiedSize() == alloc_size);
60 ASSERT_TRUE(old_free_size - alloc_size == arena->GetFreeSize());
61 }
62
63 template <class ArenaT>
ResizeAndResetTestImplementation(size_t arena_size, size_t alloc_size)64 void ResizeAndResetTestImplementation(size_t arena_size, size_t alloc_size)
65 {
66 constexpr const int64_t immTwo = 2;
67 ASSERT_TRUE(arena_size != 0);
68 ASSERT_TRUE(alloc_size != 0);
69 ArenaT *arena = CreateArena<ArenaT>(arena_size);
70 ASSERT_TRUE(alloc_size * immTwo <= arena->GetFreeSize());
71 void *first_allocation = arena->Alloc(alloc_size);
72 void *second_allocation = arena->Alloc(alloc_size);
73 ASSERT_TRUE(first_allocation != nullptr);
74 ASSERT_TRUE(first_allocation != nullptr);
75 ASSERT_TRUE(arena->GetOccupiedSize() == immTwo * alloc_size);
76 arena->Resize(alloc_size);
77 ASSERT_TRUE(arena->GetOccupiedSize() == alloc_size);
78 void *third_allocation = arena->Alloc(alloc_size);
79 // we expect that we get the same address
80 ASSERT_TRUE(ToUintPtr(second_allocation) == ToUintPtr(third_allocation));
81 ASSERT_TRUE(arena->GetOccupiedSize() == immTwo * alloc_size);
82 arena->Reset();
83 ASSERT_TRUE(arena->GetOccupiedSize() == 0);
84 }
85 };
86
TEST_F(ArenaTest, GetOccupiedAndFreeSizeTest)87 TEST_F(ArenaTest, GetOccupiedAndFreeSizeTest)
88 {
89 static constexpr size_t ALLOC_SIZE = AlignUp(ARENA_SIZE / 2, GetAlignmentInBytes(ARENA_DEFAULT_ALIGNMENT));
90 static constexpr Alignment ARENA_ALIGNMENT = LOG_ALIGN_4;
91 static constexpr size_t ALIGNED_ALLOC_SIZE = AlignUp(ALLOC_SIZE, GetAlignmentInBytes(ARENA_ALIGNMENT));
92 GetOccupiedAndFreeSizeTestImplementation<Arena>(ARENA_SIZE, ALLOC_SIZE);
93 GetOccupiedAndFreeSizeTestImplementation<AlignedArena<ARENA_ALIGNMENT>>(ARENA_SIZE, ALIGNED_ALLOC_SIZE);
94 GetOccupiedAndFreeSizeTestImplementation<DoubleLinkedAlignedArena<ARENA_ALIGNMENT>>(ARENA_SIZE, ALIGNED_ALLOC_SIZE);
95 }
96
TEST_F(ArenaTest, ResizeAndResetTest)97 TEST_F(ArenaTest, ResizeAndResetTest)
98 {
99 static constexpr size_t ALLOC_SIZE = AlignUp(ARENA_SIZE / 3, GetAlignmentInBytes(ARENA_DEFAULT_ALIGNMENT));
100 static constexpr Alignment ARENA_ALIGNMENT = LOG_ALIGN_4;
101 static constexpr size_t ALIGNED_ALLOC_SIZE = AlignUp(ALLOC_SIZE, GetAlignmentInBytes(ARENA_ALIGNMENT));
102 ResizeAndResetTestImplementation<Arena>(ARENA_SIZE, ALLOC_SIZE);
103 ResizeAndResetTestImplementation<AlignedArena<ARENA_ALIGNMENT>>(ARENA_SIZE, ALIGNED_ALLOC_SIZE);
104 ResizeAndResetTestImplementation<DoubleLinkedAlignedArena<ARENA_ALIGNMENT>>(ARENA_SIZE, ALIGNED_ALLOC_SIZE);
105 }
106
107 } // namespace panda
108