X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=blobdiff_plain;f=folly%2FSharedMutex.h;h=b6a1a2639a919e546433482be6f0b7dc5ffa00ea;hp=a0f79f5b32ac00e45d0b78a71d8ed9f23a2cb47c;hb=39018ad5c77c53156cb7cd672c05a19fb75a6af7;hpb=ed8c80a0e0988e4ce687f51ca832a00e4a6b7930 diff --git a/folly/SharedMutex.h b/folly/SharedMutex.h index a0f79f5b..b6a1a263 100644 --- a/folly/SharedMutex.h +++ b/folly/SharedMutex.h @@ -19,11 +19,13 @@ #pragma once #include + #include #include #include + #include -#include +#include #include #include #include @@ -234,10 +236,11 @@ struct SharedMutexToken { uint16_t slot_; }; -template class Atom = std::atomic, - bool BlockImmediately = false> +template < + bool ReaderPriority, + typename Tag_ = void, + template class Atom = std::atomic, + bool BlockImmediately = false> class SharedMutexImpl { public: static constexpr bool kReaderPriority = ReaderPriority; @@ -249,7 +252,7 @@ class SharedMutexImpl { class UpgradeHolder; class WriteHolder; - constexpr SharedMutexImpl() : state_(0) {} + constexpr SharedMutexImpl() noexcept : state_(0) {} SharedMutexImpl(const SharedMutexImpl&) = delete; SharedMutexImpl(SharedMutexImpl&&) = delete; @@ -765,7 +768,7 @@ class SharedMutexImpl { } uint32_t after = (state & kMayDefer) == 0 ? 0 : kPrevDefer; - if (!ReaderPriority || (state & (kMayDefer | kHasS)) == 0) { + if (!kReaderPriority || (state & (kMayDefer | kHasS)) == 0) { // Block readers immediately, either because we are in write // priority mode or because we can acquire the lock in one // step. Note that if state has kHasU, then we are doing an @@ -806,7 +809,7 @@ class SharedMutexImpl { return false; } - if (ReaderPriority && (state & kHasE) == 0) { + if (kReaderPriority && (state & kHasE) == 0) { assert((state & kBegunE) != 0); if (!state_.compare_exchange_strong(state, (state & ~kBegunE) | kHasE)) { @@ -847,6 +850,7 @@ class SharedMutexImpl { WaitContext& ctx) { #ifdef RUSAGE_THREAD struct rusage usage; + std::memset(&usage, 0, sizeof(usage)); long before = -1; #endif for (uint32_t yieldCount = 0; yieldCount < kMaxSoftYieldCount; @@ -989,7 +993,7 @@ class SharedMutexImpl { return; } } - asm_pause(); + asm_volatile_pause(); if (UNLIKELY(++spinCount >= kMaxSpinCount)) { applyDeferredReaders(state, ctx, slot); return; @@ -1002,6 +1006,7 @@ class SharedMutexImpl { #ifdef RUSAGE_THREAD struct rusage usage; + std::memset(&usage, 0, sizeof(usage)); long before = -1; #endif for (uint32_t yieldCount = 0; yieldCount < kMaxSoftYieldCount; @@ -1133,10 +1138,15 @@ class SharedMutexImpl { public: class ReadHolder { - public: ReadHolder() : lock_(nullptr) {} - explicit ReadHolder(const SharedMutexImpl* lock) : ReadHolder(*lock) {} + public: + explicit ReadHolder(const SharedMutexImpl* lock) + : lock_(const_cast(lock)) { + if (lock_) { + lock_->lock_shared(token_); + } + } explicit ReadHolder(const SharedMutexImpl& lock) : lock_(const_cast(&lock)) { @@ -1190,10 +1200,14 @@ class SharedMutexImpl { }; class UpgradeHolder { - public: UpgradeHolder() : lock_(nullptr) {} - explicit UpgradeHolder(SharedMutexImpl* lock) : UpgradeHolder(*lock) {} + public: + explicit UpgradeHolder(SharedMutexImpl* lock) : lock_(lock) { + if (lock_) { + lock_->lock_upgrade(); + } + } explicit UpgradeHolder(SharedMutexImpl& lock) : lock_(&lock) { lock_->lock_upgrade(); @@ -1236,10 +1250,14 @@ class SharedMutexImpl { }; class WriteHolder { - public: WriteHolder() : lock_(nullptr) {} - explicit WriteHolder(SharedMutexImpl* lock) : WriteHolder(*lock) {} + public: + explicit WriteHolder(SharedMutexImpl* lock) : lock_(lock) { + if (lock_) { + lock_->lock(); + } + } explicit WriteHolder(SharedMutexImpl& lock) : lock_(&lock) { lock_->lock(); @@ -1404,8 +1422,7 @@ bool SharedMutexImpl:: // starting point for our empty-slot search, can change after // calling waitForZeroBits uint32_t bestSlot = - (uint32_t)folly::detail::AccessSpreader::current( - kMaxDeferredReaders); + (uint32_t)folly::AccessSpreader::current(kMaxDeferredReaders); // deferred readers are already enabled, or it is time to // enable them if we can find a slot