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 @@
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.
......
......@@ -16,8 +16,7 @@
#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);
......@@ -1429,33 +1429,16 @@ class SharedMutexImpl {
}
};
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
......@@ -28,6 +28,8 @@
#include <folly/Format.h>
#include <folly/ScopeGuard.h>
DECLARE_ACCESS_SPREADER_TYPE(std::atomic)
namespace folly {
namespace detail {
......@@ -231,11 +233,21 @@ Getcpu::Func Getcpu::resolveVdsoFunc() {
#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
......@@ -161,16 +161,6 @@ struct SequentialThreadId {
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 {
......@@ -287,10 +277,7 @@ struct AccessSpreader {
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*) {
......@@ -339,20 +326,22 @@ struct AccessSpreader {
}
};
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
......@@ -31,6 +31,7 @@ using namespace folly::detail;
template <typename dummy> \
struct tag {}; \
} \
DECLARE_ACCESS_SPREADER_TYPE(tag) \
namespace folly { \
namespace detail { \
template <> \
......
......@@ -413,6 +413,7 @@ TEST(AccessSpreader, Simple) {
template <typename dummy> \
struct tag {}; \
} \
DECLARE_ACCESS_SPREADER_TYPE(tag) \
namespace folly { \
namespace detail { \
template <> \
......
......@@ -15,17 +15,15 @@
*/
#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 {
......@@ -141,7 +139,7 @@ int DeterministicSchedule::getRandNumber(int n) {
if (tls_sched) {
return tls_sched->scheduler_(n);
}
return Random::rand32() % n;
return std::rand() % n;
}
int DeterministicSchedule::getcpu(unsigned* cpu,
......
......@@ -42,6 +42,11 @@ typedef SharedMutexImpl<true, void, DeterministicAtomic, true>
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;
......
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