• 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 #ifndef RUNTIME_MEM_ALLOCATOR_ADAPTER_H
16 #define RUNTIME_MEM_ALLOCATOR_ADAPTER_H
17 
18 #include "runtime/include/mem/allocator.h"
19 
20 namespace panda::mem {
21 
22 template <typename T, AllocScope AllocScopeT>
23 class AllocatorAdapter;
24 
25 template <AllocScope AllocScopeT>
26 class AllocatorAdapter<void, AllocScopeT> {
27 public:
28     using value_type = void;
29     using pointer = void *;
30     using const_pointer = const void *;
31 
32     template <typename U>
33     struct Rebind {
34         using other = AllocatorAdapter<U, AllocScopeT>;
35     };
36 
37     template <typename U>
38     using rebind = Rebind<U>;
39 
40     explicit AllocatorAdapter(Allocator *allocator = InternalAllocator<>::GetInternalAllocatorFromRuntime())
allocator_(allocator)41         : allocator_(allocator)
42     {
43     }
44     template <typename U>
45     // NOLINTNEXTLINE(google-explicit-constructor)
AllocatorAdapter(const AllocatorAdapter<U,AllocScopeT> & other)46     AllocatorAdapter(const AllocatorAdapter<U, AllocScopeT> &other) : allocator_(other.allocator_)
47     {
48     }
49     AllocatorAdapter(const AllocatorAdapter &) = default;
50     AllocatorAdapter &operator=(const AllocatorAdapter &) = default;
51 
AllocatorAdapter(AllocatorAdapter && other)52     AllocatorAdapter(AllocatorAdapter &&other) noexcept
53     {
54         allocator_ = other.allocator_;
55         other.allocator_ = nullptr;
56     }
57 
58     AllocatorAdapter &operator=(AllocatorAdapter &&other) noexcept
59     {
60         allocator_ = other.allocator_;
61         other.allocator_ = nullptr;
62         return *this;
63     }
64 
65     ~AllocatorAdapter() = default;
66 
67 private:
68     Allocator *allocator_;
69 
70     template <typename U, AllocScope TypeT>
71     friend class AllocatorAdapter;
72 };
73 
74 template <typename T, AllocScope AllocScopeT = AllocScope::GLOBAL>
75 class AllocatorAdapter {
76 public:
77     using value_type = T;
78     using pointer = T *;
79     using reference = T &;
80     using const_pointer = const T *;
81     using const_reference = const T &;
82     using size_type = size_t;
83     using difference_type = ptrdiff_t;
84 
85     template <typename U>
86     struct Rebind {
87         using other = AllocatorAdapter<U, AllocScopeT>;
88     };
89 
90     template <typename U>
91     using rebind = Rebind<U>;
92 
93     explicit AllocatorAdapter(Allocator *allocator = InternalAllocator<>::GetInternalAllocatorFromRuntime())
allocator_(allocator)94         : allocator_(allocator)
95     {
96     }
97     template <typename U>
98     // NOLINTNEXTLINE(google-explicit-constructor)
AllocatorAdapter(const AllocatorAdapter<U,AllocScopeT> & other)99     AllocatorAdapter(const AllocatorAdapter<U, AllocScopeT> &other) : allocator_(other.allocator_)
100     {
101     }
102     AllocatorAdapter(const AllocatorAdapter &) = default;
103     AllocatorAdapter &operator=(const AllocatorAdapter &) = default;
104 
AllocatorAdapter(AllocatorAdapter && other)105     AllocatorAdapter(AllocatorAdapter &&other) noexcept
106     {
107         allocator_ = other.allocator_;
108         other.allocator_ = nullptr;
109     }
110 
111     AllocatorAdapter &operator=(AllocatorAdapter &&other) noexcept
112     {
113         allocator_ = other.allocator_;
114         other.allocator_ = nullptr;
115         return *this;
116     }
117 
118     ~AllocatorAdapter() = default;
119 
120     // NOLINTNEXTLINE(readability-identifier-naming)
121     pointer allocate(size_type size, [[maybe_unused]] const void *hint = nullptr)
122     {
123         // NOLINTNEXTLINE(bugprone-suspicious-semicolon, readability-braces-around-statements)
124         if constexpr (AllocScopeT == AllocScope::GLOBAL) {
125             return allocator_->AllocArray<T>(size);
126             // NOLINTNEXTLINE(readability-misleading-indentation)
127         } else {
128             return allocator_->AllocArrayLocal<T>(size);
129         }
130     }
131 
132     // NOLINTNEXTLINE(readability-identifier-naming)
deallocate(pointer ptr,size_type size)133     void deallocate(pointer ptr, [[maybe_unused]] size_type size)
134     {
135         allocator_->Free(ptr);
136     }
137 
138     template <typename U, typename... Args>
construct(U * ptr,Args &&...args)139     void construct(U *ptr, Args &&... args)  // NOLINT(readability-identifier-naming)
140     {
141         ::new (static_cast<void *>(ptr)) U(std::forward<Args>(args)...);
142     }
143 
144     template <typename U>
destroy(U * ptr)145     void destroy(U *ptr)  // NOLINT(readability-identifier-naming)
146     {
147         ptr->~U();
148     }
149 
150     template <typename U>
151     bool operator==(const AllocatorAdapter<U> &other) const
152     {
153         return this->allocator_ == other.allocator_;
154     }
155 
156     template <typename U>
157     bool operator!=(const AllocatorAdapter<U> &other) const
158     {
159         return this->allocator_ != other.allocator_;
160     }
161 
162 private:
163     Allocator *allocator_;
164 
165     template <typename U, AllocScope TypeT>
166     friend class AllocatorAdapter;
167 };
168 
169 template <AllocScope AllocScopeT>
Adapter()170 inline AllocatorAdapter<void, AllocScopeT> Allocator::Adapter()
171 {
172     return AllocatorAdapter<void, AllocScopeT>(this);
173 }
174 
175 }  // namespace panda::mem
176 
177 #endif  // RUNTIME_MEM_ALLOCATOR_ADAPTER_H
178