PMDK C++ bindings  1.9.1
This is the C++ bindings documentation for PMDK's libpmemobj.
common.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2016-2020, 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_COMMON_HPP
39 #define LIBPMEMOBJ_CPP_COMMON_HPP
40 
42 #include <libpmemobj/tx_base.h>
43 #include <string>
44 #include <typeinfo>
45 
46 #if _MSC_VER
47 #include <intrin.h>
48 #include <windows.h>
49 #endif
50 
51 #if defined(__GNUC__) || defined(__clang__)
52 #define POBJ_CPP_DEPRECATED __attribute__((deprecated))
53 #elif defined(_MSC_VER)
54 #define POBJ_CPP_DEPRECATED __declspec(deprecated)
55 #else
56 #define POBJ_CPP_DEPRECATED
57 #endif
58 
59 #if LIBPMEMOBJ_CPP_VG_ENABLED
60 #undef LIBPMEMOBJ_CPP_VG_PMEMCHECK_ENABLED
61 #undef LIBPMEMOBJ_CPP_VG_MEMCHECK_ENABLED
62 #undef LIBPMEMOBJ_CPP_VG_HELGRIND_ENABLED
63 #undef LIBPMEMOBJ_CPP_VG_DRD_ENABLED
64 
65 #define LIBPMEMOBJ_CPP_VG_PMEMCHECK_ENABLED 1
66 #define LIBPMEMOBJ_CPP_VG_MEMCHECK_ENABLED 1
67 #define LIBPMEMOBJ_CPP_VG_HELGRIND_ENABLED 1
68 #define LIBPMEMOBJ_CPP_VG_DRD_ENABLED 1
69 #endif
70 
71 #if LIBPMEMOBJ_CPP_VG_PMEMCHECK_ENABLED || \
72  LIBPMEMOBJ_CPP_VG_MEMCHECK_ENABLED || \
73  LIBPMEMOBJ_CPP_VG_HELGRIND_ENABLED || LIBPMEMOBJ_CPP_VG_DRD_ENABLED
74 #define LIBPMEMOBJ_CPP_ANY_VG_TOOL_ENABLED 1
75 #endif
76 
77 #if LIBPMEMOBJ_CPP_ANY_VG_TOOL_ENABLED
78 #include <valgrind.h>
79 #endif
80 
81 #if LIBPMEMOBJ_CPP_VG_PMEMCHECK_ENABLED
82 #include <pmemcheck.h>
83 #endif
84 
85 #if LIBPMEMOBJ_CPP_VG_MEMCHECK_ENABLED
86 #include <memcheck.h>
87 #endif
88 
89 #if LIBPMEMOBJ_CPP_VG_HELGRIND_ENABLED
90 #include <helgrind.h>
91 #endif
92 
93 #if LIBPMEMOBJ_CPP_VG_DRD_ENABLED
94 #include <drd.h>
95 #endif
96 
97 /*
98  * Workaround for missing "is_trivially_copyable" in gcc < 5.0.
99  * Be aware of a difference between __has_trivial_copy and is_trivially_copyable
100  * e.g. for deleted copy constructors __has_trivial_copy(A) returns 1 in clang
101  * and 0 in gcc. It means that for gcc < 5 LIBPMEMOBJ_CPP_IS_TRIVIALLY_COPYABLE
102  * is more restrictive than is_trivially_copyable.
103  */
104 #if !defined(LIBPMEMOBJ_CPP_USE_HAS_TRIVIAL_COPY)
105 #if !defined(__clang__) && defined(__GNUG__) && __GNUC__ < 5
106 #define LIBPMEMOBJ_CPP_USE_HAS_TRIVIAL_COPY 1
107 #else
108 #define LIBPMEMOBJ_CPP_USE_HAS_TRIVIAL_COPY 0
109 #endif
110 #endif
111 
112 #if LIBPMEMOBJ_CPP_USE_HAS_TRIVIAL_COPY
113 #define LIBPMEMOBJ_CPP_IS_TRIVIALLY_COPYABLE(T) __has_trivial_copy(T)
114 #else
115 #define LIBPMEMOBJ_CPP_IS_TRIVIALLY_COPYABLE(T) \
116  std::is_trivially_copyable<T>::value
117 #endif
118 
126 namespace pmem
127 {
134 namespace obj
135 {
136 template <typename T>
137 class persistent_ptr;
138 
146 namespace experimental
147 {
148 }
149 }
150 
157 namespace detail
158 {
159 
160 /*
161  * Conditionally add 'count' objects to a transaction.
162  *
163  * Adds count objects starting from `that` to the transaction if '*that' is
164  * within a pmemobj pool and there is an active transaction.
165  * Does nothing otherwise.
166  *
167  * @param[in] that pointer to the first object being added to the transaction.
168  * @param[in] count number of elements to be added to the transaction.
169  * @param[in] flags is a bitmask of values which are described in libpmemobj
170  * manpage (pmemobj_tx_xadd_range method)
171  */
172 template <typename T>
173 inline void
174 conditional_add_to_tx(const T *that, std::size_t count = 1, uint64_t flags = 0)
175 {
176  if (count == 0)
177  return;
178 
179  if (pmemobj_tx_stage() != TX_STAGE_WORK)
180  return;
181 
182  /* 'that' is not in any open pool */
183  if (!pmemobj_pool_by_ptr(that))
184  return;
185 
186  if (pmemobj_tx_xadd_range_direct(that, sizeof(*that) * count, flags)) {
187  if (errno == ENOMEM)
189  "Could not add object(s) to the transaction.")
190  .with_pmemobj_errormsg();
191  else
193  "Could not add object(s) to the transaction.")
194  .with_pmemobj_errormsg();
195  }
196 }
197 
198 /*
199  * Return type number for given type.
200  */
201 template <typename T>
202 uint64_t
203 type_num()
204 {
205  return typeid(T).hash_code();
206 }
207 
211 inline uint64_t
212 next_pow_2(uint64_t v)
213 {
214  v--;
215  v |= v >> 1;
216  v |= v >> 2;
217  v |= v >> 4;
218  v |= v >> 8;
219  v |= v >> 16;
220  v |= v >> 32;
221  ++v;
222  return v + (v == 0);
223 }
224 
228 inline uint64_t
229 next_pow_2(uint32_t v)
230 {
231  v--;
232  v |= v >> 1;
233  v |= v >> 2;
234  v |= v >> 4;
235  v |= v >> 8;
236  v |= v >> 16;
237  ++v;
238  return v + (v == 0);
239 }
240 
241 #if _MSC_VER
242 static inline int
243 Log2(uint64_t x)
244 {
245  unsigned long j;
246  _BitScanReverse64(&j, x);
247  return static_cast<int>(j);
248 }
249 #elif __GNUC__ || __clang__
250 static inline int
251 Log2(uint64_t x)
252 {
253  // __builtin_clz builtin count _number_ of leading zeroes
254  return 8 * int(sizeof(x)) - __builtin_clzll(x) - 1;
255 }
256 #else
257 static inline int
258 Log2(uint64_t x)
259 {
260  x |= (x >> 1);
261  x |= (x >> 2);
262  x |= (x >> 4);
263  x |= (x >> 8);
264  x |= (x >> 16);
265  x |= (x >> 32);
266 
267  static const int table[64] = {
268  0, 58, 1, 59, 47, 53, 2, 60, 39, 48, 27, 54, 33, 42, 3, 61,
269  51, 37, 40, 49, 18, 28, 20, 55, 30, 34, 11, 43, 14, 22, 4, 62,
270  57, 46, 52, 38, 26, 32, 41, 50, 36, 17, 19, 29, 10, 13, 21, 56,
271  45, 25, 31, 35, 16, 9, 12, 44, 24, 15, 8, 23, 7, 6, 5, 63};
272 
273  return table[(x * 0x03f6eaf2cd271461) >> 58];
274 }
275 #endif
276 
277 } /* namespace detail */
278 
279 } /* namespace pmem */
280 
281 #endif /* LIBPMEMOBJ_CPP_COMMON_HPP */
pmem::detail::next_pow_2
uint64_t next_pow_2(uint64_t v)
Round up to the next lowest power of 2.
Definition: common.hpp:212
pmem::transaction_error
Custom transaction error class.
Definition: pexceptions.hpp:94
pmem
Persistent memory namespace.
Definition: allocation_flag.hpp:44
pmem::transaction_out_of_memory
Custom out of memory error class.
Definition: pexceptions.hpp:154
pexceptions.hpp
Custom exceptions.