1 /*
2 * Copyright (c) 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 CORE_UTIL_LINEAR_ALLOCATOR_H
17 #define CORE_UTIL_LINEAR_ALLOCATOR_H
18
19 #include <cstdint>
20 #include <cstdlib>
21 #include <memory>
22
23 #include <base/containers/unique_ptr.h>
24 #include <core/namespace.h>
25
CORE_BEGIN_NAMESPACE()26 CORE_BEGIN_NAMESPACE()
27 class LinearAllocator {
28 public:
29 explicit LinearAllocator(size_t size) : size_(size), data_(BASE_NS::make_unique<uint8_t[]>(size))
30 {
31 Reset();
32 }
33
34 LinearAllocator(size_t size, size_t alignment)
35 : size_(size), alignment_(alignment), data_(BASE_NS::make_unique<uint8_t[]>(size_ + alignment_ - 1))
36 {
37 Reset();
38 }
39
40 ~LinearAllocator() = default;
41
42 template<typename T>
43 T* Allocate()
44 {
45 return static_cast<T*>(Allocate(sizeof(T), alignof(T)));
46 }
47
48 void* Allocate(size_t size)
49 {
50 return Allocate(size, 1);
51 }
52
53 void* Allocate(size_t size, size_t alignment)
54 {
55 if (std::align(alignment, size, current_, free_)) {
56 void* result = current_;
57
58 current_ = static_cast<char*>(current_) + size;
59 free_ -= size;
60 return result;
61 }
62
63 return nullptr;
64 }
65
66 inline void Reset()
67 {
68 current_ = data_.get();
69 free_ = size_;
70 auto allocationSize = size_ + alignment_ - 1;
71 std::align(alignment_, 1, current_, allocationSize);
72 }
73
74 inline size_t GetByteSize() const
75 {
76 return size_;
77 }
78
79 inline size_t GetCurrentByteSize() const
80 {
81 return size_ - free_;
82 }
83
84 inline size_t GetAlignment() const
85 {
86 return alignment_;
87 }
88
89 private:
90 size_t const size_ { 0 };
91 size_t const alignment_ = 1;
92 size_t free_ { 0 };
93
94 BASE_NS::unique_ptr<uint8_t[]> data_;
95 void* current_ { nullptr };
96 };
97 CORE_END_NAMESPACE()
98
99 #endif // CORE_UTIL_LINEAR_ALLOCATOR_H
100