Commit 0d13183a authored by Alastair Daivis's avatar Alastair Daivis Committed by Facebook Github Bot

Statically allocate futex array

Summary:
AFAICT this is currently the only thing preventing the non-dynamic version of Folly's MPMCQueue from being allocation-free on enqueue and dequeue operations. Allocating this with a constant expression should move the allocation from runtime to link (possibly compile?) time, which will let us use it in allocation sensitive contexts.

Feel free to suggest other reviewers, I couldn't find an existing folly reviewer group.

Reviewed By: yfeldblum, agola11, nbronson

Differential Revision: D6447848

fbshipit-source-id: 86b84b19d62f1e1bcecdb9e757a6dfa90597b084
parent 4bec077b
...@@ -399,6 +399,12 @@ constexpr auto kIsObjC = true; ...@@ -399,6 +399,12 @@ constexpr auto kIsObjC = true;
constexpr auto kIsObjC = false; constexpr auto kIsObjC = false;
#endif #endif
#if FOLLY_MOBILE
constexpr auto kIsMobile = true;
#else
constexpr auto kIsMobile = false;
#endif
#if defined(__linux__) && !FOLLY_MOBILE #if defined(__linux__) && !FOLLY_MOBILE
constexpr auto kIsLinux = true; constexpr auto kIsLinux = true;
#else #else
......
...@@ -16,11 +16,13 @@ ...@@ -16,11 +16,13 @@
#include <folly/detail/Futex.h> #include <folly/detail/Futex.h>
#include <boost/intrusive/list.hpp> #include <boost/intrusive/list.hpp>
#include <folly/Indestructible.h>
#include <folly/ScopeGuard.h> #include <folly/ScopeGuard.h>
#include <folly/hash/Hash.h> #include <folly/hash/Hash.h>
#include <folly/portability/SysSyscall.h> #include <folly/portability/SysSyscall.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <array>
#include <cerrno> #include <cerrno>
#include <condition_variable> #include <condition_variable>
#include <mutex> #include <mutex>
...@@ -186,13 +188,17 @@ struct EmulatedFutexBucket { ...@@ -186,13 +188,17 @@ struct EmulatedFutexBucket {
std::mutex mutex_; std::mutex mutex_;
boost::intrusive::list<EmulatedFutexWaitNode> waiters_; boost::intrusive::list<EmulatedFutexWaitNode> waiters_;
static const size_t kNumBuckets = 4096; static constexpr size_t const kNumBuckets = kIsMobile ? 256 : 4096;
static EmulatedFutexBucket& bucketFor(void* addr) { static EmulatedFutexBucket& bucketFor(void* addr) {
static auto gBuckets = new EmulatedFutexBucket[kNumBuckets]; // Statically allocating this lets us use this in allocation-sensitive
uint64_t mixedBits = folly::hash::twang_mix64( // contexts. This relies on the assumption that std::mutex won't dynamically
reinterpret_cast<uintptr_t>(addr)); // allocate memory, which we assume to be the case on Linux and iOS.
return gBuckets[mixedBits % kNumBuckets]; static Indestructible<std::array<EmulatedFutexBucket, kNumBuckets>>
gBuckets;
uint64_t mixedBits =
folly::hash::twang_mix64(reinterpret_cast<uintptr_t>(addr));
return (*gBuckets)[mixedBits % kNumBuckets];
} }
}; };
......
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