Fix to build SharedMutexTest on aarch64
[folly.git] / folly / RWSpinLock.h
index cc4f480a4e29b123cafd16af71963bbd3b63f03e..2f177ed001bdc71142fe4b76218ab9819892f1f4 100644 (file)
@@ -138,19 +138,19 @@ pthread_rwlock_t Read        728698     24us       101ns     7.28ms     194us
 #include <folly/Portability.h>
 #include <folly/portability/Asm.h>
 
-#if defined(__GNUC__) && \
-  (defined(__i386) || FOLLY_X64 || \
-   defined(ARCH_K8))
-# define RW_SPINLOCK_USE_X86_INTRINSIC_
-# include <x86intrin.h>
+#if defined(__GNUC__) && (defined(__i386) || FOLLY_X64 || defined(ARCH_K8))
+#define RW_SPINLOCK_USE_X86_INTRINSIC_
+#include <x86intrin.h>
 #elif defined(_MSC_VER) && defined(FOLLY_X64)
-# define RW_SPINLOCK_USE_X86_INTRINSIC_
+#define RW_SPINLOCK_USE_X86_INTRINSIC_
+#elif FOLLY_AARCH64
+#define RW_SPINLOCK_USE_X86_INTRINSIC_
 #else
-# undef RW_SPINLOCK_USE_X86_INTRINSIC_
+#undef RW_SPINLOCK_USE_X86_INTRINSIC_
 #endif
 
 // iOS doesn't define _mm_cvtsi64_si128 and friends
-#if (FOLLY_SSE >= 2) && !FOLLY_MOBILE
+#if (FOLLY_SSE >= 2) && !FOLLY_MOBILE && FOLLY_X64
 #define RW_SPINLOCK_USE_SSE_INSTRUCTIONS_
 #else
 #undef RW_SPINLOCK_USE_SSE_INSTRUCTIONS_
@@ -192,9 +192,11 @@ class RWSpinLock {
 
   // Lockable Concept
   void lock() {
-    int count = 0;
+    uint_fast32_t count = 0;
     while (!LIKELY(try_lock())) {
-      if (++count > 1000) std::this_thread::yield();
+      if (++count > 1000) {
+        std::this_thread::yield();
+      }
     }
   }
 
@@ -206,9 +208,11 @@ class RWSpinLock {
 
   // SharedLockable Concept
   void lock_shared() {
-    int count = 0;
+    uint_fast32_t count = 0;
     while (!LIKELY(try_lock_shared())) {
-      if (++count > 1000) std::this_thread::yield();
+      if (++count > 1000) {
+        std::this_thread::yield();
+      }
     }
   }
 
@@ -224,9 +228,11 @@ class RWSpinLock {
 
   // UpgradeLockable Concept
   void lock_upgrade() {
-    int count = 0;
+    uint_fast32_t count = 0;
     while (!try_lock_upgrade()) {
-      if (++count > 1000) std::this_thread::yield();
+      if (++count > 1000) {
+        std::this_thread::yield();
+      }
     }
   }
 
@@ -238,7 +244,9 @@ class RWSpinLock {
   void unlock_upgrade_and_lock() {
     int64_t count = 0;
     while (!try_unlock_upgrade_and_lock()) {
-      if (++count > 1000) std::this_thread::yield();
+      if (++count > 1000) {
+        std::this_thread::yield();
+      }
     }
   }
 
@@ -308,7 +316,9 @@ class RWSpinLock {
   class ReadHolder {
    public:
     explicit ReadHolder(RWSpinLock* lock) : lock_(lock) {
-      if (lock_) lock_->lock_shared();
+      if (lock_) {
+        lock_->lock_shared();
+      }
     }
 
     explicit ReadHolder(RWSpinLock& lock) : lock_(&lock) {
@@ -322,12 +332,16 @@ class RWSpinLock {
     // down-grade
     explicit ReadHolder(UpgradedHolder&& upgraded) : lock_(upgraded.lock_) {
       upgraded.lock_ = nullptr;
-      if (lock_) lock_->unlock_upgrade_and_lock_shared();
+      if (lock_) {
+        lock_->unlock_upgrade_and_lock_shared();
+      }
     }
 
     explicit ReadHolder(WriteHolder&& writer) : lock_(writer.lock_) {
       writer.lock_ = nullptr;
-      if (lock_) lock_->unlock_and_lock_shared();
+      if (lock_) {
+        lock_->unlock_and_lock_shared();
+      }
     }
 
     ReadHolder& operator=(ReadHolder&& other) {
@@ -339,13 +353,23 @@ class RWSpinLock {
     ReadHolder(const ReadHolder& other) = delete;
     ReadHolder& operator=(const ReadHolder& other) = delete;
 
-    ~ReadHolder() { if (lock_) lock_->unlock_shared(); }
+    ~ReadHolder() {
+      if (lock_) {
+        lock_->unlock_shared();
+      }
+    }
 
     void reset(RWSpinLock* lock = nullptr) {
-      if (lock == lock_) return;
-      if (lock_) lock_->unlock_shared();
+      if (lock == lock_) {
+        return;
+      }
+      if (lock_) {
+        lock_->unlock_shared();
+      }
       lock_ = lock;
-      if (lock_) lock_->lock_shared();
+      if (lock_) {
+        lock_->lock_shared();
+      }
     }
 
     void swap(ReadHolder* other) {
@@ -361,7 +385,9 @@ class RWSpinLock {
   class UpgradedHolder {
    public:
     explicit UpgradedHolder(RWSpinLock* lock) : lock_(lock) {
-      if (lock_) lock_->lock_upgrade();
+      if (lock_) {
+        lock_->lock_upgrade();
+      }
     }
 
     explicit UpgradedHolder(RWSpinLock& lock) : lock_(&lock) {
@@ -371,7 +397,9 @@ class RWSpinLock {
     explicit UpgradedHolder(WriteHolder&& writer) {
       lock_ = writer.lock_;
       writer.lock_ = nullptr;
-      if (lock_) lock_->unlock_and_lock_upgrade();
+      if (lock_) {
+        lock_->unlock_and_lock_upgrade();
+      }
     }
 
     UpgradedHolder(UpgradedHolder&& other) noexcept : lock_(other.lock_) {
@@ -387,13 +415,23 @@ class RWSpinLock {
     UpgradedHolder(const UpgradedHolder& other) = delete;
     UpgradedHolder& operator =(const UpgradedHolder& other) = delete;
 
-    ~UpgradedHolder() { if (lock_) lock_->unlock_upgrade(); }
+    ~UpgradedHolder() {
+      if (lock_) {
+        lock_->unlock_upgrade();
+      }
+    }
 
     void reset(RWSpinLock* lock = nullptr) {
-      if (lock == lock_) return;
-      if (lock_) lock_->unlock_upgrade();
+      if (lock == lock_) {
+        return;
+      }
+      if (lock_) {
+        lock_->unlock_upgrade();
+      }
       lock_ = lock;
-      if (lock_) lock_->lock_upgrade();
+      if (lock_) {
+        lock_->lock_upgrade();
+      }
     }
 
     void swap(UpgradedHolder* other) {
@@ -410,7 +448,9 @@ class RWSpinLock {
   class WriteHolder {
    public:
     explicit WriteHolder(RWSpinLock* lock) : lock_(lock) {
-      if (lock_) lock_->lock();
+      if (lock_) {
+        lock_->lock();
+      }
     }
 
     explicit WriteHolder(RWSpinLock& lock) : lock_(&lock) {
@@ -421,7 +461,9 @@ class RWSpinLock {
     explicit WriteHolder(UpgradedHolder&& upgraded) {
       lock_ = upgraded.lock_;
       upgraded.lock_ = nullptr;
-      if (lock_) lock_->unlock_upgrade_and_lock();
+      if (lock_) {
+        lock_->unlock_upgrade_and_lock();
+      }
     }
 
     WriteHolder(WriteHolder&& other) noexcept : lock_(other.lock_) {
@@ -437,13 +479,23 @@ class RWSpinLock {
     WriteHolder(const WriteHolder& other) = delete;
     WriteHolder& operator =(const WriteHolder& other) = delete;
 
-    ~WriteHolder () { if (lock_) lock_->unlock(); }
+    ~WriteHolder() {
+      if (lock_) {
+        lock_->unlock();
+      }
+    }
 
     void reset(RWSpinLock* lock = nullptr) {
-      if (lock == lock_) return;
-      if (lock_) lock_->unlock();
+      if (lock == lock_) {
+        return;
+      }
+      if (lock_) {
+        lock_->unlock();
+      }
       lock_ = lock;
-      if (lock_) lock_->lock();
+      if (lock_) {
+        lock_->lock();
+      }
     }
 
     void swap(WriteHolder* other) {
@@ -519,10 +571,9 @@ struct RWTicketIntTrait<32> {
   }
 #endif
 };
-}  // detail
-
+} // namespace detail
 
-template<size_t kBitWidth, bool kFavorWriter=false>
+template <size_t kBitWidth, bool kFavorWriter = false>
 class RWTicketSpinLockT {
   typedef detail::RWTicketIntTrait<kBitWidth> IntTraitType;
   typedef typename detail::RWTicketIntTrait<kBitWidth>::FullInt FullInt;
@@ -542,13 +593,13 @@ class RWTicketSpinLockT {
   } ticket;
 
  private: // Some x64-specific utilities for atomic access to ticket.
-  template<class T> static T load_acquire(T* addr) {
+  template <class T> static T load_acquire(T* addr) {
     T t = *addr; // acquire barrier
     asm_volatile_memory();
     return t;
   }
 
-  template<class T>
+  template <class T>
   static void store_release(T* addr, T v) {
     asm_volatile_memory();
     *addr = v; // release barrier
@@ -589,7 +640,9 @@ class RWTicketSpinLockT {
   bool try_lock() {
     RWTicket t;
     FullInt old = t.whole = load_acquire(&ticket.whole);
-    if (t.users != t.write) return false;
+    if (t.users != t.write) {
+      return false;
+    }
     ++t.users;
     return __sync_bool_compare_and_swap(&ticket.whole, old, t.whole);
   }
@@ -606,11 +659,13 @@ class RWTicketSpinLockT {
     // cores allocated to this process. This is less likely than the
     // corresponding situation in lock_shared(), but we still want to
     // avoid it
-    int count = 0;
+    uint_fast32_t count = 0;
     QuarterInt val = __sync_fetch_and_add(&ticket.users, 1);
     while (val != load_acquire(&ticket.write)) {
       asm_volatile_pause();
-      if (UNLIKELY(++count > 1000)) std::this_thread::yield();
+      if (UNLIKELY(++count > 1000)) {
+        std::this_thread::yield();
+      }
     }
   }
 
@@ -637,9 +692,9 @@ class RWTicketSpinLockT {
   void unlock() {
     RWTicket t;
     t.whole = load_acquire(&ticket.whole);
-    FullInt old = t.whole;
 
 #ifdef RW_SPINLOCK_USE_SSE_INSTRUCTIONS_
+    FullInt old = t.whole;
     // SSE2 can reduce the lock and unlock overhead by 10%
     static const QuarterInt kDeltaBuf[4] = { 1, 1, 0, 0 };   // write/read/user
     static const __m128i kDelta = IntTraitType::make128(kDeltaBuf);
@@ -656,10 +711,12 @@ class RWTicketSpinLockT {
     // std::this_thread::yield() is important here because we can't grab the
     // shared lock if there is a pending writeLockAggressive, so we
     // need to let threads that already have a shared lock complete
-    int count = 0;
+    uint_fast32_t count = 0;
     while (!LIKELY(try_lock_shared())) {
       asm_volatile_pause();
-      if (UNLIKELY((++count & 1023) == 0)) std::this_thread::yield();
+      if (UNLIKELY((++count & 1023) == 0)) {
+        std::this_thread::yield();
+      }
     }
   }
 
@@ -681,7 +738,7 @@ class RWTicketSpinLockT {
   }
 
   void unlock_shared() {
-    QuarterInt val = __sync_fetch_and_add(&ticket.write, 1);
+    __sync_fetch_and_add(&ticket.write, 1);
   }
 
   class WriteHolder;
@@ -693,11 +750,15 @@ class RWTicketSpinLockT {
     ReadHolder& operator=(ReadHolder const&) = delete;
 
     explicit ReadHolder(RWSpinLock* lock) : lock_(lock) {
-      if (lock_) lock_->lock_shared();
+      if (lock_) {
+        lock_->lock_shared();
+      }
     }
 
     explicit ReadHolder(RWSpinLock &lock) : lock_ (&lock) {
-      if (lock_) lock_->lock_shared();
+      if (lock_) {
+        lock_->lock_shared();
+      }
     }
 
     // atomically unlock the write-lock from writer and acquire the read-lock
@@ -709,13 +770,19 @@ class RWTicketSpinLockT {
     }
 
     ~ReadHolder() {
-      if (lock_) lock_->unlock_shared();
+      if (lock_) {
+        lock_->unlock_shared();
+      }
     }
 
     void reset(RWSpinLock *lock = nullptr) {
-      if (lock_) lock_->unlock_shared();
+      if (lock_) {
+        lock_->unlock_shared();
+      }
       lock_ = lock;
-      if (lock_) lock_->lock_shared();
+      if (lock_) {
+        lock_->lock_shared();
+      }
     }
 
     void swap(ReadHolder *other) {
@@ -732,21 +799,33 @@ class RWTicketSpinLockT {
     WriteHolder& operator=(WriteHolder const&) = delete;
 
     explicit WriteHolder(RWSpinLock* lock) : lock_(lock) {
-      if (lock_) lock_->lock();
+      if (lock_) {
+        lock_->lock();
+      }
     }
     explicit WriteHolder(RWSpinLock &lock) : lock_ (&lock) {
-      if (lock_) lock_->lock();
+      if (lock_) {
+        lock_->lock();
+      }
     }
 
     ~WriteHolder() {
-      if (lock_) lock_->unlock();
+      if (lock_) {
+        lock_->unlock();
+      }
     }
 
     void reset(RWSpinLock *lock = nullptr) {
-      if (lock == lock_) return;
-      if (lock_) lock_->unlock();
+      if (lock == lock_) {
+        return;
+      }
+      if (lock_) {
+        lock_->unlock();
+      }
       lock_ = lock;
-      if (lock_) lock_->lock();
+      if (lock_) {
+        lock_->lock();
+      }
     }
 
     void swap(WriteHolder *other) {
@@ -764,7 +843,7 @@ typedef RWTicketSpinLockT<64> RWTicketSpinLock64;
 
 #endif  // RW_SPINLOCK_USE_X86_INTRINSIC_
 
-}  // namespace folly
+} // namespace folly
 
 #ifdef RW_SPINLOCK_USE_X86_INTRINSIC_
 #undef RW_SPINLOCK_USE_X86_INTRINSIC_