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