• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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