PMDK C++ bindings  1.7.1
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  }
281 
287  size_type
288  max_size() const
289  {
290  return PMEMOBJ_MAX_ALLOC_SIZE / sizeof(value_type);
291  }
292 };
293 
297 template <>
299 public:
300  /*
301  * Important typedefs.
302  */
303  using value_type = void;
306  using reference = value_type;
307  using const_reference = const value_type;
308  using size_type = std::size_t;
309  using bool_type = bool;
310 
314  template <class U>
315  struct rebind {
317  };
318 
322  standard_alloc_policy() = default;
323 
327  ~standard_alloc_policy() = default;
328 
333  {
334  }
335 
339  template <typename U>
341  {
342  }
343 
351  pointer
352  allocate(size_type cnt, const_pointer = 0)
353  {
354  if (pmemobj_tx_stage() != TX_STAGE_WORK)
356  "refusing to allocate memory outside of transaction scope");
357 
358  /* allocate raw memory, no object construction */
359  return pmemobj_tx_alloc(1 /* void size */ * cnt, 0);
360  }
361 
369  void
370  deallocate(pointer p, size_type = 0)
371  {
372  if (pmemobj_tx_stage() != TX_STAGE_WORK)
374  "refusing to free memory outside of transaction scope");
375 
376  if (pmemobj_tx_free(p.raw()) != 0)
378  "failed to delete persistent memory object");
379  }
380 
386  size_type
387  max_size() const
388  {
389  return PMEMOBJ_MAX_ALLOC_SIZE;
390  }
391 };
392 
398 template <typename T, typename T2>
399 inline bool
401 {
402  return true;
403 }
404 
410 template <typename T, typename OtherAllocator>
411 inline bool
412 operator==(standard_alloc_policy<T> const &, OtherAllocator const &)
413 {
414  return false;
415 }
416 
424 template <typename T, typename Policy = standard_alloc_policy<T>,
425  typename Traits = object_traits<T>>
426 class allocator : public Policy, public Traits {
427 private:
428  /*
429  * private typedefs
430  */
431  using AllocationPolicy = Policy;
432  using TTraits = Traits;
433 
434 public:
435  /*
436  * Important typedefs.
437  */
438  using size_type = typename AllocationPolicy::size_type;
439  using pointer = typename AllocationPolicy::pointer;
440  using value_type = typename AllocationPolicy::value_type;
441 
445  template <typename U>
446  struct rebind {
447  using other = allocator<
448  U, typename AllocationPolicy::template rebind<U>::other,
449  typename TTraits::template rebind<U>::other>;
450  };
451 
455  allocator() = default;
456 
460  ~allocator() = default;
461 
465  explicit allocator(allocator const &rhs) : Policy(rhs), Traits(rhs)
466  {
467  }
468 
472  template <typename U>
473  explicit allocator(allocator<U> const &)
474  {
475  }
476 
480  template <typename U, typename P, typename T2>
481  explicit allocator(allocator<U, P, T2> const &rhs)
482  : Policy(rhs), Traits(rhs)
483  {
484  }
485 };
486 
496 template <typename T, typename P, typename Tr, typename T2, typename P2,
497  typename Tr2>
498 inline bool
500 {
501  return operator==(static_cast<const P &>(lhs),
502  static_cast<const P2 &>(rhs));
503 }
504 
514 template <typename T, typename P, typename Tr, typename OtherAllocator>
515 inline bool
516 operator!=(const allocator<T, P, Tr> &lhs, const OtherAllocator &rhs)
517 {
518  return !operator==(lhs, rhs);
519 }
520 
521 } /* namespace obj */
522 
523 } /* namespace pmem */
524 
525 #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:400
pointer allocate(size_type cnt, const_pointer=0)
Allocate storage for cnt bytes.
Definition: allocator.hpp:352
(EXPERIMENTAL) Encapsulates the information about the persistent memory allocation model using PMDK's...
Definition: allocator.hpp:426
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:465
Persistent pointer class.
Definition: common.hpp:119
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:370
allocator(allocator< U, P, T2 > const &rhs)
Type converting constructor.
Definition: allocator.hpp:481
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:332
allocator(allocator< U > const &)
Type converting constructor.
Definition: allocator.hpp:473
Rebind to a different type.
Definition: allocator.hpp:446
~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:94
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:387
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:516
Custom transaction error class.
Definition: pexceptions.hpp:104
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:288
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:340