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