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 #ifndef LIBPANDABASE_MEM_MALLOC_MEM_POOL_INL_H
17 #define LIBPANDABASE_MEM_MALLOC_MEM_POOL_INL_H
18
19 #include "malloc_mem_pool.h"
20 #include "mem.h"
21 #include "os/mem.h"
22 #include "utils/logger.h"
23 #include <cstdlib>
24 #include <memory>
25
26 namespace panda {
27
28 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
29 #define LOG_MALLOC_MEM_POOL(level) LOG(level, MEMORYPOOL) << "MallocMemPool: "
30
MallocMemPool()31 inline MallocMemPool::MallocMemPool() : MemPool("MallocMemPool")
32 {
33 LOG_MALLOC_MEM_POOL(DEBUG) << "Successfully initialized MallocMemPool";
34 }
35
36 template <class ArenaT>
AllocArenaImpl(size_t size,SpaceType space_type,AllocatorType allocator_type,const void * allocator_addr)37 inline ArenaT *MallocMemPool::AllocArenaImpl(size_t size, [[maybe_unused]] SpaceType space_type,
38 [[maybe_unused]] AllocatorType allocator_type,
39 [[maybe_unused]] const void *allocator_addr)
40 {
41 LOG_MALLOC_MEM_POOL(DEBUG) << "Try to get new arena with size " << std::dec << size << " for "
42 << SpaceTypeToString(space_type);
43 size_t max_alignment_drift = 0;
44 if (alignof(ArenaT) < DEFAULT_ALIGNMENT_IN_BYTES) {
45 max_alignment_drift = DEFAULT_ALIGNMENT_IN_BYTES - alignof(ArenaT);
46 }
47 size_t max_size = size + sizeof(ArenaT) + max_alignment_drift;
48 auto ret = panda::os::mem::AlignedAlloc(std::max(DEFAULT_ALIGNMENT_IN_BYTES, alignof(ArenaT)), max_size);
49 void *buff = reinterpret_cast<char *>(reinterpret_cast<std::uintptr_t>(ret) + sizeof(ArenaT));
50 size_t size_for_buff = max_size - sizeof(ArenaT);
51 buff = std::align(DEFAULT_ALIGNMENT_IN_BYTES, size, buff, size_for_buff);
52 ASSERT(buff != nullptr);
53 ASSERT(reinterpret_cast<std::uintptr_t>(buff) - reinterpret_cast<std::uintptr_t>(ret) >= sizeof(ArenaT));
54 ASSERT(size_for_buff >= size);
55 ret = new (ret) ArenaT(size_for_buff, buff);
56 ASSERT(reinterpret_cast<std::uintptr_t>(ret) + max_size >= reinterpret_cast<std::uintptr_t>(buff) + size);
57 LOG_MALLOC_MEM_POOL(DEBUG) << "Allocated new arena with size " << std::dec << size_for_buff
58 << " at addr = " << std::hex << buff << " for " << SpaceTypeToString(space_type);
59 return static_cast<ArenaT *>(ret);
60 }
61
62 template <class ArenaT>
FreeArenaImpl(ArenaT * arena)63 inline void MallocMemPool::FreeArenaImpl(ArenaT *arena)
64 {
65 LOG_MALLOC_MEM_POOL(DEBUG) << "Try to free arena with size " << std::dec << arena->GetSize()
66 << " at addr = " << std::hex << arena;
67 arena->~Arena();
68 os::mem::AlignedFree(arena);
69 LOG_MALLOC_MEM_POOL(DEBUG) << "Free arena call finished";
70 }
71
72 /* static */
AllocPoolImpl(size_t size,SpaceType space_type,AllocatorType allocator_type,const void * allocator_addr)73 inline Pool MallocMemPool::AllocPoolImpl(size_t size, [[maybe_unused]] SpaceType space_type,
74 [[maybe_unused]] AllocatorType allocator_type,
75 [[maybe_unused]] const void *allocator_addr)
76 {
77 LOG_MALLOC_MEM_POOL(DEBUG) << "Try to get new pool with size " << std::dec << size << " for "
78 << SpaceTypeToString(space_type);
79 void *mem = std::malloc(size); // NOLINT(cppcoreguidelines-no-malloc)
80 LOG_MALLOC_MEM_POOL(DEBUG) << "Allocated new pool with size " << std::dec << size << " at addr = " << std::hex
81 << mem << " for " << SpaceTypeToString(space_type);
82 return Pool(size, mem);
83 }
84
85 /* static */
FreePoolImpl(void * mem,size_t size)86 inline void MallocMemPool::FreePoolImpl(void *mem, [[maybe_unused]] size_t size)
87 {
88 LOG_MALLOC_MEM_POOL(DEBUG) << "Try to free pool with size " << std::dec << size << " at addr = " << std::hex << mem;
89 std::free(mem); // NOLINT(cppcoreguidelines-no-malloc)
90 LOG_MALLOC_MEM_POOL(DEBUG) << "Free pool call finished";
91 }
92
93 /* static */
GetAllocatorInfoForAddrImpl(const void * addr)94 inline AllocatorInfo MallocMemPool::GetAllocatorInfoForAddrImpl([[maybe_unused]] const void *addr)
95 {
96 // TODO(aemelenko): Implement this method
97 LOG(FATAL, ALLOC) << "Not implemented method";
98 return AllocatorInfo(AllocatorType::UNDEFINED, nullptr);
99 }
100
101 /* static */
GetSpaceTypeForAddrImpl(const void * addr)102 inline SpaceType MallocMemPool::GetSpaceTypeForAddrImpl([[maybe_unused]] const void *addr)
103 {
104 // TODO(aemelenko): Implement this method
105 LOG(FATAL, ALLOC) << "Not implemented method";
106 return SpaceType::SPACE_TYPE_UNDEFINED;
107 }
108
109 /* static */
GetStartAddrPoolForAddrImpl(const void * addr)110 inline void *MallocMemPool::GetStartAddrPoolForAddrImpl([[maybe_unused]] const void *addr)
111 {
112 // TODO(ipetrov): Implement this method
113 LOG(FATAL, ALLOC) << "Not implemented method";
114 return nullptr;
115 }
116
117 } // namespace panda
118
119 #endif // LIBPANDABASE_MEM_MALLOC_MEM_POOL_INL_H
120