Commit dbf7c3d2 authored by Francis Ma's avatar Francis Ma Committed by facebook-github-bot-0

Make folly::detail::CacheLocality portable on apple

Summary:
This is one of the series steps to port folly::future on ios. Apple doesn't support __thread. Adding a HashingThreadId as a fallback
on apple.

Reviewed By: nbronson

Differential Revision: D2832068

fb-gh-sync-id: c3389245f3c0bbd36de6260680f7ac6110b3206c
parent 94174b55
......@@ -223,7 +223,9 @@ namespace std { typedef ::max_align_t max_align_t; }
* the semantics are the same
* (but remember __thread has different semantics when using emutls (ex. apple))
*/
#if defined(_MSC_VER)
#if defined(__APPLE__)
#undef FOLLY_TLS
#elif defined(_MSC_VER)
# define FOLLY_TLS __declspec(thread)
#elif defined(__GNUC__) || defined(__clang__)
# define FOLLY_TLS __thread
......
......@@ -232,6 +232,7 @@ Getcpu::Func Getcpu::vdsoFunc() {
return func;
}
#ifdef FOLLY_TLS
/////////////// SequentialThreadId
template<>
......@@ -239,6 +240,7 @@ std::atomic<size_t> SequentialThreadId<std::atomic>::prevId(0);
template<>
FOLLY_TLS size_t SequentialThreadId<std::atomic>::currentId(0);
#endif
/////////////// AccessSpreader
......@@ -277,7 +279,7 @@ Getcpu::Func AccessSpreader<std::atomic>::pickGetcpuFunc(size_t numStripes) {
return &degenerateGetcpu;
} else {
auto best = Getcpu::vdsoFunc();
return best ? best : &SequentialThreadId<std::atomic>::getcpu;
return best ? best : &FallbackGetcpuType::getcpu;
}
}
......
......@@ -26,6 +26,7 @@
#include <string>
#include <type_traits>
#include <vector>
#include <folly/Hash.h>
#include <folly/Likely.h>
#include <folly/Portability.h>
......@@ -141,10 +142,7 @@ struct Getcpu {
static Func vdsoFunc();
};
/// A class that lazily binds a unique (for each implementation of Atom)
/// identifier to a thread. This is a fallback mechanism for the access
/// spreader if we are in testing (using DeterministicAtomic) or if
/// __vdso_getcpu can't be dynamically loaded
#ifdef FOLLY_TLS
template <template<typename> class Atom>
struct SequentialThreadId {
......@@ -157,11 +155,32 @@ struct SequentialThreadId {
return rv;
}
private:
static Atom<size_t> prevId;
static FOLLY_TLS size_t currentId;
};
#endif
struct HashingThreadId {
static size_t get() {
pthread_t pid = pthread_self();
uint64_t id = 0;
memcpy(&id, &pid, std::min(sizeof(pid), sizeof(id)));
return hash::twang_32from64(id);
}
};
/// A class that lazily binds a unique (for each implementation of Atom)
/// identifier to a thread. This is a fallback mechanism for the access
/// spreader if __vdso_getcpu can't be loaded
template <typename ThreadId>
struct FallbackGetcpu {
/// Fills the thread id into the cpu and node out params (if they
/// are non-null). This method is intended to act like getcpu when a
/// fast-enough form of getcpu isn't available or isn't desired
static int getcpu(unsigned* cpu, unsigned* node, void* unused) {
auto id = get();
auto id = ThreadId::get();
if (cpu) {
*cpu = id;
}
......@@ -170,13 +189,14 @@ struct SequentialThreadId {
}
return 0;
}
private:
static Atom<size_t> prevId;
static FOLLY_TLS size_t currentId;
};
#ifdef FOLLY_TLS
typedef FallbackGetcpu<SequentialThreadId<std::atomic>> FallbackGetcpuType;
#else
typedef FallbackGetcpu<HashingThreadId> FallbackGetcpuType;
#endif
template <template<typename> class Atom, size_t kMaxCpus>
struct AccessSpreaderArray;
......
This diff is collapsed.
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