Commit 3d61464f authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook GitHub Bot

extract some SharedMutex params to a policy

Summary: There are many possible knobs that may be tweaked but long chains of positional params are awkward. Extract a policy param to house many of these chained params. Facilitates adding more params in the future as well.

Reviewed By: ot, luciang

Differential Revision: D28824188

fbshipit-source-id: f56ec15242b148890eced06a3dd101d7cfaaefb1
parent 704df442
...@@ -251,7 +251,21 @@ struct SharedMutexToken { ...@@ -251,7 +251,21 @@ struct SharedMutexToken {
uint16_t slot_; uint16_t slot_;
}; };
struct SharedMutexPolicyDefault {
static constexpr bool block_immediately = false;
static constexpr bool track_thread_id = false;
static constexpr bool skip_annotate_rwlock = false;
};
namespace shared_mutex_detail { namespace shared_mutex_detail {
struct PolicyTracked : SharedMutexPolicyDefault {
static constexpr bool track_thread_id = true;
};
struct PolicySuppressTSAN : SharedMutexPolicyDefault {
static constexpr bool skip_annotate_rwlock = true;
};
// Returns a guard that gives permission for the current thread to // Returns a guard that gives permission for the current thread to
// annotate, and adjust the annotation bits in, the SharedMutex at ptr. // annotate, and adjust the annotation bits in, the SharedMutex at ptr.
std::unique_lock<std::mutex> annotationGuard(void* ptr); std::unique_lock<std::mutex> annotationGuard(void* ptr);
...@@ -316,14 +330,17 @@ template < ...@@ -316,14 +330,17 @@ template <
bool ReaderPriority, bool ReaderPriority,
typename Tag_ = void, typename Tag_ = void,
template <typename> class Atom = std::atomic, template <typename> class Atom = std::atomic,
bool BlockImmediately = false, typename Policy = SharedMutexPolicyDefault>
bool AnnotateForThreadSanitizer = kIsSanitizeThread && !ReaderPriority,
bool TrackThreadId = false>
class SharedMutexImpl : std::conditional_t< class SharedMutexImpl : std::conditional_t<
TrackThreadId, Policy::track_thread_id,
shared_mutex_detail::ThreadIdOwnershipTracker, shared_mutex_detail::ThreadIdOwnershipTracker,
shared_mutex_detail::NopOwnershipTracker> { shared_mutex_detail::NopOwnershipTracker> {
private: private:
static constexpr bool BlockImmediately = Policy::block_immediately;
static constexpr bool AnnotateForThreadSanitizer =
kIsSanitizeThread && !ReaderPriority && !Policy::skip_annotate_rwlock;
static constexpr bool TrackThreadId = Policy::track_thread_id;
typedef std::conditional_t< typedef std::conditional_t<
TrackThreadId, TrackThreadId,
shared_mutex_detail::ThreadIdOwnershipTracker, shared_mutex_detail::ThreadIdOwnershipTracker,
...@@ -1575,13 +1592,19 @@ class SharedMutexImpl : std::conditional_t< ...@@ -1575,13 +1592,19 @@ class SharedMutexImpl : std::conditional_t<
} }
}; };
typedef SharedMutexImpl<true> SharedMutexReadPriority; using SharedMutexReadPriority = SharedMutexImpl<true>;
typedef SharedMutexImpl<false> SharedMutexWritePriority; using SharedMutexWritePriority = SharedMutexImpl<false>;
typedef SharedMutexWritePriority SharedMutex; using SharedMutex = SharedMutexWritePriority;
typedef SharedMutexImpl<false, void, std::atomic, false, false, true> using SharedMutexTracked = SharedMutexImpl<
SharedMutexTracked; false,
typedef SharedMutexImpl<false, void, std::atomic, false, false> void,
SharedMutexSuppressTSAN; std::atomic,
shared_mutex_detail::PolicyTracked>;
using SharedMutexSuppressTSAN = SharedMutexImpl<
false,
void,
std::atomic,
shared_mutex_detail::PolicySuppressTSAN>;
// Prevent the compiler from instantiating these in other translation units. // Prevent the compiler from instantiating these in other translation units.
// They are instantiated once in SharedMutex.cpp // They are instantiated once in SharedMutex.cpp
...@@ -1593,23 +1616,11 @@ template < ...@@ -1593,23 +1616,11 @@ template <
typename Tag_, typename Tag_,
template <typename> template <typename>
class Atom, class Atom,
bool BlockImmediately, typename Policy>
bool AnnotateForThreadSanitizer, alignas(hardware_destructive_interference_size)
bool TrackThreadId> typename SharedMutexImpl<ReaderPriority, Tag_, Atom, Policy>::
alignas(hardware_destructive_interference_size) typename SharedMutexImpl< DeferredReaderSlot
ReaderPriority, SharedMutexImpl<ReaderPriority, Tag_, Atom, Policy>::deferredReaders
Tag_,
Atom,
BlockImmediately,
AnnotateForThreadSanitizer,
TrackThreadId>::DeferredReaderSlot
SharedMutexImpl<
ReaderPriority,
Tag_,
Atom,
BlockImmediately,
AnnotateForThreadSanitizer,
TrackThreadId>::deferredReaders
[shared_mutex_detail::kMaxDeferredReadersAllocated * [shared_mutex_detail::kMaxDeferredReadersAllocated *
kDeferredSeparationFactor] = {}; kDeferredSeparationFactor] = {};
...@@ -1618,16 +1629,9 @@ template < ...@@ -1618,16 +1629,9 @@ template <
typename Tag_, typename Tag_,
template <typename> template <typename>
class Atom, class Atom,
bool BlockImmediately, typename Policy>
bool AnnotateForThreadSanitizer, bool SharedMutexImpl<ReaderPriority, Tag_, Atom, Policy>::
bool TrackThreadId> tryUnlockTokenlessSharedDeferred() {
bool SharedMutexImpl<
ReaderPriority,
Tag_,
Atom,
BlockImmediately,
AnnotateForThreadSanitizer,
TrackThreadId>::tryUnlockTokenlessSharedDeferred() {
auto bestSlot = tls_lastTokenlessSlot().load(std::memory_order_relaxed); auto bestSlot = tls_lastTokenlessSlot().load(std::memory_order_relaxed);
// use do ... while to avoid calling // use do ... while to avoid calling
// shared_mutex_detail::getMaxDeferredReaders() unless necessary // shared_mutex_detail::getMaxDeferredReaders() unless necessary
...@@ -1650,18 +1654,10 @@ template < ...@@ -1650,18 +1654,10 @@ template <
typename Tag_, typename Tag_,
template <typename> template <typename>
class Atom, class Atom,
bool BlockImmediately, typename Policy>
bool AnnotateForThreadSanitizer,
bool TrackThreadId>
template <class WaitContext> template <class WaitContext>
bool SharedMutexImpl< bool SharedMutexImpl<ReaderPriority, Tag_, Atom, Policy>::lockSharedImpl(
ReaderPriority, uint32_t& state, Token* token, WaitContext& ctx) {
Tag_,
Atom,
BlockImmediately,
AnnotateForThreadSanitizer,
TrackThreadId>::
lockSharedImpl(uint32_t& state, Token* token, WaitContext& ctx) {
const uint32_t maxDeferredReaders = const uint32_t maxDeferredReaders =
shared_mutex_detail::getMaxDeferredReaders(); shared_mutex_detail::getMaxDeferredReaders();
while (true) { while (true) {
......
...@@ -38,11 +38,14 @@ using namespace folly::test; ...@@ -38,11 +38,14 @@ using namespace folly::test;
using namespace std; using namespace std;
using namespace std::chrono; using namespace std::chrono;
typedef DeterministicSchedule DSched; struct DSharedMutexPolicy : SharedMutexPolicyDefault {
typedef SharedMutexImpl<true, void, DeterministicAtomic, true> static constexpr bool block_immediately = true;
DSharedMutexReadPriority; };
typedef SharedMutexImpl<false, void, DeterministicAtomic, true> using DSched = DeterministicSchedule;
DSharedMutexWritePriority; using DSharedMutexReadPriority =
SharedMutexImpl<true, void, DeterministicAtomic, DSharedMutexPolicy>;
using DSharedMutexWritePriority =
SharedMutexImpl<false, void, DeterministicAtomic, DSharedMutexPolicy>;
template <typename Lock> template <typename Lock>
void runBasicTest() { void runBasicTest() {
......
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