proxygen
folly::detail::ThreadCachedInts< Tag > Class Template Reference

#include <ThreadCachedInts.h>

Classes

class  Integer
 

Public Member Functions

FOLLY_ALWAYS_INLINE void increment (uint8_t epoch)
 
FOLLY_ALWAYS_INLINE void decrement (uint8_t epoch)
 
int64_t readFull (uint8_t epoch)
 
void waitForZero (uint8_t phase)
 
void resetAfterFork ()
 

Private Member Functions

void init ()
 

Private Attributes

std::atomic< int64_torphan_inc_ [2] = {}
 
std::atomic< int64_torphan_dec_ [2] = {}
 
folly::detail::Futex waiting_ {0}
 
folly::ThreadLocalPtr< Integer, Tagcs_
 

Static Private Attributes

static thread_local Integerint_cache_ = nullptr
 

Detailed Description

template<typename Tag>
class folly::detail::ThreadCachedInts< Tag >

Definition at line 38 of file ThreadCachedInts.h.

Member Function Documentation

template<typename Tag>
FOLLY_ALWAYS_INLINE void folly::detail::ThreadCachedInts< Tag >::decrement ( uint8_t  epoch)
inline

Definition at line 92 of file ThreadCachedInts.h.

92  {
94  if (!int_cache_) {
95  init();
96  }
97 
98  auto& c = int_cache_->dec_[epoch];
99  auto val = c.load(std::memory_order_relaxed);
100  c.store(val + 1, std::memory_order_relaxed);
101 
103  if (waiting_.load(std::memory_order_acquire)) {
104  waiting_.store(0, std::memory_order_release);
106  }
107  }
static thread_local Integer * int_cache_
double val
Definition: String.cpp:273
FOLLY_ALWAYS_INLINE void asymmetricLightBarrier()
char c
int futexWake(const Futex *futex, int count, uint32_t wakeMask)
Definition: Futex-inl.h:107
template<typename Tag>
FOLLY_ALWAYS_INLINE void folly::detail::ThreadCachedInts< Tag >::increment ( uint8_t  epoch)
inline

Definition at line 80 of file ThreadCachedInts.h.

80  {
81  if (!int_cache_) {
82  init();
83  }
84 
85  auto& c = int_cache_->inc_[epoch];
86  auto val = c.load(std::memory_order_relaxed);
87  c.store(val + 1, std::memory_order_relaxed);
88 
90  }
static thread_local Integer * int_cache_
double val
Definition: String.cpp:273
FOLLY_ALWAYS_INLINE void asymmetricLightBarrier()
char c
template<typename Tag>
void folly::detail::ThreadCachedInts< Tag >::init ( )
inlineprivate

Definition at line 73 of file ThreadCachedInts.h.

Referenced by folly::detail::ThreadCachedInts< folly::detail::folly::detail::Tag >::decrement(), and folly::detail::ThreadCachedInts< folly::detail::folly::detail::Tag >::increment().

73  {
74  auto ret = new Integer(this);
75  cs_.reset(ret);
76  int_cache_ = ret;
77  }
static thread_local Integer * int_cache_
folly::ThreadLocalPtr< Integer, Tag > cs_
template<typename Tag>
int64_t folly::detail::ThreadCachedInts< Tag >::readFull ( uint8_t  epoch)
inline

Definition at line 109 of file ThreadCachedInts.h.

Referenced by folly::detail::ThreadCachedInts< folly::detail::folly::detail::Tag >::waitForZero().

109  {
110  int64_t full = -orphan_dec_[epoch].load(std::memory_order_relaxed);
111 
112  // Matches A - ensure all threads have seen new value of version,
113  // *and* that we see current values of counters in readFull()
114  //
115  // Note that in lock_shared if a reader is currently between the
116  // version load and counter increment, they may update the wrong
117  // epoch. However, this is ok - they started concurrently *after*
118  // any callbacks that will run, and therefore it is safe to run
119  // the callbacks.
121  for (auto& i : cs_.accessAllThreads()) {
122  full -= i.dec_[epoch].load(std::memory_order_relaxed);
123  }
124 
125  // Matches B - ensure that all increments are seen if decrements
126  // are seen. This is necessary because increment and decrement
127  // are allowed to happen on different threads.
129 
130  auto accessor = cs_.accessAllThreads();
131  for (auto& i : accessor) {
132  full += i.inc_[epoch].load(std::memory_order_relaxed);
133  }
134 
135  // orphan is read behind accessAllThreads lock
136  return full + orphan_inc_[epoch].load(std::memory_order_relaxed);
137  }
void asymmetricHeavyBarrier(AMBFlags flags)
folly::ThreadLocalPtr< Integer, Tag > cs_
std::atomic< int64_t > orphan_dec_[2]
std::atomic< int64_t > orphan_inc_[2]
template<typename Tag>
void folly::detail::ThreadCachedInts< Tag >::resetAfterFork ( )
inline

Definition at line 161 of file ThreadCachedInts.h.

161  {
162  if (int_cache_) {
163  int_cache_->dec_[0].store(0, std::memory_order_relaxed);
164  int_cache_->dec_[1].store(0, std::memory_order_relaxed);
165  int_cache_->inc_[0].store(0, std::memory_order_relaxed);
166  int_cache_->inc_[1].store(0, std::memory_order_relaxed);
167  }
168  orphan_inc_[0].store(0, std::memory_order_relaxed);
169  orphan_inc_[1].store(0, std::memory_order_relaxed);
170  orphan_dec_[0].store(0, std::memory_order_relaxed);
171  orphan_dec_[1].store(0, std::memory_order_relaxed);
172  }
static thread_local Integer * int_cache_
std::atomic< int64_t > orphan_dec_[2]
std::atomic< int64_t > orphan_inc_[2]
template<typename Tag>
void folly::detail::ThreadCachedInts< Tag >::waitForZero ( uint8_t  phase)
inline

Definition at line 139 of file ThreadCachedInts.h.

139  {
140  // Try reading before futex sleeping.
141  if (readFull(phase) == 0) {
142  return;
143  }
144 
145  while (true) {
146  waiting_.store(1, std::memory_order_release);
147  // Matches C. Ensure either decrement sees waiting_,
148  // or we see their decrement and can safely sleep.
150  if (readFull(phase) == 0) {
151  break;
152  }
154  }
155  waiting_.store(0, std::memory_order_relaxed);
156  }
void asymmetricHeavyBarrier(AMBFlags flags)
FutexResult futexWait(const Futex *futex, uint32_t expected, uint32_t waitMask)
Definition: Futex-inl.h:100
int64_t readFull(uint8_t epoch)

Member Data Documentation

template<typename Tag>
folly::ThreadLocalPtr<Integer, Tag> folly::detail::ThreadCachedInts< Tag >::cs_
private

Definition at line 68 of file ThreadCachedInts.h.

template<typename Tag>
thread_local detail::ThreadCachedInts< Tag >::Integer * folly::detail::ThreadCachedInts< Tag >::int_cache_ = nullptr
staticprivate

Definition at line 71 of file ThreadCachedInts.h.

template<typename Tag>
std::atomic<int64_t> folly::detail::ThreadCachedInts< Tag >::orphan_dec_[2] = {}
private
template<typename Tag>
std::atomic<int64_t> folly::detail::ThreadCachedInts< Tag >::orphan_inc_[2] = {}
private

The documentation for this class was generated from the following file: