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 #ifndef PANDA_LIBPANDABASE_MEM_STACK_LIKE_ALLOCATOR_H 16 #define PANDA_LIBPANDABASE_MEM_STACK_LIKE_ALLOCATOR_H 17 18 #include "libpandabase/mem/mem.h" 19 #include "libpandabase/mem/pool_map.h" 20 21 namespace ark::mem { 22 static constexpr size_t STACK_LIKE_ALLOCATOR_DEFAUL_MAX_SIZE = 48_MB; 23 24 // Allocation flow looks like that: 25 // 26 // 1. Allocate big memory piece via mmap. 27 // 2. Allocate/Free memory in this preallocated memory piece. 28 // 3. Return nullptr if we reached the limit of created memory piece. 29 30 template <Alignment ALIGNMENT = DEFAULT_FRAME_ALIGNMENT, size_t MAX_SIZE = STACK_LIKE_ALLOCATOR_DEFAUL_MAX_SIZE> 31 class StackLikeAllocator { 32 public: 33 explicit StackLikeAllocator(bool usePoolManager = true, SpaceType spaceType = SpaceType::SPACE_TYPE_FRAMES); 34 ~StackLikeAllocator(); 35 NO_MOVE_SEMANTIC(StackLikeAllocator); 36 NO_COPY_SEMANTIC(StackLikeAllocator); 37 38 template <bool USE_MEMSET = true> 39 [[nodiscard]] void *Alloc(size_t size); 40 41 void Free(void *mem); 42 43 /// @brief Returns true if address inside current allocator. 44 bool Contains(void *mem); 45 GetAllocatorType()46 static constexpr AllocatorType GetAllocatorType() 47 { 48 return AllocatorType::STACK_LIKE_ALLOCATOR; 49 } 50 GetAllocatedSize()51 size_t GetAllocatedSize() const 52 { 53 ASSERT(ToUintPtr(freePointer_) >= ToUintPtr(startAddr_)); 54 return ToUintPtr(freePointer_) - ToUintPtr(startAddr_); 55 } 56 SetReservedMemorySize(size_t size)57 void SetReservedMemorySize(size_t size) 58 { 59 ASSERT(GetFullMemorySize() >= size); 60 reservedEndAddr_ = ToVoidPtr(ToUintPtr(startAddr_) + size); 61 } 62 UseWholeMemory()63 void UseWholeMemory() 64 { 65 endAddr_ = allocatedEndAddr_; 66 } 67 ReserveMemory()68 void ReserveMemory() 69 { 70 ASSERT(reservedEndAddr_ != nullptr); 71 endAddr_ = reservedEndAddr_; 72 } 73 GetFullMemorySize()74 size_t GetFullMemorySize() const 75 { 76 return ToUintPtr(allocatedEndAddr_) - ToUintPtr(startAddr_); 77 } 78 79 private: 80 static constexpr size_t RELEASE_PAGES_SIZE = 256_KB; 81 static constexpr size_t RELEASE_PAGES_SHIFT = 18; 82 static_assert(RELEASE_PAGES_SIZE == (1U << RELEASE_PAGES_SHIFT)); 83 static_assert(MAX_SIZE % GetAlignmentInBytes(ALIGNMENT) == 0); 84 void *startAddr_ {nullptr}; 85 void *endAddr_ {nullptr}; 86 void *freePointer_ {nullptr}; 87 bool usePoolManager_ {false}; 88 void *reservedEndAddr_ {nullptr}; 89 void *allocatedEndAddr_ {nullptr}; 90 }; 91 } // namespace ark::mem 92 93 #endif // PANDA_LIBPANDABASE_MEM_STACK_LIKE_ALLOCATOR_H 94