Commit 214b26f3 authored by Christopher Dykes's avatar Christopher Dykes Committed by Facebook Github Bot

Don't use pthread_spinlock_t in TimedRWMutex

Summary: `TimedMutex` was already using `folly::SpinLock`, so switch `TimedRWMutex` to do the same.

Reviewed By: andriigrynenko

Differential Revision: D4888005

fbshipit-source-id: 6e782347bc22dc186ed41f2e77c6614b8444bae2
parent 62134365
...@@ -151,11 +151,11 @@ inline void TimedMutex::unlock() { ...@@ -151,11 +151,11 @@ inline void TimedMutex::unlock() {
template <typename BatonType> template <typename BatonType>
void TimedRWMutex<BatonType>::read_lock() { void TimedRWMutex<BatonType>::read_lock() {
pthread_spin_lock(&lock_); lock_.lock();
if (state_ == State::WRITE_LOCKED) { if (state_ == State::WRITE_LOCKED) {
MutexWaiter waiter; MutexWaiter waiter;
read_waiters_.push_back(waiter); read_waiters_.push_back(waiter);
pthread_spin_unlock(&lock_); lock_.unlock();
waiter.baton.wait(); waiter.baton.wait();
assert(state_ == State::READ_LOCKED); assert(state_ == State::READ_LOCKED);
return; return;
...@@ -166,18 +166,18 @@ void TimedRWMutex<BatonType>::read_lock() { ...@@ -166,18 +166,18 @@ void TimedRWMutex<BatonType>::read_lock() {
assert(read_waiters_.empty()); assert(read_waiters_.empty());
state_ = State::READ_LOCKED; state_ = State::READ_LOCKED;
readers_ += 1; readers_ += 1;
pthread_spin_unlock(&lock_); lock_.unlock();
} }
template <typename BatonType> template <typename BatonType>
template <typename Rep, typename Period> template <typename Rep, typename Period>
bool TimedRWMutex<BatonType>::timed_read_lock( bool TimedRWMutex<BatonType>::timed_read_lock(
const std::chrono::duration<Rep, Period>& duration) { const std::chrono::duration<Rep, Period>& duration) {
pthread_spin_lock(&lock_); lock_.lock();
if (state_ == State::WRITE_LOCKED) { if (state_ == State::WRITE_LOCKED) {
MutexWaiter waiter; MutexWaiter waiter;
read_waiters_.push_back(waiter); read_waiters_.push_back(waiter);
pthread_spin_unlock(&lock_); lock_.unlock();
if (!waiter.baton.timed_wait(duration)) { if (!waiter.baton.timed_wait(duration)) {
// We timed out. Two cases: // We timed out. Two cases:
...@@ -185,13 +185,13 @@ bool TimedRWMutex<BatonType>::timed_read_lock( ...@@ -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 // 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 // times out but the mutex is unlocked before we reach this code. In
// this case we'll pretend we got the lock on time. // this case we'll pretend we got the lock on time.
pthread_spin_lock(&lock_); lock_.lock();
if (waiter.hook.is_linked()) { if (waiter.hook.is_linked()) {
read_waiters_.erase(read_waiters_.iterator_to(waiter)); read_waiters_.erase(read_waiters_.iterator_to(waiter));
pthread_spin_unlock(&lock_); lock_.unlock();
return false; return false;
} }
pthread_spin_unlock(&lock_); lock_.unlock();
} }
return true; return true;
} }
...@@ -201,13 +201,13 @@ bool TimedRWMutex<BatonType>::timed_read_lock( ...@@ -201,13 +201,13 @@ bool TimedRWMutex<BatonType>::timed_read_lock(
assert(read_waiters_.empty()); assert(read_waiters_.empty());
state_ = State::READ_LOCKED; state_ = State::READ_LOCKED;
readers_ += 1; readers_ += 1;
pthread_spin_unlock(&lock_); lock_.unlock();
return true; return true;
} }
template <typename BatonType> template <typename BatonType>
bool TimedRWMutex<BatonType>::try_read_lock() { bool TimedRWMutex<BatonType>::try_read_lock() {
pthread_spin_lock(&lock_); lock_.lock();
if (state_ != State::WRITE_LOCKED) { if (state_ != State::WRITE_LOCKED) {
assert( assert(
(state_ == State::UNLOCKED && readers_ == 0) || (state_ == State::UNLOCKED && readers_ == 0) ||
...@@ -215,25 +215,25 @@ bool TimedRWMutex<BatonType>::try_read_lock() { ...@@ -215,25 +215,25 @@ bool TimedRWMutex<BatonType>::try_read_lock() {
assert(read_waiters_.empty()); assert(read_waiters_.empty());
state_ = State::READ_LOCKED; state_ = State::READ_LOCKED;
readers_ += 1; readers_ += 1;
pthread_spin_unlock(&lock_); lock_.unlock();
return true; return true;
} }
pthread_spin_unlock(&lock_); lock_.unlock();
return false; return false;
} }
template <typename BatonType> template <typename BatonType>
void TimedRWMutex<BatonType>::write_lock() { void TimedRWMutex<BatonType>::write_lock() {
pthread_spin_lock(&lock_); lock_.lock();
if (state_ == State::UNLOCKED) { if (state_ == State::UNLOCKED) {
verify_unlocked_properties(); verify_unlocked_properties();
state_ = State::WRITE_LOCKED; state_ = State::WRITE_LOCKED;
pthread_spin_unlock(&lock_); lock_.unlock();
return; return;
} }
MutexWaiter waiter; MutexWaiter waiter;
write_waiters_.push_back(waiter); write_waiters_.push_back(waiter);
pthread_spin_unlock(&lock_); lock_.unlock();
waiter.baton.wait(); waiter.baton.wait();
} }
...@@ -241,16 +241,16 @@ template <typename BatonType> ...@@ -241,16 +241,16 @@ template <typename BatonType>
template <typename Rep, typename Period> template <typename Rep, typename Period>
bool TimedRWMutex<BatonType>::timed_write_lock( bool TimedRWMutex<BatonType>::timed_write_lock(
const std::chrono::duration<Rep, Period>& duration) { const std::chrono::duration<Rep, Period>& duration) {
pthread_spin_lock(&lock_); lock_.lock();
if (state_ == State::UNLOCKED) { if (state_ == State::UNLOCKED) {
verify_unlocked_properties(); verify_unlocked_properties();
state_ = State::WRITE_LOCKED; state_ = State::WRITE_LOCKED;
pthread_spin_unlock(&lock_); lock_.unlock();
return true; return true;
} }
MutexWaiter waiter; MutexWaiter waiter;
write_waiters_.push_back(waiter); write_waiters_.push_back(waiter);
pthread_spin_unlock(&lock_); lock_.unlock();
if (!waiter.baton.timed_wait(duration)) { if (!waiter.baton.timed_wait(duration)) {
// We timed out. Two cases: // We timed out. Two cases:
...@@ -258,13 +258,13 @@ bool TimedRWMutex<BatonType>::timed_write_lock( ...@@ -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 // 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 // times out but the mutex is unlocked before we reach this code. In
// this case we'll pretend we got the lock on time. // this case we'll pretend we got the lock on time.
pthread_spin_lock(&lock_); lock_.lock();
if (waiter.hook.is_linked()) { if (waiter.hook.is_linked()) {
write_waiters_.erase(write_waiters_.iterator_to(waiter)); write_waiters_.erase(write_waiters_.iterator_to(waiter));
pthread_spin_unlock(&lock_); lock_.unlock();
return false; return false;
} }
pthread_spin_unlock(&lock_); lock_.unlock();
} }
assert(state_ == State::WRITE_LOCKED); assert(state_ == State::WRITE_LOCKED);
return true; return true;
...@@ -272,20 +272,20 @@ bool TimedRWMutex<BatonType>::timed_write_lock( ...@@ -272,20 +272,20 @@ bool TimedRWMutex<BatonType>::timed_write_lock(
template <typename BatonType> template <typename BatonType>
bool TimedRWMutex<BatonType>::try_write_lock() { bool TimedRWMutex<BatonType>::try_write_lock() {
pthread_spin_lock(&lock_); lock_.lock();
if (state_ == State::UNLOCKED) { if (state_ == State::UNLOCKED) {
verify_unlocked_properties(); verify_unlocked_properties();
state_ = State::WRITE_LOCKED; state_ = State::WRITE_LOCKED;
pthread_spin_unlock(&lock_); lock_.unlock();
return true; return true;
} }
pthread_spin_unlock(&lock_); lock_.unlock();
return false; return false;
} }
template <typename BatonType> template <typename BatonType>
void TimedRWMutex<BatonType>::unlock() { void TimedRWMutex<BatonType>::unlock() {
pthread_spin_lock(&lock_); lock_.lock();
assert(state_ != State::UNLOCKED); assert(state_ != State::UNLOCKED);
assert( assert(
(state_ == State::READ_LOCKED && readers_ > 0) || (state_ == State::READ_LOCKED && readers_ > 0) ||
...@@ -322,12 +322,12 @@ void TimedRWMutex<BatonType>::unlock() { ...@@ -322,12 +322,12 @@ void TimedRWMutex<BatonType>::unlock() {
} else { } else {
assert(state_ == State::READ_LOCKED); assert(state_ == State::READ_LOCKED);
} }
pthread_spin_unlock(&lock_); lock_.unlock();
} }
template <typename BatonType> template <typename BatonType>
void TimedRWMutex<BatonType>::downgrade() { void TimedRWMutex<BatonType>::downgrade() {
pthread_spin_lock(&lock_); lock_.lock();
assert(state_ == State::WRITE_LOCKED && readers_ == 0); assert(state_ == State::WRITE_LOCKED && readers_ == 0);
state_ = State::READ_LOCKED; state_ = State::READ_LOCKED;
readers_ += 1; readers_ += 1;
...@@ -341,7 +341,7 @@ void TimedRWMutex<BatonType>::downgrade() { ...@@ -341,7 +341,7 @@ void TimedRWMutex<BatonType>::downgrade() {
to_wake.baton.post(); to_wake.baton.post();
} }
} }
pthread_spin_unlock(&lock_); lock_.unlock();
} }
} }
} }
...@@ -15,8 +15,6 @@ ...@@ -15,8 +15,6 @@
*/ */
#pragma once #pragma once
#include <pthread.h>
#include <folly/IntrusiveList.h> #include <folly/IntrusiveList.h>
#include <folly/SpinLock.h> #include <folly/SpinLock.h>
#include <folly/fibers/GenericBaton.h> #include <folly/fibers/GenericBaton.h>
...@@ -93,13 +91,8 @@ class TimedMutex { ...@@ -93,13 +91,8 @@ class TimedMutex {
template <typename BatonType> template <typename BatonType>
class TimedRWMutex { class TimedRWMutex {
public: public:
TimedRWMutex() { TimedRWMutex() = default;
pthread_spin_init(&lock_, PTHREAD_PROCESS_PRIVATE); ~TimedRWMutex() = default;
}
~TimedRWMutex() {
pthread_spin_destroy(&lock_);
}
TimedRWMutex(const TimedRWMutex& rhs) = delete; TimedRWMutex(const TimedRWMutex& rhs) = delete;
TimedRWMutex& operator=(const TimedRWMutex& rhs) = delete; TimedRWMutex& operator=(const TimedRWMutex& rhs) = delete;
...@@ -223,7 +216,7 @@ class TimedRWMutex { ...@@ -223,7 +216,7 @@ class TimedRWMutex {
boost::intrusive::constant_time_size<true>> boost::intrusive::constant_time_size<true>>
MutexWaiterList; MutexWaiterList;
pthread_spinlock_t lock_; //< lock protecting the internal state folly::SpinLock lock_; //< lock protecting the internal state
// (state_, read_waiters_, etc.) // (state_, read_waiters_, etc.)
State state_ = State::UNLOCKED; State state_ = State::UNLOCKED;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment