*/
#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>
-#include <boost/intrusive/list.hpp>
-#include <folly/CallOnce.h>
-#include <folly/Hash.h>
-#include <folly/ScopeGuard.h>
#ifdef __linux__
-# include <errno.h>
-# include <linux/futex.h>
-# include <sys/syscall.h>
+#include <linux/futex.h>
#endif
using namespace std::chrono;
-namespace folly { namespace detail {
+namespace folly {
+namespace detail {
namespace {
std::mutex mutex_;
boost::intrusive::list<EmulatedFutexWaitNode> waiters_;
- static const size_t kNumBuckets = 4096;
- static EmulatedFutexBucket* gBuckets;
- static folly::once_flag gBucketInit;
+ static constexpr size_t const kNumBuckets = kIsMobile ? 256 : 4096;
static EmulatedFutexBucket& bucketFor(void* addr) {
- folly::call_once(gBucketInit, [](){
- 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];
}
};
-EmulatedFutexBucket* EmulatedFutexBucket::gBuckets;
-folly::once_flag EmulatedFutexBucket::gBucketInit;
-
int emulatedFutexWake(void* addr, int count, uint32_t waitMask) {
auto& bucket = EmulatedFutexBucket::bucketFor(addr);
std::unique_lock<std::mutex> bucketLock(bucket.mutex_);
return FutexResult::AWOKEN;
}
-} // anon namespace
-
+} // namespace
/////////////////////////////////
// Futex<> specializations
this, expected, absSystemTime, absSteadyTime, waitMask);
}
-}} // namespace folly::detail
+} // namespace detail
+} // namespace folly