Statically allocate futex array v2017.12.04.00
authorAlastair Daivis <alaroldai@fb.com>
Sun, 3 Dec 2017 01:35:33 +0000 (17:35 -0800)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Sun, 3 Dec 2017 01:51:46 +0000 (17:51 -0800)
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

folly/Portability.h
folly/detail/Futex.cpp

index 6c140379de9e9920755e3eb70cb615c6bd8acb88..3f06c7753e743e99ffdd8f37a3efc5d320442de1 100644 (file)
@@ -399,6 +399,12 @@ constexpr auto kIsObjC = true;
 constexpr auto kIsObjC = false;
 #endif
 
 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
 #if defined(__linux__) && !FOLLY_MOBILE
 constexpr auto kIsLinux = true;
 #else
index da7a04dce18d88d1f8971934e10233a708b2c68f..a7847b18b637b8cd8038a54255c8e98d1beb5d36 100644 (file)
 
 #include <folly/detail/Futex.h>
 #include <boost/intrusive/list.hpp>
 
 #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 <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 <cerrno>
 #include <condition_variable>
 #include <mutex>
@@ -186,13 +188,17 @@ struct EmulatedFutexBucket {
   std::mutex mutex_;
   boost::intrusive::list<EmulatedFutexWaitNode> waiters_;
 
   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 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];
   }
 };
 
   }
 };