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