PMDK C++ bindings  1.13.0-git23.gf49772ac
This is the C++ bindings documentation for PMDK's libpmemobj.
atomic_backoff.hpp
Go to the documentation of this file.
1 // SPDX-License-Identifier: BSD-3-Clause
2 /* Copyright 2019-2020, Intel Corporation */
3 
13 #ifndef LIBPMEMOBJ_ATOMIC_BACKOFF_HPP
14 #define LIBPMEMOBJ_ATOMIC_BACKOFF_HPP
15 
16 #include <thread>
17 
18 #if _MSC_VER
19 #include <intrin.h>
20 #include <windows.h>
21 #endif
22 
23 namespace pmem
24 {
25 namespace detail
26 {
27 
28 class atomic_backoff {
34  static const int32_t LOOPS_BEFORE_YIELD = 16;
35  int32_t count;
36 
37  static inline void
38  __pause(int32_t delay)
39  {
40  for (; delay > 0; --delay) {
41 #if _MSC_VER
42  YieldProcessor();
43 #elif __GNUC__ && (__i386__ || __x86_64__)
44  // Only i386 and x86-64 have pause instruction
45  __builtin_ia32_pause();
46 #endif
47  }
48  }
49 
50 public:
54  atomic_backoff(const atomic_backoff &) = delete;
58  atomic_backoff &operator=(const atomic_backoff &) = delete;
59 
61  /* In many cases, an object of this type is initialized eagerly on hot
62  * path, as in for(atomic_backoff b; ; b.pause()) {...} For this reason,
63  * the construction cost must be very small! */
64  atomic_backoff() : count(1)
65  {
66  }
67 
71  atomic_backoff(bool) : count(1)
72  {
73  pause();
74  }
75 
79  void
80  pause()
81  {
82  if (count <= LOOPS_BEFORE_YIELD) {
83  __pause(count);
84  /* Pause twice as long the next time. */
85  count *= 2;
86  } else {
87  /* Pause is so long that we might as well yield CPU to
88  * scheduler. */
89  std::this_thread::yield();
90  }
91  }
92 
96  bool
97  bounded_pause()
98  {
99  __pause(count);
100  if (count < LOOPS_BEFORE_YIELD) {
101  /* Pause twice as long the next time. */
102  count *= 2;
103  return true;
104  } else {
105  return false;
106  }
107  }
108 
109  void
110  reset()
111  {
112  count = 1;
113  }
114 }; /* class atomic_backoff */
115 
116 } /* namespace detail */
117 
118 } /* namespace pmem */
119 
120 #endif
Persistent memory namespace.
Definition: allocation_flag.hpp:15