Metall v0.30
A persistent memory allocator for data-centric analytics
 
Loading...
Searching...
No Matches
fallback_allocator.hpp
Go to the documentation of this file.
1// Copyright 2024 Lawrence Livermore National Security, LLC and other Metall
2// Project Developers. See the top-level COPYRIGHT file for details.
3//
4// SPDX-License-Identifier: (Apache-2.0 OR MIT)
5
6#ifndef METALL_CONTAINER_FALLBACK_ALLOCATOR_HPP
7#define METALL_CONTAINER_FALLBACK_ALLOCATOR_HPP
8
9#include <memory>
10#include <cstdlib>
11#include <type_traits>
12
13namespace metall::container {
14
20template <typename StatefulAllocator>
22 // Check if the StatefulAllocator takes arguments in its constructor
23 static_assert(!std::is_constructible<StatefulAllocator>::value,
24 "The stateful allocator must not be default constructible");
25
26 private:
27 template <typename T>
28 using other_stateful_allocator_type = typename std::allocator_traits<
30
31 public:
32 // -------------------- //
33 // Public types and static values
34 // -------------------- //
35 using stateful_allocator_type = typename std::remove_const<
36 typename std::remove_reference<StatefulAllocator>::type>::type;
37
38 using value_type = typename stateful_allocator_type::value_type;
39 using pointer = typename stateful_allocator_type::pointer;
40 using const_pointer = typename stateful_allocator_type::const_pointer;
41 using void_pointer = typename stateful_allocator_type::void_pointer;
43 typename stateful_allocator_type::const_void_pointer;
44 using difference_type = typename stateful_allocator_type::difference_type;
45 using size_type = typename stateful_allocator_type::size_type;
46
48 template <typename T2>
52
53 public:
54 // -------------------- //
55 // Constructor & assign operator
56 // -------------------- //
57
60 fallback_allocator_adaptor() noexcept : m_stateful_allocator(nullptr) {}
61
64 template <
66 std::enable_if_t<std::is_constructible<stateful_allocator_type,
68 int> = 0>
73
76 template <
78 std::enable_if_t<std::is_constructible<stateful_allocator_type,
80 int> = 0>
84
87 default;
88
91 default;
92
95 const fallback_allocator_adaptor &) noexcept = default;
96
99 template <
101 std::enable_if_t<std::is_constructible<stateful_allocator_type,
103 int> = 0>
106 &other) noexcept {
107 m_stateful_allocator = other.stateful_allocator();
108 return *this;
109 }
110
112 template <
114 std::enable_if_t<std::is_constructible<stateful_allocator_type,
116 int> = 0>
119 m_stateful_allocator = allocator_instance;
120 return *this;
121 }
122
125 fallback_allocator_adaptor &&other) noexcept = default;
126
129 template <
131 std::enable_if_t<std::is_constructible<stateful_allocator_type,
133 int> = 0>
136 m_stateful_allocator = std::move(other.stateful_allocator());
137 return *this;
138 }
139
141 template <
143 std::enable_if_t<std::is_constructible<stateful_allocator_type,
145 int> = 0>
148 m_stateful_allocator = std::move(allocator_instance);
149 return *this;
150 }
151
156 if (priv_stateful_allocator_available()) {
157 return m_stateful_allocator.allocate(n);
158 }
159 return priv_fallback_allocate(n);
160 }
161
165 void deallocate(pointer ptr, const size_type size) const {
166 if (priv_stateful_allocator_available()) {
167 m_stateful_allocator.deallocate(ptr, size);
168 } else {
169 priv_fallback_deallocate(ptr);
170 }
171 }
172
176 return m_stateful_allocator.max_size();
177 }
178
183 template <class... Args>
184 void construct(const pointer &ptr, Args &&...args) const {
185 if (priv_stateful_allocator_available()) {
186 m_stateful_allocator.construct(ptr, std::forward<Args>(args)...);
187 } else {
188 priv_fallback_construct(ptr, std::forward<Args>(args)...);
189 }
190 }
191
194 void destroy(const pointer &ptr) const {
195 if (priv_stateful_allocator_available()) {
196 m_stateful_allocator.destroy(ptr);
197 } else {
198 priv_fallback_destroy(ptr);
199 }
200 }
201
202 // ---------- This class's unique public functions ---------- //
203
205 stateful_allocator_type &get_stateful_allocator() { return m_stateful_allocator; }
206
209 return m_stateful_allocator;
210 }
211
215 return priv_stateful_allocator_available();
216 }
217
218 private:
219 // -------------------- //
220 // Private methods
221 // -------------------- //
222 auto priv_stateful_allocator_available() const {
223 return !!(m_stateful_allocator.get_pointer_to_manager_kernel());
224 }
225
226 pointer priv_fallback_allocate(const size_type n) const {
227 if (max_size() < n) {
228 throw std::bad_array_new_length();
229 }
230
231 void *const addr = std::malloc(n * sizeof(value_type));
232 if (!addr) {
233 throw std::bad_alloc();
234 }
235
236 return pointer(static_cast<value_type *>(addr));
237 }
238
239 void priv_fallback_deallocate(pointer ptr) const {
240 std::free(to_raw_pointer(ptr));
241 }
242
243 void priv_fallback_destroy(pointer ptr) const { (*ptr).~value_type(); }
244
245 template <class... arg_types>
246 void priv_fallback_construct(const pointer &ptr, arg_types &&...args) const {
247 ::new ((void *)to_raw_pointer(ptr))
248 value_type(std::forward<arg_types>(args)...);
249 }
250
251 // -------------------- //
252 // Private fields
253 // -------------------- //
254 stateful_allocator_type m_stateful_allocator;
255};
256
257template <typename stateful_allocator_type>
258inline bool operator==(
261 // Return true if they point to the same manager kernel
262 return rhd.get_stateful_allocator() == lhd.get_stateful_allocator();
263}
264
265template <typename stateful_allocator_type>
271
272} // namespace metall::container
273
276
277#endif // METALL_CONTAINER_FALLBACK_ALLOCATOR_HPP
A Metall STL compatible allocator which fallbacks to a heap allocator (e.g., malloc()) if its constru...
Definition fallback_allocator.hpp:21
fallback_allocator_adaptor & operator=(const stateful_allocator_type2 &allocator_instance) noexcept
Copy assign operator for any stateful_allocator.
Definition fallback_allocator.hpp:117
void construct(const pointer &ptr, Args &&...args) const
Constructs an object of T.
Definition fallback_allocator.hpp:184
fallback_allocator_adaptor & operator=(fallback_allocator_adaptor &&other) noexcept=default
Move assign operator.
typename stateful_allocator_type::size_type size_type
Definition fallback_allocator.hpp:45
typename stateful_allocator_type::const_void_pointer const_void_pointer
Definition fallback_allocator.hpp:43
fallback_allocator_adaptor(fallback_allocator_adaptor< stateful_allocator_type2 > allocator_instance) noexcept
Construct a new instance using an instance of fallback_allocator_adaptor with any stateful_allocator ...
Definition fallback_allocator.hpp:69
typename std::remove_const< typename std::remove_reference< StatefulAllocator >::type >::type stateful_allocator_type
Definition fallback_allocator.hpp:36
void destroy(const pointer &ptr) const
Deconstruct an object of T.
Definition fallback_allocator.hpp:194
typename stateful_allocator_type::pointer pointer
Definition fallback_allocator.hpp:39
pointer allocate(const size_type n) const
Allocates n * sizeof(T) bytes of storage.
Definition fallback_allocator.hpp:155
fallback_allocator_adaptor & operator=(const fallback_allocator_adaptor< stateful_allocator_type2 > &other) noexcept
Copy assign operator, using an instance of fallback_allocator_adaptor with any stateful_allocator typ...
Definition fallback_allocator.hpp:104
typename stateful_allocator_type::difference_type difference_type
Definition fallback_allocator.hpp:44
fallback_allocator_adaptor(const fallback_allocator_adaptor &other) noexcept=default
Copy constructor.
size_type max_size() const noexcept
The size of the theoretical maximum allocation size.
Definition fallback_allocator.hpp:175
typename stateful_allocator_type::void_pointer void_pointer
Definition fallback_allocator.hpp:41
stateful_allocator_type & get_stateful_allocator()
Returns a reference to the stateful allocator.
Definition fallback_allocator.hpp:205
fallback_allocator_adaptor(fallback_allocator_adaptor &&other) noexcept=default
Move constructor.
typename stateful_allocator_type::value_type value_type
Definition fallback_allocator.hpp:38
bool stateful_allocator_available() const
Returns true if the stateful allocator is available.
Definition fallback_allocator.hpp:214
fallback_allocator_adaptor() noexcept
Default constructor which falls back on the regular allocator (i.e., malloc()).
Definition fallback_allocator.hpp:60
fallback_allocator_adaptor & operator=(const fallback_allocator_adaptor &) noexcept=default
Copy assign operator.
fallback_allocator_adaptor(stateful_allocator_type2 allocator_instance) noexcept
Construct a new instance using an instance of any stateful_allocator.
Definition fallback_allocator.hpp:81
fallback_allocator_adaptor & operator=(stateful_allocator_type2 &&allocator_instance) noexcept
Move assign operator for any stateful_allocator.
Definition fallback_allocator.hpp:146
const stateful_allocator_type & get_stateful_allocator() const
Returns a const reference to the stateful allocator.
Definition fallback_allocator.hpp:208
void deallocate(pointer ptr, const size_type size) const
Deallocates the storage reference by the pointer ptr.
Definition fallback_allocator.hpp:165
fallback_allocator_adaptor & operator=(fallback_allocator_adaptor< stateful_allocator_type2 > &&other) noexcept
Move assign operator, using an instance of fallback_allocator_adaptor with any stateful_allocator typ...
Definition fallback_allocator.hpp:134
typename stateful_allocator_type::const_pointer const_pointer
Definition fallback_allocator.hpp:40
Namespace for Metall container.
bool operator!=(const fallback_allocator_adaptor< stateful_allocator_type > &rhd, const fallback_allocator_adaptor< stateful_allocator_type > &lhd)
Definition fallback_allocator.hpp:266
bool operator==(const fallback_allocator_adaptor< stateful_allocator_type > &rhd, const fallback_allocator_adaptor< stateful_allocator_type > &lhd)
Definition fallback_allocator.hpp:258
boost::container::vector< T, Allocator > vector
A vector container that uses Metall as its default allocator.
Definition vector.hpp:17
Makes another allocator type for type T2.
Definition fallback_allocator.hpp:49
fallback_allocator_adaptor< other_stateful_allocator_type< T2 > > other
Definition fallback_allocator.hpp:50