// another thread now does ++numPendingEntries_, we expect it
// to pass the isFull_.load() test above. (It shouldn't insert
// a new entry.)
- FOLLY_SPIN_WAIT(
- isFull_.load(std::memory_order_acquire) != NO_PENDING_INSERTS
- && numPendingEntries_.readFull() != 0
- );
+ detail::atomic_hash_spin_wait([&] {
+ return
+ (isFull_.load(std::memory_order_acquire) != NO_PENDING_INSERTS) &&
+ (numPendingEntries_.readFull() != 0);
+ });
isFull_.store(NO_PENDING_INSERTS, std::memory_order_release);
if (relaxedLoadKey(*cell) == kEmptyKey_) {
}
DCHECK(relaxedLoadKey(*cell) != kEmptyKey_);
if (kLockedKey_ == acquireLoadKey(*cell)) {
- FOLLY_SPIN_WAIT(
- kLockedKey_ == acquireLoadKey(*cell)
- );
+ detail::atomic_hash_spin_wait([&] {
+ return kLockedKey_ == acquireLoadKey(*cell);
+ });
}
const KeyT thisKey = acquireLoadKey(*cell);
}; // aha_iterator
} // namespace folly
-
-#undef FOLLY_SPIN_WAIT
} else {
// If we lost the race, we'll have to wait for the next map to get
// allocated before doing any insertion here.
- FOLLY_SPIN_WAIT(
- nextMapIdx >= numMapsAllocated_.load(std::memory_order_acquire)
- );
+ detail::atomic_hash_spin_wait([&] {
+ return nextMapIdx >= numMapsAllocated_.load(std::memory_order_acquire);
+ });
}
// Relaxed is ok here because either we just created this map, or we
}; // ahm_iterator
} // namespace folly
-
-#undef FOLLY_SPIN_WAIT
* limitations under the License.
*/
+#ifndef incl_FOLLY_ATOMIC_HASH_UTILS_H
+#define incl_FOLLY_ATOMIC_HASH_UTILS_H
+
+#include <folly/Portability.h>
+#include <thread>
+
// Some utilities used by AtomicHashArray and AtomicHashMap
//
-// Note: no include guard; different -inl.h files include this and
-// undef it more than once in a translation unit.
-// override-include-guard
-#if !(defined(__x86__) || defined(__i386__) || FOLLY_X64)
-#define FOLLY_SPIN_WAIT(condition) \
- for (int counter = 0; condition; ++counter) { \
- if (counter < 10000) continue; \
- pthread_yield(); \
- }
-#else
-#define FOLLY_SPIN_WAIT(condition) \
- for (int counter = 0; condition; ++counter) { \
- if (counter < 10000) { \
- asm volatile("pause"); \
- continue; \
- } \
- pthread_yield(); \
+namespace folly { namespace detail {
+
+template <typename Cond>
+void atomic_hash_spin_wait(Cond condition) {
+ constexpr size_t kPauseLimit = 10000;
+ for (size_t i = 0; condition(); ++i) {
+ if (i < kPauseLimit) {
+ folly::asm_pause();
+ } else {
+ std::this_thread::yield();
+ }
}
+}
+
+}} // namespace folly::detail
+
#endif