proxygen
folly::PicoSpinLock< IntType, Bit > Struct Template Reference

#include <PicoSpinLock.h>

Public Types

typedef std::make_unsigned< IntType >::type UIntType
 

Public Member Functions

void init (IntType initialValue=0)
 
IntType getData () const
 
void setData (IntType w)
 
bool try_lock () const
 
void lock () const
 
void unlock () const
 

Public Attributes

UIntType lock_
 

Static Public Attributes

static const UIntType kLockBitMask_ = UIntType(1) << Bit
 

Detailed Description

template<class IntType, int Bit = sizeof(IntType) * 8 - 1>
struct folly::PicoSpinLock< IntType, Bit >

Definition at line 73 of file PicoSpinLock.h.

Member Typedef Documentation

template<class IntType, int Bit = sizeof(IntType) * 8 - 1>
typedef std::make_unsigned<IntType>::type folly::PicoSpinLock< IntType, Bit >::UIntType

Definition at line 75 of file PicoSpinLock.h.

Member Function Documentation

template<class IntType, int Bit = sizeof(IntType) * 8 - 1>
IntType folly::PicoSpinLock< IntType, Bit >::getData ( ) const
inline

Definition at line 111 of file PicoSpinLock.h.

Referenced by folly::PackedSyncPtr< T >::extra(), folly::PackedSyncPtr< T >::get(), and folly::PackedSyncPtr< T >::setExtra().

111  {
112  auto res = reinterpret_cast<std::atomic<UIntType>*>(&lock_)->load(
113  std::memory_order_relaxed) &
114  ~kLockBitMask_;
115  return res;
116  }
def load()
Definition: deadlock.py:441
static const UIntType kLockBitMask_
Definition: PicoSpinLock.h:85
template<class IntType, int Bit = sizeof(IntType) * 8 - 1>
void folly::PicoSpinLock< IntType, Bit >::init ( IntType  initialValue = 0)
inline

Definition at line 96 of file PicoSpinLock.h.

Referenced by folly::PackedSyncPtr< T >::init().

96  {
97  CHECK(!(initialValue & kLockBitMask_));
98  reinterpret_cast<std::atomic<UIntType>*>(&lock_)->store(
99  UIntType(initialValue), std::memory_order_release);
100  }
static const UIntType kLockBitMask_
Definition: PicoSpinLock.h:85
std::make_unsigned< IntType >::type UIntType
Definition: PicoSpinLock.h:75
template<class IntType, int Bit = sizeof(IntType) * 8 - 1>
void folly::PicoSpinLock< IntType, Bit >::lock ( ) const
inline

Definition at line 229 of file PicoSpinLock.h.

Referenced by folly::PackedSyncPtr< T >::lock().

229  {
230  detail::Sleeper sleeper;
231  while (!try_lock()) {
232  sleeper.wait();
233  }
234  }
bool try_lock() const
Definition: PicoSpinLock.h:136
template<class IntType, int Bit = sizeof(IntType) * 8 - 1>
void folly::PicoSpinLock< IntType, Bit >::setData ( IntType  w)
inline

Definition at line 124 of file PicoSpinLock.h.

Referenced by folly::PackedSyncPtr< T >::set(), and folly::PackedSyncPtr< T >::setExtra().

124  {
125  CHECK(!(w & kLockBitMask_));
126  auto l = reinterpret_cast<std::atomic<UIntType>*>(&lock_);
127  l->store(
128  (l->load(std::memory_order_relaxed) & kLockBitMask_) | w,
129  std::memory_order_relaxed);
130  }
static const UIntType kLockBitMask_
Definition: PicoSpinLock.h:85
template<class IntType, int Bit = sizeof(IntType) * 8 - 1>
bool folly::PicoSpinLock< IntType, Bit >::try_lock ( ) const
inline

Definition at line 136 of file PicoSpinLock.h.

Referenced by folly::PackedSyncPtr< T >::try_lock().

136  {
137  bool ret = false;
138 
139 #if defined(FOLLY_SANITIZE_THREAD)
140  // TODO: Might be able to fully move to std::atomic when gcc emits lock btr:
141  // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49244
142  ret =
143  !(reinterpret_cast<std::atomic<UIntType>*>(&lock_)->fetch_or(
144  kLockBitMask_, std::memory_order_acquire) &
145  kLockBitMask_);
146 #elif _MSC_VER
147  switch (sizeof(IntType)) {
148  case 2:
149  // There is no _interlockedbittestandset16 for some reason :(
150  ret = _InterlockedOr16((volatile short*)&lock_, (short)kLockBitMask_) &
152  break;
153  case 4:
154  ret = _interlockedbittestandset((volatile long*)&lock_, Bit);
155  break;
156  case 8:
157  ret = _interlockedbittestandset64((volatile long long*)&lock_, Bit);
158  break;
159  }
160 #elif FOLLY_X64
161 #define FB_DOBTS(size) \
162  asm volatile("lock; bts" #size " %1, (%2); setnc %0" \
163  : "=r"(ret) \
164  : "i"(Bit), "r"(&lock_) \
165  : "memory", "flags")
166 
167  switch (sizeof(IntType)) {
168  case 2:
169  FB_DOBTS(w);
170  break;
171  case 4:
172  FB_DOBTS(l);
173  break;
174  case 8:
175  FB_DOBTS(q);
176  break;
177  }
178 
179 #undef FB_DOBTS
180 #elif FOLLY_AARCH64
181  using SIntType = typename std::make_signed<UIntType>::type;
182  auto const lock = reinterpret_cast<SIntType*>(&lock_);
183  auto const mask = static_cast<SIntType>(kLockBitMask_);
184  return !(mask & __atomic_fetch_or(lock, mask, __ATOMIC_ACQUIRE));
185 #elif FOLLY_PPC64
186 #define FB_DOBTS(size) \
187  asm volatile( \
188  "\teieio\n" \
189  "\tl" #size \
190  "arx 14,0,%[lockPtr]\n" \
191  "\tli 15,1\n" \
192  "\tsldi 15,15,%[bit]\n" \
193  "\tand. 16,15,14\n" \
194  "\tbne 0f\n" \
195  "\tor 14,14,15\n" \
196  "\tst" #size \
197  "cx. 14,0,%[lockPtr]\n" \
198  "\tbne 0f\n" \
199  "\tori %[output],%[output],1\n" \
200  "\tisync\n" \
201  "0:\n" \
202  : [output] "+r"(ret) \
203  : [lockPtr] "r"(&lock_), [bit] "i"(Bit) \
204  : "cr0", "memory", "r14", "r15", "r16")
205 
206  switch (sizeof(IntType)) {
207  case 2:
208  FB_DOBTS(h);
209  break;
210  case 4:
211  FB_DOBTS(w);
212  break;
213  case 8:
214  FB_DOBTS(d);
215  break;
216  }
217 
218 #undef FB_DOBTS
219 #else
220 #error "x86 aarch64 ppc64 only"
221 #endif
222 
223  return ret;
224  }
*than *hazptr_holder h
Definition: Hazptr.h:116
PskType type
void lock() const
Definition: PicoSpinLock.h:229
static const UIntType kLockBitMask_
Definition: PicoSpinLock.h:85
template<class IntType, int Bit = sizeof(IntType) * 8 - 1>
void folly::PicoSpinLock< IntType, Bit >::unlock ( ) const
inline

Definition at line 240 of file PicoSpinLock.h.

Referenced by folly::PackedSyncPtr< T >::unlock().

240  {
241 #ifdef _MSC_VER
242  switch (sizeof(IntType)) {
243  case 2:
244  // There is no _interlockedbittestandreset16 for some reason :(
245  _InterlockedAnd16((volatile short*)&lock_, (short)~kLockBitMask_);
246  break;
247  case 4:
248  _interlockedbittestandreset((volatile long*)&lock_, Bit);
249  break;
250  case 8:
251  _interlockedbittestandreset64((volatile long long*)&lock_, Bit);
252  break;
253  }
254 #elif FOLLY_X64
255 #define FB_DOBTR(size) \
256  asm volatile("lock; btr" #size " %0, (%1)" \
257  : \
258  : "i"(Bit), "r"(&lock_) \
259  : "memory", "flags")
260 
261  // Reads and writes can not be reordered wrt locked instructions,
262  // so we don't need a memory fence here.
263  switch (sizeof(IntType)) {
264  case 2:
265  FB_DOBTR(w);
266  break;
267  case 4:
268  FB_DOBTR(l);
269  break;
270  case 8:
271  FB_DOBTR(q);
272  break;
273  }
274 
275 #undef FB_DOBTR
276 #elif FOLLY_AARCH64
277  using SIntType = typename std::make_signed<UIntType>::type;
278  auto const lock = reinterpret_cast<SIntType*>(&lock_);
279  auto const mask = static_cast<SIntType>(kLockBitMask_);
280  __atomic_fetch_and(lock, ~mask, __ATOMIC_RELEASE);
281 #elif FOLLY_PPC64
282 #define FB_DOBTR(size) \
283  asm volatile( \
284  "\teieio\n" \
285  "0: l" #size \
286  "arx 14,0,%[lockPtr]\n" \
287  "\tli 15,1\n" \
288  "\tsldi 15,15,%[bit]\n" \
289  "\txor 14,14,15\n" \
290  "\tst" #size \
291  "cx. 14,0,%[lockPtr]\n" \
292  "\tbne 0b\n" \
293  "\tisync\n" \
294  : \
295  : [lockPtr] "r"(&lock_), [bit] "i"(Bit) \
296  : "cr0", "memory", "r14", "r15")
297 
298  switch (sizeof(IntType)) {
299  case 2:
300  FB_DOBTR(h);
301  break;
302  case 4:
303  FB_DOBTR(w);
304  break;
305  case 8:
306  FB_DOBTR(d);
307  break;
308  }
309 
310 #undef FB_DOBTR
311 #else
312 #error "x64 aarch64 ppc64 only"
313 #endif
314  }
*than *hazptr_holder h
Definition: Hazptr.h:116
PskType type
void lock() const
Definition: PicoSpinLock.h:229
static const UIntType kLockBitMask_
Definition: PicoSpinLock.h:85

Member Data Documentation

template<class IntType, int Bit = sizeof(IntType) * 8 - 1>
const UIntType folly::PicoSpinLock< IntType, Bit >::kLockBitMask_ = UIntType(1) << Bit
static

Definition at line 85 of file PicoSpinLock.h.

template<class IntType, int Bit = sizeof(IntType) * 8 - 1>
UIntType folly::PicoSpinLock< IntType, Bit >::lock_
mutable

Definition at line 86 of file PicoSpinLock.h.


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