PMDK C++ bindings  1.13.0-git23.gf49772ac
This is the C++ bindings documentation for PMDK's libpmemobj.
allocator.hpp
Go to the documentation of this file.
1 // SPDX-License-Identifier: BSD-3-Clause
2 /* Copyright 2016-2020, Intel Corporation */
3 
9 #ifndef LIBPMEMOBJ_CPP_ALLOCATOR_HPP
10 #define LIBPMEMOBJ_CPP_ALLOCATOR_HPP
11 
16 #include <libpmemobj++/pext.hpp>
17 #include <libpmemobj/tx_base.h>
18 
19 namespace pmem
20 {
21 
22 namespace obj
23 {
24 
29 template <typename T>
31 public:
32  /*
33  * Important typedefs.
34  */
35  using value_type = T;
38  using reference = value_type &;
39  using const_reference = const value_type &;
40 
44  template <class U>
45  struct rebind {
46  using other = object_traits<U>;
47  };
48 
52  object_traits() = default;
53 
57  ~object_traits() = default;
58 
62  template <typename U,
63  typename = typename std::enable_if<
64  std::is_convertible<U *, T *>::value>::type>
65  explicit object_traits(object_traits<U> const &)
66  {
67  }
68 
81  void
82  construct(pointer p, const_reference t)
83  {
84  if (pmemobj_tx_stage() != TX_STAGE_WORK)
86  "construct is called outside of transaction scope");
87 
88  /* construct called on newly allocated objects */
89  detail::conditional_add_to_tx(p.get());
90  new (static_cast<void *>(p.get())) value_type(t);
91  }
92 
105  template <typename... Args>
106  void
107  construct(pointer p, Args &&... args)
108  {
109  if (pmemobj_tx_stage() != TX_STAGE_WORK)
111  "construct is called outside of transaction scope");
112 
113  detail::conditional_add_to_tx(p.get());
114  new (static_cast<void *>(p.get()))
115  value_type(std::forward<Args>(args)...);
116  }
117 
125  void
127  {
128  /* XXX should we allow modifications outside of tx? */
129  if (pmemobj_tx_stage() == TX_STAGE_WORK) {
130  pmemobj_tx_add_range_direct((void *)p.get(), sizeof(p));
131  }
132 
133  detail::destroy<value_type>(*p);
134  }
135 };
136 
141 template <>
142 class object_traits<void> {
143 public:
144  /*
145  * Important typedefs.
146  */
147  using value_type = void;
149 
153  template <class U>
154  struct rebind {
155  using other = object_traits<U>;
156  };
157 
161  object_traits() = default;
162 
166  ~object_traits() = default;
167 
171  template <typename U>
172  explicit object_traits(object_traits<U> const &)
173  {
174  }
175 };
176 
183 template <typename T>
185 public:
186  /*
187  * Important typedefs.
188  */
189  using value_type = T;
192  using size_type = std::size_t;
193  using bool_type = bool;
194 
198  template <class U>
199  struct rebind {
201  };
202 
207 
212 
217  {
218  }
219 
223  template <typename U,
224  typename = typename std::enable_if<
225  std::is_convertible<U *, T *>::value>::type>
227  {
228  }
229 
241  pointer
242  allocate(size_type cnt, const_void_pointer = 0)
243  {
244  if (pmemobj_tx_stage() != TX_STAGE_WORK)
246  "refusing to allocate memory outside of transaction scope");
247 
248  /* allocate raw memory, no object construction */
249  pointer ptr = pmemobj_tx_alloc(sizeof(value_type) * cnt,
250  detail::type_num<value_type>());
251 
252  if (ptr == nullptr) {
253  if (errno == ENOMEM) {
255  "Failed to allocate persistent memory object")
256  .with_pmemobj_errormsg();
257  } else {
259  "Failed to allocate persistent memory object")
260  .with_pmemobj_errormsg();
261  }
262  }
263 
264  return ptr;
265  }
266 
274  void
275  deallocate(pointer p, size_type = 0)
276  {
277  if (pmemobj_tx_stage() != TX_STAGE_WORK)
279  "refusing to free memory outside of transaction scope");
280 
281  if (pmemobj_tx_free(*p.raw_ptr()) != 0)
283  "failed to delete persistent memory object")
284  .with_pmemobj_errormsg();
285  }
286 
292  size_type
293  max_size() const
294  {
295  return PMEMOBJ_MAX_ALLOC_SIZE / sizeof(value_type);
296  }
297 };
298 
302 template <>
304 public:
305  /*
306  * Important typedefs.
307  */
308  using value_type = void;
311  using reference = value_type;
312  using const_reference = const value_type;
313  using size_type = std::size_t;
314  using bool_type = bool;
315 
319  template <class U>
320  struct rebind {
322  };
323 
328 
333 
338  {
339  }
340 
344  template <typename U>
346  {
347  }
348 
356  pointer
357  allocate(size_type cnt, const_pointer = 0)
358  {
359  if (pmemobj_tx_stage() != TX_STAGE_WORK)
361  "refusing to allocate memory outside of transaction scope");
362 
363  /* allocate raw memory, no object construction */
364  pointer ptr = pmemobj_tx_alloc(1 /* void size */ * cnt, 0);
365 
366  if (ptr == nullptr) {
367  if (errno == ENOMEM) {
369  "Failed to allocate persistent memory object")
370  .with_pmemobj_errormsg();
371  } else {
373  "Failed to allocate persistent memory object")
374  .with_pmemobj_errormsg();
375  }
376  }
377 
378  return ptr;
379  }
380 
388  void
389  deallocate(pointer p, size_type = 0)
390  {
391  if (pmemobj_tx_stage() != TX_STAGE_WORK)
393  "refusing to free memory outside of transaction scope");
394 
395  if (pmemobj_tx_free(p.raw()) != 0)
397  "failed to delete persistent memory object")
398  .with_pmemobj_errormsg();
399  }
400 
406  size_type
407  max_size() const
408  {
409  return PMEMOBJ_MAX_ALLOC_SIZE;
410  }
411 };
412 
418 template <typename T, typename T2>
419 inline bool
421 {
422  return true;
423 }
424 
430 template <typename T, typename OtherAllocator>
431 inline bool
432 operator==(standard_alloc_policy<T> const &, OtherAllocator const &)
433 {
434  return false;
435 }
436 
444 template <typename T, typename Policy = standard_alloc_policy<T>,
445  typename Traits = object_traits<T>>
446 class allocator : public Policy, public Traits {
447 private:
448  /*
449  * private typedefs
450  */
451  using AllocationPolicy = Policy;
452  using TTraits = Traits;
453 
454 public:
455  /*
456  * Important typedefs.
457  */
458  using size_type = typename AllocationPolicy::size_type;
459  using pointer = typename AllocationPolicy::pointer;
460  using value_type = typename AllocationPolicy::value_type;
461 
465  template <typename U>
466  struct rebind {
467  using other = allocator<
468  U, typename AllocationPolicy::template rebind<U>::other,
469  typename TTraits::template rebind<U>::other>;
470  };
471 
475  allocator() = default;
476 
480  ~allocator() = default;
481 
485  allocator(allocator const &rhs) : Policy(rhs), Traits(rhs)
486  {
487  }
488 
492  template <typename U>
493  explicit allocator(allocator<U> const &)
494  {
495  }
496 
500  template <typename U, typename P, typename T2>
501  explicit allocator(allocator<U, P, T2> const &rhs)
502  : Policy(rhs), Traits(rhs)
503  {
504  }
505 };
506 
516 template <typename T, typename P, typename Tr, typename T2, typename P2,
517  typename Tr2>
518 inline bool
520 {
521  return operator==(static_cast<const P &>(lhs),
522  static_cast<const P2 &>(rhs));
523 }
524 
534 template <typename T, typename P, typename Tr, typename OtherAllocator>
535 inline bool
536 operator!=(const allocator<T, P, Tr> &lhs, const OtherAllocator &rhs)
537 {
538  return !operator==(lhs, rhs);
539 }
540 
541 } /* namespace obj */
542 
543 } /* namespace pmem */
544 
545 #endif /* LIBPMEMOBJ_CPP_ALLOCATOR_HPP */
(EXPERIMENTAL) Encapsulates the information about the persistent memory allocation model using PMDK's...
Definition: allocator.hpp:446
allocator()=default
Defaulted constructor.
~allocator()=default
Defaulted destructor.
allocator(allocator< U, P, T2 > const &rhs)
Type converting constructor.
Definition: allocator.hpp:501
allocator(allocator< U > const &)
Type converting constructor.
Definition: allocator.hpp:493
allocator(allocator const &rhs)
Copy constructor.
Definition: allocator.hpp:485
object_traits()=default
Defaulted constructor.
~object_traits()=default
Defaulted destructor.
object_traits(object_traits< U > const &)
Type converting constructor.
Definition: allocator.hpp:172
Encapsulates object specific allocator functionality.
Definition: allocator.hpp:30
object_traits()=default
Defaulted constructor.
object_traits(object_traits< U > const &)
Type converting constructor.
Definition: allocator.hpp:65
void destroy(pointer p)
Destroy an object based on a pointer.
Definition: allocator.hpp:126
void construct(pointer p, const_reference t)
Create an object at a specific address.
Definition: allocator.hpp:82
~object_traits()=default
Defaulted destructor.
void construct(pointer p, Args &&... args)
Create an object at a specific address.
Definition: allocator.hpp:107
Resides on pmem class.
Definition: p.hpp:35
persistent_ptr const void specialization.
Definition: persistent_ptr.hpp:88
Persistent pointer class.
Definition: persistent_ptr.hpp:152
size_type max_size() const
The largest value that can meaningfully be passed to allocate().
Definition: allocator.hpp:407
standard_alloc_policy(standard_alloc_policy< U > const &)
Type converting constructor.
Definition: allocator.hpp:345
standard_alloc_policy(standard_alloc_policy const &)
Explicit copy constructor.
Definition: allocator.hpp:337
pointer allocate(size_type cnt, const_pointer=0)
Allocate storage for cnt bytes.
Definition: allocator.hpp:357
~standard_alloc_policy()=default
Defaulted destructor.
standard_alloc_policy()=default
Defaulted constructor.
void deallocate(pointer p, size_type=0)
Deallocates storage pointed to p, which must be a value returned by a previous call to allocate that ...
Definition: allocator.hpp:389
The allocation policy template for a given type.
Definition: allocator.hpp:184
size_type max_size() const
The largest value that can meaningfully be passed to allocate().
Definition: allocator.hpp:293
~standard_alloc_policy()=default
Defaulted destructor.
pointer allocate(size_type cnt, const_void_pointer=0)
Allocate storage for cnt objects of type T.
Definition: allocator.hpp:242
standard_alloc_policy()=default
Defaulted constructor.
void deallocate(pointer p, size_type=0)
Deallocates storage pointed to p, which must be a value returned by a previous call to allocate that ...
Definition: allocator.hpp:275
standard_alloc_policy(standard_alloc_policy< U > const &)
Type converting constructor.
Definition: allocator.hpp:226
standard_alloc_policy(standard_alloc_policy const &)
Explicit copy constructor.
Definition: allocator.hpp:216
Custom transaction error class.
Definition: pexceptions.hpp:119
Custom transaction error class.
Definition: pexceptions.hpp:158
Custom out of memory error class.
Definition: pexceptions.hpp:138
Custom transaction error class.
Definition: pexceptions.hpp:176
Commonly used functionality.
Functions for destroying arrays.
bool operator!=(const allocator< T, P, Tr > &lhs, const OtherAllocator &rhs)
Determines if memory from another allocator can be deallocated from this one.
Definition: allocator.hpp:536
bool operator==(standard_alloc_policy< T > const &, standard_alloc_policy< T2 > const &)
Determines if memory from another allocator can be deallocated from this one.
Definition: allocator.hpp:420
Persistent memory namespace.
Definition: allocation_flag.hpp:15
Persistent smart pointer.
Custom exceptions.
Convenience extensions for the resides on pmem property template.
Rebind to a different type.
Definition: allocator.hpp:466
Rebind to a different type.
Definition: allocator.hpp:45
Rebind to a different type.
Definition: allocator.hpp:199