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_MEM_POOL_H 17 #define LIBPANDABASE_MEM_MEM_POOL_H 18 19 #include <cstddef> 20 #include "macros.h" 21 #include "mem.h" 22 #include "pool_map.h" 23 24 namespace panda { 25 class Arena; 26 27 class Pool { 28 public: Pool(size_t size,void * mem)29 explicit constexpr Pool(size_t size, void *mem) : size_(size), mem_(mem) {} Pool(std::pair<size_t,void * > pool)30 explicit Pool(std::pair<size_t, void *> pool) : size_(pool.first), mem_(pool.second) {} 31 GetSize()32 size_t GetSize() const 33 { 34 return size_; 35 } 36 GetMem()37 void *GetMem() 38 { 39 return mem_; 40 } 41 42 bool operator==(const Pool &other) const 43 { 44 return (this->size_ == other.size_) && (this->mem_ == other.mem_); 45 } 46 47 bool operator!=(const Pool &other) const 48 { 49 return !(*this == other); 50 } 51 52 ~Pool() = default; 53 54 DEFAULT_COPY_SEMANTIC(Pool); 55 DEFAULT_MOVE_SEMANTIC(Pool); 56 57 private: 58 size_t size_; 59 void *mem_; 60 }; 61 62 constexpr Pool NULLPOOL {0, nullptr}; 63 64 template <class MemPoolImplT> 65 class MemPool { 66 public: 67 virtual ~MemPool() = default; MemPool(std::string pool_name)68 explicit MemPool(std::string pool_name) : name_(std::move(pool_name)) {} 69 DEFAULT_NOEXCEPT_MOVE_SEMANTIC(MemPool); 70 DEFAULT_COPY_SEMANTIC(MemPool); 71 72 /** 73 * Allocates arena with size bytes 74 * @tparam ArenaT - type of Arena 75 * @param size - size of buffer in arena in bytes 76 * @param space_type - type of the space which arena allocated for 77 * @param allocator_type - type of the allocator which arena allocated for 78 * @param allocator_addr - address of the allocator header. 79 * @return pointer to allocated arena 80 */ 81 // TODO(aemelenko): We must always define allocator_addr for AllocArena 82 // because we set up arena at the first bytes of the pool 83 template <class ArenaT = Arena> 84 inline ArenaT *AllocArena(size_t size, SpaceType space_type, AllocatorType allocator_type, 85 const void *allocator_addr = nullptr) 86 { 87 return static_cast<MemPoolImplT *>(this)->template AllocArenaImpl<ArenaT>(size, space_type, allocator_type, 88 allocator_addr); 89 } 90 91 /** 92 * Frees allocated arena 93 * @tparam ArenaT - arena type 94 * @param arena - pointer to the arena 95 */ 96 template <class ArenaT = Arena> FreeArena(ArenaT * arena)97 inline void FreeArena(ArenaT *arena) 98 { 99 static_cast<MemPoolImplT *>(this)->template FreeArenaImpl<ArenaT>(arena); 100 } 101 102 /** 103 * Allocates pool with at least size bytes 104 * @param size - minimal size of a pool in bytes 105 * @param space_type - type of the space which pool allocated for 106 * @param allocator_type - type of the allocator which arena allocated for 107 * @param allocator_addr - address of the allocator header. 108 * If it is not defined, it means that allocator header will be located at the first bytes of the returned pool. 109 * @return pool info with the size and a pointer 110 */ 111 Pool AllocPool(size_t size, SpaceType space_type, AllocatorType allocator_type, 112 const void *allocator_addr = nullptr) 113 { 114 return static_cast<MemPoolImplT *>(this)->AllocPoolImpl(size, space_type, allocator_type, allocator_addr); 115 } 116 117 /** 118 * Frees allocated pool 119 * @param mem - pointer to an allocated pool 120 * @param size - size of the allocated pool in bytes 121 */ FreePool(void * mem,size_t size)122 void FreePool(void *mem, size_t size) 123 { 124 static_cast<MemPoolImplT *>(this)->FreePoolImpl(mem, size); 125 } 126 127 /** 128 * Get info about the allocator in which this address is used 129 * @param addr 130 * @return Allocator info with a type and pointer to the allocator header 131 */ GetAllocatorInfoForAddr(const void * addr)132 AllocatorInfo GetAllocatorInfoForAddr(const void *addr) const 133 { 134 return static_cast<const MemPoolImplT *>(this)->GetAllocatorInfoForAddrImpl(addr); 135 } 136 137 /** 138 * Get space type which this address used for 139 * @param addr 140 * @return space type 141 */ GetSpaceTypeForAddr(const void * addr)142 SpaceType GetSpaceTypeForAddr(const void *addr) const 143 { 144 return static_cast<const MemPoolImplT *>(this)->GetSpaceTypeForAddrImpl(addr); 145 } 146 147 /** 148 * Get address of pool start for input address 149 * @param addr address in pool 150 * @return address of pool start 151 */ GetStartAddrPoolForAddr(const void * addr)152 void *GetStartAddrPoolForAddr(const void *addr) const 153 { 154 return static_cast<const MemPoolImplT *>(this)->GetStartAddrPoolForAddrImpl(addr); 155 } 156 157 private: 158 std::string name_; 159 }; 160 161 } // namespace panda 162 163 #endif // LIBPANDABASE_MEM_MEM_POOL_H 164