Statically allocate futex array
[folly.git] / folly / detail / Futex.cpp
index edaa279e77ffb2eaccc31eeed8bfe7451d57b8f4..a7847b18b637b8cd8038a54255c8e98d1beb5d36 100644 (file)
  */
 
 #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/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 {
 
@@ -185,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];
   }
 };
 
@@ -268,8 +275,7 @@ FutexResult emulatedFutexWaitImpl(
   return FutexResult::AWOKEN;
 }
 
-} // anon namespace
-
+} // namespace
 
 /////////////////////////////////
 // Futex<> specializations
@@ -316,4 +322,5 @@ Futex<EmulatedFutexAtomic>::futexWaitImpl(
       this, expected, absSystemTime, absSteadyTime, waitMask);
 }
 
-}} // namespace folly::detail
+} // namespace detail
+} // namespace folly