Don't use pthread_spinlock_t in TimedRWMutex
authorChristopher Dykes <cdykes@fb.com>
Fri, 14 Apr 2017 00:56:39 +0000 (17:56 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Fri, 14 Apr 2017 01:05:06 +0000 (18:05 -0700)
Summary: `TimedMutex` was already using `folly::SpinLock`, so switch `TimedRWMutex` to do the same.

Reviewed By: andriigrynenko

Differential Revision: D4888005

fbshipit-source-id: 6e782347bc22dc186ed41f2e77c6614b8444bae2

folly/fibers/TimedMutex-inl.h
folly/fibers/TimedMutex.h

index c11871a..1c64a0e 100644 (file)
@@ -151,11 +151,11 @@ inline void TimedMutex::unlock() {
 
 template <typename BatonType>
 void TimedRWMutex<BatonType>::read_lock() {
-  pthread_spin_lock(&lock_);
+  lock_.lock();
   if (state_ == State::WRITE_LOCKED) {
     MutexWaiter waiter;
     read_waiters_.push_back(waiter);
-    pthread_spin_unlock(&lock_);
+    lock_.unlock();
     waiter.baton.wait();
     assert(state_ == State::READ_LOCKED);
     return;
@@ -166,18 +166,18 @@ void TimedRWMutex<BatonType>::read_lock() {
   assert(read_waiters_.empty());
   state_ = State::READ_LOCKED;
   readers_ += 1;
-  pthread_spin_unlock(&lock_);
+  lock_.unlock();
 }
 
 template <typename BatonType>
 template <typename Rep, typename Period>
 bool TimedRWMutex<BatonType>::timed_read_lock(
     const std::chrono::duration<Rep, Period>& duration) {
-  pthread_spin_lock(&lock_);
+  lock_.lock();
   if (state_ == State::WRITE_LOCKED) {
     MutexWaiter waiter;
     read_waiters_.push_back(waiter);
-    pthread_spin_unlock(&lock_);
+    lock_.unlock();
 
     if (!waiter.baton.timed_wait(duration)) {
       // We timed out. Two cases:
@@ -185,13 +185,13 @@ bool TimedRWMutex<BatonType>::timed_read_lock(
       // 2. We're not in the waiter list anymore. This could happen if the baton
       //    times out but the mutex is unlocked before we reach this code. In
       //    this case we'll pretend we got the lock on time.
-      pthread_spin_lock(&lock_);
+      lock_.lock();
       if (waiter.hook.is_linked()) {
         read_waiters_.erase(read_waiters_.iterator_to(waiter));
-        pthread_spin_unlock(&lock_);
+        lock_.unlock();
         return false;
       }
-      pthread_spin_unlock(&lock_);
+      lock_.unlock();
     }
     return true;
   }
@@ -201,13 +201,13 @@ bool TimedRWMutex<BatonType>::timed_read_lock(
   assert(read_waiters_.empty());
   state_ = State::READ_LOCKED;
   readers_ += 1;
-  pthread_spin_unlock(&lock_);
+  lock_.unlock();
   return true;
 }
 
 template <typename BatonType>
 bool TimedRWMutex<BatonType>::try_read_lock() {
-  pthread_spin_lock(&lock_);
+  lock_.lock();
   if (state_ != State::WRITE_LOCKED) {
     assert(
         (state_ == State::UNLOCKED && readers_ == 0) ||
@@ -215,25 +215,25 @@ bool TimedRWMutex<BatonType>::try_read_lock() {
     assert(read_waiters_.empty());
     state_ = State::READ_LOCKED;
     readers_ += 1;
-    pthread_spin_unlock(&lock_);
+    lock_.unlock();
     return true;
   }
-  pthread_spin_unlock(&lock_);
+  lock_.unlock();
   return false;
 }
 
 template <typename BatonType>
 void TimedRWMutex<BatonType>::write_lock() {
-  pthread_spin_lock(&lock_);
+  lock_.lock();
   if (state_ == State::UNLOCKED) {
     verify_unlocked_properties();
     state_ = State::WRITE_LOCKED;
-    pthread_spin_unlock(&lock_);
+    lock_.unlock();
     return;
   }
   MutexWaiter waiter;
   write_waiters_.push_back(waiter);
-  pthread_spin_unlock(&lock_);
+  lock_.unlock();
   waiter.baton.wait();
 }
 
@@ -241,16 +241,16 @@ template <typename BatonType>
 template <typename Rep, typename Period>
 bool TimedRWMutex<BatonType>::timed_write_lock(
     const std::chrono::duration<Rep, Period>& duration) {
-  pthread_spin_lock(&lock_);
+  lock_.lock();
   if (state_ == State::UNLOCKED) {
     verify_unlocked_properties();
     state_ = State::WRITE_LOCKED;
-    pthread_spin_unlock(&lock_);
+    lock_.unlock();
     return true;
   }
   MutexWaiter waiter;
   write_waiters_.push_back(waiter);
-  pthread_spin_unlock(&lock_);
+  lock_.unlock();
 
   if (!waiter.baton.timed_wait(duration)) {
     // We timed out. Two cases:
@@ -258,13 +258,13 @@ bool TimedRWMutex<BatonType>::timed_write_lock(
     // 2. We're not in the waiter list anymore. This could happen if the baton
     //    times out but the mutex is unlocked before we reach this code. In
     //    this case we'll pretend we got the lock on time.
-    pthread_spin_lock(&lock_);
+    lock_.lock();
     if (waiter.hook.is_linked()) {
       write_waiters_.erase(write_waiters_.iterator_to(waiter));
-      pthread_spin_unlock(&lock_);
+      lock_.unlock();
       return false;
     }
-    pthread_spin_unlock(&lock_);
+    lock_.unlock();
   }
   assert(state_ == State::WRITE_LOCKED);
   return true;
@@ -272,20 +272,20 @@ bool TimedRWMutex<BatonType>::timed_write_lock(
 
 template <typename BatonType>
 bool TimedRWMutex<BatonType>::try_write_lock() {
-  pthread_spin_lock(&lock_);
+  lock_.lock();
   if (state_ == State::UNLOCKED) {
     verify_unlocked_properties();
     state_ = State::WRITE_LOCKED;
-    pthread_spin_unlock(&lock_);
+    lock_.unlock();
     return true;
   }
-  pthread_spin_unlock(&lock_);
+  lock_.unlock();
   return false;
 }
 
 template <typename BatonType>
 void TimedRWMutex<BatonType>::unlock() {
-  pthread_spin_lock(&lock_);
+  lock_.lock();
   assert(state_ != State::UNLOCKED);
   assert(
       (state_ == State::READ_LOCKED && readers_ > 0) ||
@@ -322,12 +322,12 @@ void TimedRWMutex<BatonType>::unlock() {
   } else {
     assert(state_ == State::READ_LOCKED);
   }
-  pthread_spin_unlock(&lock_);
+  lock_.unlock();
 }
 
 template <typename BatonType>
 void TimedRWMutex<BatonType>::downgrade() {
-  pthread_spin_lock(&lock_);
+  lock_.lock();
   assert(state_ == State::WRITE_LOCKED && readers_ == 0);
   state_ = State::READ_LOCKED;
   readers_ += 1;
@@ -341,7 +341,7 @@ void TimedRWMutex<BatonType>::downgrade() {
       to_wake.baton.post();
     }
   }
-  pthread_spin_unlock(&lock_);
+  lock_.unlock();
 }
 }
 }
index 7c42b8b..671409a 100644 (file)
@@ -15,8 +15,6 @@
  */
 #pragma once
 
-#include <pthread.h>
-
 #include <folly/IntrusiveList.h>
 #include <folly/SpinLock.h>
 #include <folly/fibers/GenericBaton.h>
@@ -93,13 +91,8 @@ class TimedMutex {
 template <typename BatonType>
 class TimedRWMutex {
  public:
-  TimedRWMutex() {
-    pthread_spin_init(&lock_, PTHREAD_PROCESS_PRIVATE);
-  }
-
-  ~TimedRWMutex() {
-    pthread_spin_destroy(&lock_);
-  }
+  TimedRWMutex() = default;
+  ~TimedRWMutex() = default;
 
   TimedRWMutex(const TimedRWMutex& rhs) = delete;
   TimedRWMutex& operator=(const TimedRWMutex& rhs) = delete;
@@ -223,7 +216,7 @@ class TimedRWMutex {
       boost::intrusive::constant_time_size<true>>
       MutexWaiterList;
 
-  pthread_spinlock_t lock_; //< lock protecting the internal state
+  folly::SpinLock lock_; //< lock protecting the internal state
   // (state_, read_waiters_, etc.)
   State state_ = State::UNLOCKED;