Skip to content

Commit

Permalink
Statically allocate futex array
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Alastair Daivis authored and facebook-github-bot committed Dec 3, 2017
1 parent 4bec077 commit 0d13183
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 5 deletions.
6 changes: 6 additions & 0 deletions folly/Portability.h
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,12 @@ constexpr auto kIsObjC = true;
constexpr auto kIsObjC = false;
#endif

#if FOLLY_MOBILE
constexpr auto kIsMobile = true;
#else
constexpr auto kIsMobile = false;
#endif

#if defined(__linux__) && !FOLLY_MOBILE
constexpr auto kIsLinux = true;
#else
Expand Down
16 changes: 11 additions & 5 deletions folly/detail/Futex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@

#include <folly/detail/Futex.h>
#include <boost/intrusive/list.hpp>
#include <folly/Indestructible.h>
#include <folly/ScopeGuard.h>
#include <folly/hash/Hash.h>
#include <folly/portability/SysSyscall.h>
#include <stdint.h>
#include <string.h>
#include <array>
#include <cerrno>
#include <condition_variable>
#include <mutex>
Expand Down Expand Up @@ -186,13 +188,17 @@ struct EmulatedFutexBucket {
std::mutex mutex_;
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 auto gBuckets = new EmulatedFutexBucket[kNumBuckets];
uint64_t mixedBits = folly::hash::twang_mix64(
reinterpret_cast<uintptr_t>(addr));
return gBuckets[mixedBits % kNumBuckets];
// Statically allocating this lets us use this in allocation-sensitive
// contexts. This relies on the assumption that std::mutex won't dynamically
// allocate memory, which we assume to be the case on Linux and iOS.
static Indestructible<std::array<EmulatedFutexBucket, kNumBuckets>>
gBuckets;
uint64_t mixedBits =
folly::hash::twang_mix64(reinterpret_cast<uintptr_t>(addr));
return (*gBuckets)[mixedBits % kNumBuckets];
}
};

Expand Down

0 comments on commit 0d13183

Please sign in to comment.