namespace folly {
namespace detail {
-
template <int BITS>
struct FingerprintTable {
- static const uint64_t poly[1 + (BITS - 1) / 64];
- static const uint64_t table[8][256][1 + (BITS - 1) / 64];
+ static const uint64_t poly[1 + (BITS-1)/64];
+ static const uint64_t table[8][256][1 + (BITS-1)/64];
};
-
-template <int BITS>
-const uint64_t FingerprintTable<BITS>::poly[1 + (BITS - 1) / 64] = {};
-
-template <int BITS>
-const uint64_t FingerprintTable<BITS>::table[8][256][1 + (BITS - 1) / 64] = {};
-
-} // namespace detail
+} // namespace detail
/**
* Compute the Rabin fingerprint.
#include "SharedMutex.h"
-namespace folly {
-// Explicitly instantiate SharedMutex here:
-template class SharedMutexImpl<true>;
-template class SharedMutexImpl<false>;
-}
+COMMON_CONCURRENCY_SHARED_MUTEX_DECLARE_STATIC_STORAGE(
+ folly::SharedMutexReadPriority);
+COMMON_CONCURRENCY_SHARED_MUTEX_DECLARE_STATIC_STORAGE(
+ folly::SharedMutexWritePriority);
}
};
-template <
- bool ReaderPriority,
- typename Tag_,
- template <typename> class Atom,
- bool BlockImmediately>
-typename SharedMutexImpl<ReaderPriority, Tag_, Atom, BlockImmediately>::
- DeferredReaderSlot
- SharedMutexImpl<ReaderPriority, Tag_, Atom, BlockImmediately>::
- deferredReaders[kMaxDeferredReaders * kDeferredSeparationFactor] =
- {};
-
-template <
- bool ReaderPriority,
- typename Tag_,
- template <typename> class Atom,
- bool BlockImmediately>
-FOLLY_TLS uint32_t
- SharedMutexImpl<ReaderPriority, Tag_, Atom, BlockImmediately>::
- tls_lastTokenlessSlot = 0;
+#define COMMON_CONCURRENCY_SHARED_MUTEX_DECLARE_STATIC_STORAGE(type) \
+ template <> \
+ type::DeferredReaderSlot \
+ type::deferredReaders[type::kMaxDeferredReaders * \
+ type::kDeferredSeparationFactor] = {}; \
+ template <> \
+ FOLLY_TLS uint32_t type::tls_lastTokenlessSlot = 0;
typedef SharedMutexImpl<true> SharedMutexReadPriority;
typedef SharedMutexImpl<false> SharedMutexWritePriority;
typedef SharedMutexWritePriority SharedMutex;
-// Prevent the compiler from instantiating these in other translation units.
-// They are instantiated once in SharedMutex.cpp
-extern template class SharedMutexImpl<true>;
-extern template class SharedMutexImpl<false>;
-
} // namespace folly
#include <folly/Format.h>
#include <folly/ScopeGuard.h>
+DECLARE_ACCESS_SPREADER_TYPE(std::atomic)
+
namespace folly {
namespace detail {
#ifdef FOLLY_TLS
/////////////// SequentialThreadId
-template struct SequentialThreadId<std::atomic>;
+
+template <>
+std::atomic<size_t> SequentialThreadId<std::atomic>::prevId(0);
+
+template <>
+FOLLY_TLS size_t SequentialThreadId<std::atomic>::currentId(0);
#endif
/////////////// AccessSpreader
-template struct AccessSpreader<std::atomic>;
+
+template <>
+Getcpu::Func AccessSpreader<std::atomic>::pickGetcpuFunc() {
+ auto best = Getcpu::resolveVdsoFunc();
+ return best ? best : &FallbackGetcpuType::getcpu;
+}
} // namespace detail
} // namespace folly
static FOLLY_TLS size_t currentId;
};
-
-template <template <typename> class Atom>
-Atom<size_t> SequentialThreadId<Atom>::prevId(0);
-
-template <template <typename> class Atom>
-FOLLY_TLS size_t SequentialThreadId<Atom>::currentId(0);
-
-// Suppress this instantiation in other translation units. It is
-// instantiated in CacheLocality.cpp
-extern template struct SequentialThreadId<std::atomic>;
#endif
struct HashingThreadId {
static bool initialized;
/// Returns the best getcpu implementation for Atom
- static Getcpu::Func pickGetcpuFunc() {
- auto best = Getcpu::resolveVdsoFunc();
- return best ? best : &FallbackGetcpuType::getcpu;
- }
+ static Getcpu::Func pickGetcpuFunc();
/// Always claims to be on CPU zero, node zero
static int degenerateGetcpu(unsigned* cpu, unsigned* node, void*) {
}
};
-template <template <typename> class Atom>
-Getcpu::Func AccessSpreader<Atom>::getcpuFunc =
- AccessSpreader<Atom>::degenerateGetcpu;
-
-template <template <typename> class Atom>
-typename AccessSpreader<Atom>::CompactStripe
- AccessSpreader<Atom>::widthAndCpuToStripe[kMaxCpus + 1][kMaxCpus] = {};
-
-template <template <typename> class Atom>
-bool AccessSpreader<Atom>::initialized = AccessSpreader<Atom>::initialize();
-
-// Suppress this instantiation in other translation units. It is
-// instantiated in CacheLocality.cpp
-extern template struct AccessSpreader<std::atomic>;
+template <>
+Getcpu::Func AccessSpreader<std::atomic>::pickGetcpuFunc();
+
+#define DECLARE_ACCESS_SPREADER_TYPE(Atom) \
+ namespace folly { \
+ namespace detail { \
+ template <> \
+ Getcpu::Func AccessSpreader<Atom>::getcpuFunc = \
+ AccessSpreader<Atom>::degenerateGetcpu; \
+ template <> \
+ typename AccessSpreader<Atom>::CompactStripe \
+ AccessSpreader<Atom>::widthAndCpuToStripe[129][128] = {}; \
+ template <> \
+ bool AccessSpreader<Atom>::initialized = AccessSpreader<Atom>::initialize(); \
+ } \
+ }
} // namespace detail
} // namespace folly
template <typename dummy> \
struct tag {}; \
} \
+ DECLARE_ACCESS_SPREADER_TYPE(tag) \
namespace folly { \
namespace detail { \
template <> \
template <typename dummy> \
struct tag {}; \
} \
+ DECLARE_ACCESS_SPREADER_TYPE(tag) \
namespace folly { \
namespace detail { \
template <> \
*/
#include <folly/test/DeterministicSchedule.h>
-
-#include <assert.h>
-
#include <algorithm>
#include <list>
#include <mutex>
#include <random>
-#include <unordered_map>
#include <utility>
+#include <unordered_map>
+#include <assert.h>
-#include <folly/Random.h>
+DECLARE_ACCESS_SPREADER_TYPE(folly::test::DeterministicAtomic)
namespace folly {
namespace test {
if (tls_sched) {
return tls_sched->scheduler_(n);
}
- return Random::rand32() % n;
+ return std::rand() % n;
}
int DeterministicSchedule::getcpu(unsigned* cpu,
typedef SharedMutexImpl<false, void, DeterministicAtomic, true>
DSharedMutexWritePriority;
+COMMON_CONCURRENCY_SHARED_MUTEX_DECLARE_STATIC_STORAGE(
+ DSharedMutexReadPriority);
+COMMON_CONCURRENCY_SHARED_MUTEX_DECLARE_STATIC_STORAGE(
+ DSharedMutexWritePriority);
+
template <typename Lock>
void runBasicTest() {
Lock lock;