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