1b1994897Sopenharmony_ci/** 2b1994897Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3b1994897Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4b1994897Sopenharmony_ci * you may not use this file except in compliance with the License. 5b1994897Sopenharmony_ci * You may obtain a copy of the License at 6b1994897Sopenharmony_ci * 7b1994897Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8b1994897Sopenharmony_ci * 9b1994897Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10b1994897Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11b1994897Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12b1994897Sopenharmony_ci * See the License for the specific language governing permissions and 13b1994897Sopenharmony_ci * limitations under the License. 14b1994897Sopenharmony_ci */ 15b1994897Sopenharmony_ci 16b1994897Sopenharmony_ci#ifndef LIBPANDABASE_MEM_ARENA_H 17b1994897Sopenharmony_ci#define LIBPANDABASE_MEM_ARENA_H 18b1994897Sopenharmony_ci 19b1994897Sopenharmony_ci#include "mem.h" 20b1994897Sopenharmony_ci 21b1994897Sopenharmony_ciWEAK_FOR_LTO_START 22b1994897Sopenharmony_ci 23b1994897Sopenharmony_cinamespace panda { 24b1994897Sopenharmony_ci 25b1994897Sopenharmony_ciconstexpr size_t ARENA_DEFAULT_SIZE = SIZE_1M; 26b1994897Sopenharmony_ciconstexpr Alignment ARENA_DEFAULT_ALIGNMENT = DEFAULT_ALIGNMENT; 27b1994897Sopenharmony_ci 28b1994897Sopenharmony_ciclass Arena { 29b1994897Sopenharmony_cipublic: 30b1994897Sopenharmony_ci Arena(size_t buff_size, void *buff); 31b1994897Sopenharmony_ci virtual ~Arena(); 32b1994897Sopenharmony_ci DEFAULT_MOVE_SEMANTIC(Arena); 33b1994897Sopenharmony_ci DEFAULT_COPY_SEMANTIC(Arena); 34b1994897Sopenharmony_ci 35b1994897Sopenharmony_ci /** 36b1994897Sopenharmony_ci * \brief Allocates memory with size \param size and aligned with \param alignment 37b1994897Sopenharmony_ci * @param size - size of the allocated memory 38b1994897Sopenharmony_ci * @param alignment - alignment of the allocated memory 39b1994897Sopenharmony_ci * @return pointer to the allocated memory on success, or nullptr on fail 40b1994897Sopenharmony_ci */ 41b1994897Sopenharmony_ci void *Alloc(size_t size, Alignment alignment = ARENA_DEFAULT_ALIGNMENT); 42b1994897Sopenharmony_ci 43b1994897Sopenharmony_ci /** 44b1994897Sopenharmony_ci * \brief Links this Arena to the \param arena 45b1994897Sopenharmony_ci * @param arena - Arena which will be linked as next to the current 46b1994897Sopenharmony_ci */ 47b1994897Sopenharmony_ci void LinkTo(Arena *arena); 48b1994897Sopenharmony_ci 49b1994897Sopenharmony_ci /** 50b1994897Sopenharmony_ci * \brief Clear link to the next arena 51b1994897Sopenharmony_ci */ 52b1994897Sopenharmony_ci void ClearNextLink(); 53b1994897Sopenharmony_ci 54b1994897Sopenharmony_ci /** 55b1994897Sopenharmony_ci * \brief Returns next linked Arena 56b1994897Sopenharmony_ci * @return next linked Arena or nullptr 57b1994897Sopenharmony_ci */ 58b1994897Sopenharmony_ci Arena *GetNextArena() const; 59b1994897Sopenharmony_ci 60b1994897Sopenharmony_ci /** 61b1994897Sopenharmony_ci * @return Size of free area in the arena 62b1994897Sopenharmony_ci */ 63b1994897Sopenharmony_ci size_t GetFreeSize() const; 64b1994897Sopenharmony_ci 65b1994897Sopenharmony_ci /** 66b1994897Sopenharmony_ci * @return Size of an occupied area in the arena 67b1994897Sopenharmony_ci */ 68b1994897Sopenharmony_ci size_t GetOccupiedSize() const; 69b1994897Sopenharmony_ci 70b1994897Sopenharmony_ci /** 71b1994897Sopenharmony_ci * @return A pointer to the first byte not in the arena 72b1994897Sopenharmony_ci */ 73b1994897Sopenharmony_ci void *GetArenaEnd() const; 74b1994897Sopenharmony_ci 75b1994897Sopenharmony_ci /** 76b1994897Sopenharmony_ci * @return A pointer to the first not allocated byte 77b1994897Sopenharmony_ci */ 78b1994897Sopenharmony_ci void *GetAllocatedEnd() const; 79b1994897Sopenharmony_ci 80b1994897Sopenharmony_ci /** 81b1994897Sopenharmony_ci * @return A pointer to the first allocated byte 82b1994897Sopenharmony_ci */ 83b1994897Sopenharmony_ci void *GetAllocatedStart() const; 84b1994897Sopenharmony_ci 85b1994897Sopenharmony_ci /** 86b1994897Sopenharmony_ci * @return A pointer to the raw memory inside arena 87b1994897Sopenharmony_ci */ 88b1994897Sopenharmony_ci void *GetMem() const 89b1994897Sopenharmony_ci { 90b1994897Sopenharmony_ci return buff_; 91b1994897Sopenharmony_ci } 92b1994897Sopenharmony_ci 93b1994897Sopenharmony_ci void *GetTop() const 94b1994897Sopenharmony_ci { 95b1994897Sopenharmony_ci return curPos_; 96b1994897Sopenharmony_ci } 97b1994897Sopenharmony_ci 98b1994897Sopenharmony_ci size_t GetSize() const 99b1994897Sopenharmony_ci { 100b1994897Sopenharmony_ci return size_; 101b1994897Sopenharmony_ci } 102b1994897Sopenharmony_ci 103b1994897Sopenharmony_ci /** 104b1994897Sopenharmony_ci * \brief Check that \param mem is stored inside this Arena 105b1994897Sopenharmony_ci * @return true on success, or false on fail 106b1994897Sopenharmony_ci */ 107b1994897Sopenharmony_ci bool InArena(const void *mem) const; 108b1994897Sopenharmony_ci 109b1994897Sopenharmony_ci /** 110b1994897Sopenharmony_ci * \brief Mark all memory after \param mem as free. Check that \param mem is stored inside this arena. 111b1994897Sopenharmony_ci */ 112b1994897Sopenharmony_ci void Free(void *mem); 113b1994897Sopenharmony_ci 114b1994897Sopenharmony_ci /** 115b1994897Sopenharmony_ci * \brief Set occupied memory size to \param new_size. 116b1994897Sopenharmony_ci */ 117b1994897Sopenharmony_ci void Resize(size_t new_size); 118b1994897Sopenharmony_ci 119b1994897Sopenharmony_ci /* 120b1994897Sopenharmony_ci * \brief empties arena 121b1994897Sopenharmony_ci */ 122b1994897Sopenharmony_ci void Reset(); 123b1994897Sopenharmony_ci 124b1994897Sopenharmony_ci /* 125b1994897Sopenharmony_ci * \brief Expand arena. The new memory must be located just after the current buffer. 126b1994897Sopenharmony_ci * @param extra_buff - pointer to the extra buffer located just after the current. 127b1994897Sopenharmony_ci * @param size - the size of the extra buffer 128b1994897Sopenharmony_ci */ 129b1994897Sopenharmony_ci void ExpandArena(const void *extra_buff, size_t size); 130b1994897Sopenharmony_ci 131b1994897Sopenharmony_ciprotected: 132b1994897Sopenharmony_ci Arena(size_t buff_size, void *buff, Alignment start_alignment); 133b1994897Sopenharmony_ci /** 134b1994897Sopenharmony_ci * \brief Fast allocates memory with size \param size 135b1994897Sopenharmony_ci * @param size - size of the allocated memory, must be \param alignment aligned 136b1994897Sopenharmony_ci * @param alignment - alignment of the allocated memory, used only for debug 137b1994897Sopenharmony_ci * @return pointer to the allocated memory on success, or nullptr on fail 138b1994897Sopenharmony_ci */ 139b1994897Sopenharmony_ci void *AlignedAlloc(size_t size, Alignment alignment); 140b1994897Sopenharmony_ci 141b1994897Sopenharmony_ci void *GetStartPos() const 142b1994897Sopenharmony_ci { 143b1994897Sopenharmony_ci return startPos_; 144b1994897Sopenharmony_ci } 145b1994897Sopenharmony_ci 146b1994897Sopenharmony_ciprivate: 147b1994897Sopenharmony_ci Arena *next_ = nullptr; 148b1994897Sopenharmony_ci void *buff_ = nullptr; 149b1994897Sopenharmony_ci void *startPos_ = nullptr; 150b1994897Sopenharmony_ci void *curPos_ = nullptr; 151b1994897Sopenharmony_ci size_t size_ = 0; 152b1994897Sopenharmony_ci}; 153b1994897Sopenharmony_ci 154b1994897Sopenharmony_citemplate <Alignment AlignmentT> 155b1994897Sopenharmony_ciclass AlignedArena : public Arena { 156b1994897Sopenharmony_cipublic: 157b1994897Sopenharmony_ci AlignedArena(size_t buff_size, void *buff) : Arena(buff_size, buff, AlignmentT) {} 158b1994897Sopenharmony_ci 159b1994897Sopenharmony_ci ~AlignedArena() override = default; 160b1994897Sopenharmony_ci 161b1994897Sopenharmony_ci void *Alloc(size_t size) 162b1994897Sopenharmony_ci { 163b1994897Sopenharmony_ci return Arena::AlignedAlloc(size, AlignmentT); 164b1994897Sopenharmony_ci } 165b1994897Sopenharmony_ci 166b1994897Sopenharmony_ciprivate: 167b1994897Sopenharmony_ci DEFAULT_MOVE_SEMANTIC(AlignedArena); 168b1994897Sopenharmony_ci DEFAULT_COPY_SEMANTIC(AlignedArena); 169b1994897Sopenharmony_ci}; 170b1994897Sopenharmony_ci 171b1994897Sopenharmony_citemplate <Alignment AlignmentT> 172b1994897Sopenharmony_ciclass DoubleLinkedAlignedArena : public AlignedArena<AlignmentT> { 173b1994897Sopenharmony_cipublic: 174b1994897Sopenharmony_ci DoubleLinkedAlignedArena(size_t buff_size, void *buff) : AlignedArena<AlignmentT>(buff_size, buff) {} 175b1994897Sopenharmony_ci 176b1994897Sopenharmony_ci /** 177b1994897Sopenharmony_ci * \brief Links this Arena to the next \param arena 178b1994897Sopenharmony_ci * @param arena - Arena which will be linked as next to the current 179b1994897Sopenharmony_ci */ 180b1994897Sopenharmony_ci void LinkNext(DoubleLinkedAlignedArena *arena) 181b1994897Sopenharmony_ci { 182b1994897Sopenharmony_ci Arena::LinkTo(static_cast<Arena *>(arena)); 183b1994897Sopenharmony_ci } 184b1994897Sopenharmony_ci 185b1994897Sopenharmony_ci /** 186b1994897Sopenharmony_ci * \brief Links this Arena to the prev \param arena 187b1994897Sopenharmony_ci * @param arena - Arena which will be linked as prev to the current 188b1994897Sopenharmony_ci */ 189b1994897Sopenharmony_ci void LinkPrev(DoubleLinkedAlignedArena *arena) 190b1994897Sopenharmony_ci { 191b1994897Sopenharmony_ci ASSERT(prev_ == nullptr); 192b1994897Sopenharmony_ci prev_ = arena; 193b1994897Sopenharmony_ci } 194b1994897Sopenharmony_ci 195b1994897Sopenharmony_ci /** 196b1994897Sopenharmony_ci * \brief Returns next linked Arena 197b1994897Sopenharmony_ci * @return next linked Arena or nullptr 198b1994897Sopenharmony_ci */ 199b1994897Sopenharmony_ci DoubleLinkedAlignedArena *GetNextArena() const 200b1994897Sopenharmony_ci { 201b1994897Sopenharmony_ci return static_cast<DoubleLinkedAlignedArena *>(Arena::GetNextArena()); 202b1994897Sopenharmony_ci } 203b1994897Sopenharmony_ci 204b1994897Sopenharmony_ci /** 205b1994897Sopenharmony_ci * \brief Returns prev linked Arena 206b1994897Sopenharmony_ci * @return prev linked Arena or nullptr 207b1994897Sopenharmony_ci */ 208b1994897Sopenharmony_ci DoubleLinkedAlignedArena *GetPrevArena() const 209b1994897Sopenharmony_ci { 210b1994897Sopenharmony_ci return prev_; 211b1994897Sopenharmony_ci } 212b1994897Sopenharmony_ci 213b1994897Sopenharmony_ci /** 214b1994897Sopenharmony_ci * \brief Clear link to the prev arena 215b1994897Sopenharmony_ci */ 216b1994897Sopenharmony_ci void ClearPrevLink() 217b1994897Sopenharmony_ci { 218b1994897Sopenharmony_ci prev_ = nullptr; 219b1994897Sopenharmony_ci } 220b1994897Sopenharmony_ci 221b1994897Sopenharmony_ci ~DoubleLinkedAlignedArena() override = default; 222b1994897Sopenharmony_ci 223b1994897Sopenharmony_ci DEFAULT_MOVE_SEMANTIC(DoubleLinkedAlignedArena); 224b1994897Sopenharmony_ci DEFAULT_COPY_SEMANTIC(DoubleLinkedAlignedArena); 225b1994897Sopenharmony_ci 226b1994897Sopenharmony_ciprivate: 227b1994897Sopenharmony_ci DoubleLinkedAlignedArena *prev_ = nullptr; 228b1994897Sopenharmony_ci}; 229b1994897Sopenharmony_ci 230b1994897Sopenharmony_ci} // namespace panda 231b1994897Sopenharmony_ci 232b1994897Sopenharmony_ciWEAK_FOR_LTO_END 233b1994897Sopenharmony_ci 234b1994897Sopenharmony_ci#endif // LIBPANDABASE_MEM_ARENA_H 235