PMDK C++ bindings  1.8.2
This is the C++ bindings documentation for PMDK's libpmemobj.
allocator.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2016-2019, Intel Corporation
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  *
16  * * Neither the name of the copyright holder nor the names of its
17  * contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
38 #ifndef LIBPMEMOBJ_CPP_ALLOCATOR_HPP
39 #define LIBPMEMOBJ_CPP_ALLOCATOR_HPP
40 
45 #include <libpmemobj++/pext.hpp>
46 #include <libpmemobj/tx_base.h>
47 
48 namespace pmem
49 {
50 
51 namespace obj
52 {
53 
58 template <typename T>
60 public:
61  /*
62  * Important typedefs.
63  */
64  using value_type = T;
67  using reference = value_type &;
68  using const_reference = const value_type &;
69 
73  template <class U>
74  struct rebind {
75  using other = object_traits<U>;
76  };
77 
81  object_traits() = default;
82 
86  ~object_traits() = default;
87 
91  template <typename U,
92  typename = typename std::enable_if<
93  std::is_convertible<U *, T *>::value>::type>
94  explicit object_traits(object_traits<U> const &)
95  {
96  }
97 
106  void
107  construct(pointer p, const_reference t)
108  {
109  /* construct called on newly allocated objects */
110  detail::conditional_add_to_tx(p.get());
111  new (static_cast<void *>(p.get())) value_type(t);
112  }
113 
122  template <typename... Args>
123  void
124  construct(pointer p, Args &&... args)
125  {
126  detail::conditional_add_to_tx(p.get());
127  new (static_cast<void *>(p.get()))
128  value_type(std::forward<Args>(args)...);
129  }
130 
138  void
140  {
141  /* XXX should we allow modifications outside of tx? */
142  if (pmemobj_tx_stage() == TX_STAGE_WORK) {
143  pmemobj_tx_add_range_direct((void *)p.get(), sizeof(p));
144  }
145 
146  detail::destroy<value_type>(*p);
147  }
148 };
149 
154 template <>
155 class object_traits<void> {
156 public:
157  /*
158  * Important typedefs.
159  */
160  using value_type = void;
162 
166  template <class U>
167  struct rebind {
168  using other = object_traits<U>;
169  };
170 
174  object_traits() = default;
175 
179  ~object_traits() = default;
180 
184  template <typename U>
185  explicit object_traits(object_traits<U> const &)
186  {
187  }
188 };
189 
196 template <typename T>
198 public:
199  /*
200  * Important typedefs.
201  */
202  using value_type = T;
204  using const_void_pointer = persistent_ptr<const void>;
205  using size_type = std::size_t;
206  using bool_type = bool;
207 
211  template <class U>
212  struct rebind {
214  };
215 
219  standard_alloc_policy() = default;
220 
224  ~standard_alloc_policy() = default;
225 
230  {
231  }
232 
236  template <typename U,
237  typename = typename std::enable_if<
238  std::is_convertible<U *, T *>::value>::type>
240  {
241  }
242 
251  pointer
252  allocate(size_type cnt, const_void_pointer = 0)
253  {
254  if (pmemobj_tx_stage() != TX_STAGE_WORK)
256  "refusing to allocate memory outside of transaction scope");
257 
258  /* allocate raw memory, no object construction */
259  return pmemobj_tx_alloc(sizeof(value_type) * cnt,
260  detail::type_num<T>());
261  }
262 
270  void
271  deallocate(pointer p, size_type = 0)
272  {
273  if (pmemobj_tx_stage() != TX_STAGE_WORK)
275  "refusing to free memory outside of transaction scope");
276 
277  if (pmemobj_tx_free(*p.raw_ptr()) != 0)
279  "failed to delete persistent memory object")
280  .with_pmemobj_errormsg();
281  }
282 
288  size_type
289  max_size() const
290  {
291  return PMEMOBJ_MAX_ALLOC_SIZE / sizeof(value_type);
292  }
293 };
294 
298 template <>
300 public:
301  /*
302  * Important typedefs.
303  */
304  using value_type = void;
307  using reference = value_type;
308  using const_reference = const value_type;
309  using size_type = std::size_t;
310  using bool_type = bool;
311 
315  template <class U>
316  struct rebind {
318  };
319 
323  standard_alloc_policy() = default;
324 
328  ~standard_alloc_policy() = default;
329 
334  {
335  }
336 
340  template <typename U>
342  {
343  }
344 
352  pointer
353  allocate(size_type cnt, const_pointer = 0)
354  {
355  if (pmemobj_tx_stage() != TX_STAGE_WORK)
357  "refusing to allocate memory outside of transaction scope");
358 
359  /* allocate raw memory, no object construction */
360  return pmemobj_tx_alloc(1 /* void size */ * cnt, 0);
361  }
362 
370  void
371  deallocate(pointer p, size_type = 0)
372  {
373  if (pmemobj_tx_stage() != TX_STAGE_WORK)
375  "refusing to free memory outside of transaction scope");
376 
377  if (pmemobj_tx_free(p.raw()) != 0)
379  "failed to delete persistent memory object")
380  .with_pmemobj_errormsg();
381  }
382 
388  size_type
389  max_size() const
390  {
391  return PMEMOBJ_MAX_ALLOC_SIZE;
392  }
393 };
394 
400 template <typename T, typename T2>
401 inline bool
403 {
404  return true;
405 }
406 
412 template <typename T, typename OtherAllocator>
413 inline bool
414 operator==(standard_alloc_policy<T> const &, OtherAllocator const &)
415 {
416  return false;
417 }
418 
426 template <typename T, typename Policy = standard_alloc_policy<T>,
427  typename Traits = object_traits<T>>
428 class allocator : public Policy, public Traits {
429 private:
430  /*
431  * private typedefs
432  */
433  using AllocationPolicy = Policy;
434  using TTraits = Traits;
435 
436 public:
437  /*
438  * Important typedefs.
439  */
440  using size_type = typename AllocationPolicy::size_type;
441  using pointer = typename AllocationPolicy::pointer;
442  using value_type = typename AllocationPolicy::value_type;
443 
447  template <typename U>
448  struct rebind {
449  using other = allocator<
450  U, typename AllocationPolicy::template rebind<U>::other,
451  typename TTraits::template rebind<U>::other>;
452  };
453 
457  allocator() = default;
458 
462  ~allocator() = default;
463 
467  explicit allocator(allocator const &rhs) : Policy(rhs), Traits(rhs)
468  {
469  }
470 
474  template <typename U>
475  explicit allocator(allocator<U> const &)
476  {
477  }
478 
482  template <typename U, typename P, typename T2>
483  explicit allocator(allocator<U, P, T2> const &rhs)
484  : Policy(rhs), Traits(rhs)
485  {
486  }
487 };
488 
498 template <typename T, typename P, typename Tr, typename T2, typename P2,
499  typename Tr2>
500 inline bool
502 {
503  return operator==(static_cast<const P &>(lhs),
504  static_cast<const P2 &>(rhs));
505 }
506 
516 template <typename T, typename P, typename Tr, typename OtherAllocator>
517 inline bool
518 operator!=(const allocator<T, P, Tr> &lhs, const OtherAllocator &rhs)
519 {
520  return !operator==(lhs, rhs);
521 }
522 
523 } /* namespace obj */
524 
525 } /* namespace pmem */
526 
527 #endif /* LIBPMEMOBJ_CPP_ALLOCATOR_HPP */
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:402
pointer allocate(size_type cnt, const_pointer=0)
Allocate storage for cnt bytes.
Definition: allocator.hpp:353
(EXPERIMENTAL) Encapsulates the information about the persistent memory allocation model using PMDK's...
Definition: allocator.hpp:428
standard_alloc_policy(standard_alloc_policy< U > const &)
Type converting constructor.
Definition: allocator.hpp:239
allocator(allocator const &rhs)
Explicit copy constructor.
Definition: allocator.hpp:467
Persistent pointer class.
Definition: common.hpp:125
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:371
allocator(allocator< U, P, T2 > const &rhs)
Type converting constructor.
Definition: allocator.hpp:483
object_traits(object_traits< U > const &)
Type converting constructor.
Definition: allocator.hpp:94
standard_alloc_policy()=default
Defaulted constructor.
standard_alloc_policy(standard_alloc_policy const &)
Explicit copy constructor.
Definition: allocator.hpp:229
Convenience extensions for the resides on pmem property template.
~standard_alloc_policy()=default
Defaulted destructor.
void destroy(pointer p)
Destroy an object based on a pointer.
Definition: allocator.hpp:139
Functions for destroying arrays.
Commonly used functionality.
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:271
Custom exceptions.
Rebind to a different type.
Definition: allocator.hpp:74
object_traits(object_traits< U > const &)
Type converting constructor.
Definition: allocator.hpp:185
The allocation policy template for a given type.
Definition: allocator.hpp:197
object_traits()=default
Defaulted constructor.
~object_traits()=default
Defaulted destructor.
standard_alloc_policy(standard_alloc_policy const &)
Explicit copy constructor.
Definition: allocator.hpp:333
allocator(allocator< U > const &)
Type converting constructor.
Definition: allocator.hpp:475
Rebind to a different type.
Definition: allocator.hpp:448
~allocator()=default
Defaulted destructor.
Rebind to a different type.
Definition: allocator.hpp:212
Persistent smart pointer.
pointer allocate(size_type cnt, const_void_pointer=0)
Allocate storage for cnt objects of type T.
Definition: allocator.hpp:252
Custom transaction error class.
Definition: pexceptions.hpp:167
Resides on pmem class.
Definition: p.hpp:64
size_type max_size() const
The largest value that can meaningfully be passed to allocate().
Definition: allocator.hpp:389
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:518
Custom transaction error class.
Definition: pexceptions.hpp:185
A persistent version of concurrent hash map implementation Ref: https://arxiv.org/abs/1509....
Definition: allocation_flag.hpp:43
Encapsulates object specific allocator functionality.
Definition: allocator.hpp:59
void construct(pointer p, Args &&... args)
Create an object at a specific address.
Definition: allocator.hpp:124
size_type max_size() const
The largest value that can meaningfully be passed to allocate().
Definition: allocator.hpp:289
void construct(pointer p, const_reference t)
Create an object at a specific address.
Definition: allocator.hpp:107
allocator()=default
Defaulted constructor.
standard_alloc_policy(standard_alloc_policy< U > const &)
Type converting constructor.
Definition: allocator.hpp:341