1 /* 2 * Copyright (c) 2021-2024 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_ARENA_H 17 #define LIBPANDABASE_MEM_ARENA_H 18 19 #include "mem.h" 20 21 WEAK_FOR_LTO_START 22 23 namespace ark { 24 25 constexpr size_t ARENA_DEFAULT_SIZE = 1_MB; 26 constexpr Alignment ARENA_DEFAULT_ALIGNMENT = DEFAULT_ALIGNMENT; 27 28 class Arena { 29 public: 30 Arena(size_t buffSize, void *buff); 31 virtual ~Arena(); 32 DEFAULT_MOVE_SEMANTIC(Arena); 33 DEFAULT_COPY_SEMANTIC(Arena); 34 35 /** 36 * @brief Allocates memory with size @param size and aligned with @param alignment 37 * @param size - size of the allocated memory 38 * @param alignment - alignment of the allocated memory 39 * @return pointer to the allocated memory on success, or nullptr on fail 40 */ 41 void *Alloc(size_t size, Alignment alignment = ARENA_DEFAULT_ALIGNMENT); 42 43 /** 44 * @brief Links this Arena to the @param arena 45 * @param arena - Arena which will be linked as next to the current 46 */ 47 void LinkTo(Arena *arena); 48 49 /// @brief Clear link to the next arena 50 void ClearNextLink(); 51 52 /** 53 * @brief Returns next linked Arena 54 * @return next linked Arena or nullptr 55 */ 56 Arena *GetNextArena() const; 57 58 /// @return Size of free area in the arena 59 size_t GetFreeSize() const; 60 61 /// @return Size of an occupied area in the arena 62 size_t GetOccupiedSize() const; 63 64 /// @return A pointer to the first byte not in the arena 65 void *GetArenaEnd() const; 66 67 /// @return A pointer to the first not allocated byte 68 void *GetAllocatedEnd() const; 69 70 /// @return A pointer to the first allocated byte 71 void *GetAllocatedStart() const; 72 73 /// @return A pointer to the raw memory inside arena GetMem()74 void *GetMem() const 75 { 76 return buff_; 77 } 78 GetTop()79 void *GetTop() const 80 { 81 return curPos_; 82 } 83 GetSize()84 size_t GetSize() const 85 { 86 return size_; 87 } 88 89 /** 90 * @brief Check that @param mem is stored inside this Arena 91 * @return true on success, or false on fail 92 */ 93 bool InArena(const void *mem) const; 94 95 /// @brief Mark all memory after @param mem as free. Check that @param mem is stored inside this arena. 96 void Free(void *mem); 97 98 /// @brief Set occupied memory size to @param new_size. 99 void Resize(size_t newSize); 100 101 /// @brief empties arena 102 void Reset(); 103 104 /** 105 * @brief Expand arena. The new memory must be located just after the current buffer. 106 * @param extra_buff - pointer to the extra buffer located just after the current. 107 * @param size - the size of the extra buffer 108 */ 109 void ExpandArena(const void *extraBuff, size_t size); 110 111 protected: 112 Arena(size_t buffSize, void *buff, Alignment startAlignment); 113 /** 114 * @brief Fast allocates memory with size @param size 115 * @param size - size of the allocated memory, must be @param alignment aligned 116 * @param alignment - alignment of the allocated memory, used only for debug 117 * @return pointer to the allocated memory on success, or nullptr on fail 118 */ 119 void *AlignedAlloc(size_t size, Alignment alignment); 120 GetStartPos()121 void *GetStartPos() const 122 { 123 return startPos_; 124 } 125 126 private: 127 Arena *next_ = nullptr; 128 void *buff_ = nullptr; 129 void *startPos_ = nullptr; 130 void *curPos_ = nullptr; 131 size_t size_ = 0; 132 }; 133 134 template <Alignment ALIGNMENT_T> 135 class AlignedArena : public Arena { 136 public: AlignedArena(size_t buffSize,void * buff)137 AlignedArena(size_t buffSize, void *buff) : Arena(buffSize, buff, ALIGNMENT_T) {} 138 139 ~AlignedArena() override = default; 140 Alloc(size_t size)141 void *Alloc(size_t size) 142 { 143 return Arena::AlignedAlloc(size, ALIGNMENT_T); 144 } 145 146 private: 147 DEFAULT_MOVE_SEMANTIC(AlignedArena); 148 DEFAULT_COPY_SEMANTIC(AlignedArena); 149 }; 150 151 template <Alignment ALIGNMENT_T> 152 class DoubleLinkedAlignedArena : public AlignedArena<ALIGNMENT_T> { 153 public: DoubleLinkedAlignedArena(size_t buffSize,void * buff)154 DoubleLinkedAlignedArena(size_t buffSize, void *buff) : AlignedArena<ALIGNMENT_T>(buffSize, buff) {} 155 156 /** 157 * @brief Links this Arena to the next @param arena 158 * @param arena - Arena which will be linked as next to the current 159 */ LinkNext(DoubleLinkedAlignedArena * arena)160 void LinkNext(DoubleLinkedAlignedArena *arena) 161 { 162 Arena::LinkTo(static_cast<Arena *>(arena)); 163 } 164 165 /** 166 * @brief Links this Arena to the prev @param arena 167 * @param arena - Arena which will be linked as prev to the current 168 */ LinkPrev(DoubleLinkedAlignedArena * arena)169 void LinkPrev(DoubleLinkedAlignedArena *arena) 170 { 171 ASSERT(prev_ == nullptr); 172 prev_ = arena; 173 } 174 175 /** 176 * @brief Returns next linked Arena 177 * @return next linked Arena or nullptr 178 */ GetNextArena()179 DoubleLinkedAlignedArena *GetNextArena() const 180 { 181 return static_cast<DoubleLinkedAlignedArena *>(Arena::GetNextArena()); 182 } 183 184 /** 185 * @brief Returns prev linked Arena 186 * @return prev linked Arena or nullptr 187 */ GetPrevArena()188 DoubleLinkedAlignedArena *GetPrevArena() const 189 { 190 return prev_; 191 } 192 193 /// @brief Clear link to the prev arena ClearPrevLink()194 void ClearPrevLink() 195 { 196 prev_ = nullptr; 197 } 198 199 ~DoubleLinkedAlignedArena() override = default; 200 201 DEFAULT_MOVE_SEMANTIC(DoubleLinkedAlignedArena); 202 DEFAULT_COPY_SEMANTIC(DoubleLinkedAlignedArena); 203 204 private: 205 DoubleLinkedAlignedArena *prev_ = nullptr; 206 }; 207 208 } // namespace ark 209 210 WEAK_FOR_LTO_END 211 212 #endif // LIBPANDABASE_MEM_ARENA_H 213