Commit 0f2aacae authored by Jinlong Zhou's avatar Jinlong Zhou Committed by Facebook Github Bot 0

Reverted commit D3270439

Summary:
[temp] (14)/6:
> A function template, member function of a class template, variable template, or static data member of a class template shall be defined in every translation unit in which it is implicitly instantiated (14.7.1) unless the corresponding specialization is explicitly instantiated (14.7.2) in some translation unit; no diagnostic is required.

`-Wundefined-var-template` warns on any implicit instantiations that are needed but could not be performed because the definition is not available. In particular, for valid code, this warns on templates/temploids which have their definition and all relevant explicit instantiations tucked away in some source file (but for which no explicit instantiation declarations are provided in the relevant header file) - used a few times in folly. This seems a bad style, the static data member template should either be defined in the header file or should be explicitly instantiated in each .cpp file.

Reviewed By: igorsugak

Differential Revision: D3270439

fbshipit-source-id: e8cdb0452c2f6240a348b93cdbf9975813f27bfe
parent ddd5d517
...@@ -51,20 +51,12 @@ ...@@ -51,20 +51,12 @@
namespace folly { namespace folly {
namespace detail { namespace detail {
template <int BITS> template <int BITS>
struct FingerprintTable { struct FingerprintTable {
static const uint64_t poly[1 + (BITS - 1) / 64]; static const uint64_t poly[1 + (BITS-1)/64];
static const uint64_t table[8][256][1 + (BITS - 1) / 64]; static const uint64_t table[8][256][1 + (BITS-1)/64];
}; };
} // namespace detail
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
/** /**
* Compute the Rabin fingerprint. * Compute the Rabin fingerprint.
......
...@@ -16,8 +16,7 @@ ...@@ -16,8 +16,7 @@
#include "SharedMutex.h" #include "SharedMutex.h"
namespace folly { COMMON_CONCURRENCY_SHARED_MUTEX_DECLARE_STATIC_STORAGE(
// Explicitly instantiate SharedMutex here: folly::SharedMutexReadPriority);
template class SharedMutexImpl<true>; COMMON_CONCURRENCY_SHARED_MUTEX_DECLARE_STATIC_STORAGE(
template class SharedMutexImpl<false>; folly::SharedMutexWritePriority);
}
...@@ -1429,33 +1429,16 @@ class SharedMutexImpl { ...@@ -1429,33 +1429,16 @@ class SharedMutexImpl {
} }
}; };
template < #define COMMON_CONCURRENCY_SHARED_MUTEX_DECLARE_STATIC_STORAGE(type) \
bool ReaderPriority, template <> \
typename Tag_, type::DeferredReaderSlot \
template <typename> class Atom, type::deferredReaders[type::kMaxDeferredReaders * \
bool BlockImmediately> type::kDeferredSeparationFactor] = {}; \
typename SharedMutexImpl<ReaderPriority, Tag_, Atom, BlockImmediately>:: template <> \
DeferredReaderSlot FOLLY_TLS uint32_t type::tls_lastTokenlessSlot = 0;
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;
typedef SharedMutexImpl<true> SharedMutexReadPriority; typedef SharedMutexImpl<true> SharedMutexReadPriority;
typedef SharedMutexImpl<false> SharedMutexWritePriority; typedef SharedMutexImpl<false> SharedMutexWritePriority;
typedef SharedMutexWritePriority SharedMutex; 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 } // namespace folly
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
#include <folly/Format.h> #include <folly/Format.h>
#include <folly/ScopeGuard.h> #include <folly/ScopeGuard.h>
DECLARE_ACCESS_SPREADER_TYPE(std::atomic)
namespace folly { namespace folly {
namespace detail { namespace detail {
...@@ -231,11 +233,21 @@ Getcpu::Func Getcpu::resolveVdsoFunc() { ...@@ -231,11 +233,21 @@ Getcpu::Func Getcpu::resolveVdsoFunc() {
#ifdef FOLLY_TLS #ifdef FOLLY_TLS
/////////////// SequentialThreadId /////////////// 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 #endif
/////////////// AccessSpreader /////////////// 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 detail
} // namespace folly } // namespace folly
...@@ -161,16 +161,6 @@ struct SequentialThreadId { ...@@ -161,16 +161,6 @@ struct SequentialThreadId {
static FOLLY_TLS size_t currentId; 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 #endif
struct HashingThreadId { struct HashingThreadId {
...@@ -287,10 +277,7 @@ struct AccessSpreader { ...@@ -287,10 +277,7 @@ struct AccessSpreader {
static bool initialized; static bool initialized;
/// Returns the best getcpu implementation for Atom /// Returns the best getcpu implementation for Atom
static Getcpu::Func pickGetcpuFunc() { static Getcpu::Func pickGetcpuFunc();
auto best = Getcpu::resolveVdsoFunc();
return best ? best : &FallbackGetcpuType::getcpu;
}
/// Always claims to be on CPU zero, node zero /// Always claims to be on CPU zero, node zero
static int degenerateGetcpu(unsigned* cpu, unsigned* node, void*) { static int degenerateGetcpu(unsigned* cpu, unsigned* node, void*) {
...@@ -339,20 +326,22 @@ struct AccessSpreader { ...@@ -339,20 +326,22 @@ struct AccessSpreader {
} }
}; };
template <template <typename> class Atom> template <>
Getcpu::Func AccessSpreader<Atom>::getcpuFunc = Getcpu::Func AccessSpreader<std::atomic>::pickGetcpuFunc();
AccessSpreader<Atom>::degenerateGetcpu;
#define DECLARE_ACCESS_SPREADER_TYPE(Atom) \
template <template <typename> class Atom> namespace folly { \
typename AccessSpreader<Atom>::CompactStripe namespace detail { \
AccessSpreader<Atom>::widthAndCpuToStripe[kMaxCpus + 1][kMaxCpus] = {}; template <> \
Getcpu::Func AccessSpreader<Atom>::getcpuFunc = \
template <template <typename> class Atom> AccessSpreader<Atom>::degenerateGetcpu; \
bool AccessSpreader<Atom>::initialized = AccessSpreader<Atom>::initialize(); template <> \
typename AccessSpreader<Atom>::CompactStripe \
// Suppress this instantiation in other translation units. It is AccessSpreader<Atom>::widthAndCpuToStripe[129][128] = {}; \
// instantiated in CacheLocality.cpp template <> \
extern template struct AccessSpreader<std::atomic>; bool AccessSpreader<Atom>::initialized = AccessSpreader<Atom>::initialize(); \
} \
}
} // namespace detail } // namespace detail
} // namespace folly } // namespace folly
...@@ -31,6 +31,7 @@ using namespace folly::detail; ...@@ -31,6 +31,7 @@ using namespace folly::detail;
template <typename dummy> \ template <typename dummy> \
struct tag {}; \ struct tag {}; \
} \ } \
DECLARE_ACCESS_SPREADER_TYPE(tag) \
namespace folly { \ namespace folly { \
namespace detail { \ namespace detail { \
template <> \ template <> \
......
...@@ -413,6 +413,7 @@ TEST(AccessSpreader, Simple) { ...@@ -413,6 +413,7 @@ TEST(AccessSpreader, Simple) {
template <typename dummy> \ template <typename dummy> \
struct tag {}; \ struct tag {}; \
} \ } \
DECLARE_ACCESS_SPREADER_TYPE(tag) \
namespace folly { \ namespace folly { \
namespace detail { \ namespace detail { \
template <> \ template <> \
......
...@@ -15,17 +15,15 @@ ...@@ -15,17 +15,15 @@
*/ */
#include <folly/test/DeterministicSchedule.h> #include <folly/test/DeterministicSchedule.h>
#include <assert.h>
#include <algorithm> #include <algorithm>
#include <list> #include <list>
#include <mutex> #include <mutex>
#include <random> #include <random>
#include <unordered_map>
#include <utility> #include <utility>
#include <unordered_map>
#include <assert.h>
#include <folly/Random.h> DECLARE_ACCESS_SPREADER_TYPE(folly::test::DeterministicAtomic)
namespace folly { namespace folly {
namespace test { namespace test {
...@@ -141,7 +139,7 @@ int DeterministicSchedule::getRandNumber(int n) { ...@@ -141,7 +139,7 @@ int DeterministicSchedule::getRandNumber(int n) {
if (tls_sched) { if (tls_sched) {
return tls_sched->scheduler_(n); return tls_sched->scheduler_(n);
} }
return Random::rand32() % n; return std::rand() % n;
} }
int DeterministicSchedule::getcpu(unsigned* cpu, int DeterministicSchedule::getcpu(unsigned* cpu,
......
...@@ -42,6 +42,11 @@ typedef SharedMutexImpl<true, void, DeterministicAtomic, true> ...@@ -42,6 +42,11 @@ typedef SharedMutexImpl<true, void, DeterministicAtomic, true>
typedef SharedMutexImpl<false, void, DeterministicAtomic, true> typedef SharedMutexImpl<false, void, DeterministicAtomic, true>
DSharedMutexWritePriority; DSharedMutexWritePriority;
COMMON_CONCURRENCY_SHARED_MUTEX_DECLARE_STATIC_STORAGE(
DSharedMutexReadPriority);
COMMON_CONCURRENCY_SHARED_MUTEX_DECLARE_STATIC_STORAGE(
DSharedMutexWritePriority);
template <typename Lock> template <typename Lock>
void runBasicTest() { void runBasicTest() {
Lock lock; Lock lock;
......
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