From 36ca845043259977fac1e8cddec7427d711e1126 Mon Sep 17 00:00:00 2001 From: Hans Fugal Date: Thu, 11 Jun 2015 13:53:21 -0700 Subject: [PATCH] Replace thread_local with FOLLY_TLS Summary: OSX doesn't support C++11's `thread_local`. :-/ (yet? http://stackoverflow.com/questions/28094794/why-does-apple-clang-disallow-c11-thread-local-when-official-clang-supports/29929949#29929949) We have `FOLLY_TLS` in `Portability.h` https://github.com/facebook/folly/blob/master/folly/Portability.h#L163-L175 So replace the usages of `thread_local` with `FOLLY_TLS`. But `__thread` is not drop-in compatible with `thread_local`, specifically the former requires global storage and needs a constexpr initializer, and a trivial destructor. `futures/QueuedImmediateExecutor` now uses `folly::ThreadLocal` (because `std::queue` has a non-trivial destructor). It might end up in one more alloc, per thread. I also rearranged the code to clarify the fact that although there may be many `QueuedImmediateExecutor`s, they all share the same queue per thread. I didn't use `folly::ThreadLocal` for fibers, because I thought it might be too expensive. But now I'm not so sure. I had to do the "check for default and then initialize" thing because of the requirement for constexpr initialization for `__thread` (and therefore `FOLLY_TLS`). Reviewed By: @jsedgwick Differential Revision: D2140369 --- folly/experimental/fibers/Fiber.cpp | 7 ++++++- folly/experimental/fibers/FiberManager-inl.h | 13 +++++++------ folly/futures/QueuedImmediateExecutor.cpp | 16 ++++++++-------- folly/futures/QueuedImmediateExecutor.h | 8 +++++++- 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/folly/experimental/fibers/Fiber.cpp b/folly/experimental/fibers/Fiber.cpp index 2a562774..e66752ac 100644 --- a/folly/experimental/fibers/Fiber.cpp +++ b/folly/experimental/fibers/Fiber.cpp @@ -34,7 +34,12 @@ namespace { static const uint64_t kMagic8Bytes = 0xfaceb00cfaceb00c; pid_t localThreadId() { - static thread_local pid_t threadId = syscall(SYS_gettid); + // __thread doesn't allow non-const initialization. + // OSX doesn't support thread_local. + static FOLLY_TLS pid_t threadId = 0; + if (UNLIKELY(threadId == 0)) { + threadId = syscall(SYS_gettid); + } return threadId; } diff --git a/folly/experimental/fibers/FiberManager-inl.h b/folly/experimental/fibers/FiberManager-inl.h index c0f0d557..42d14ac0 100644 --- a/folly/experimental/fibers/FiberManager-inl.h +++ b/folly/experimental/fibers/FiberManager-inl.h @@ -18,15 +18,16 @@ #include #include +#include +#include +#include +#include +#include #include #include #include #include #include -#include -#include -#include -#include namespace folly { namespace fibers { @@ -454,8 +455,8 @@ T& FiberManager::local() { template T& FiberManager::localThread() { - static thread_local T t; - return t; + static ThreadLocal t; + return *t; } inline void FiberManager::initLocalData(Fiber& fiber) { diff --git a/folly/futures/QueuedImmediateExecutor.cpp b/folly/futures/QueuedImmediateExecutor.cpp index 659f3f13..47b298f5 100644 --- a/folly/futures/QueuedImmediateExecutor.cpp +++ b/folly/futures/QueuedImmediateExecutor.cpp @@ -20,17 +20,17 @@ namespace folly { -void QueuedImmediateExecutor::add(Func callback) { - thread_local std::queue q; +void QueuedImmediateExecutor::addStatic(Func callback) { + static folly::ThreadLocal> q_; - if (q.empty()) { - q.push(std::move(callback)); - while (!q.empty()) { - q.front()(); - q.pop(); + if (q_->empty()) { + q_->push(std::move(callback)); + while (!q_->empty()) { + q_->front()(); + q_->pop(); } } else { - q.push(callback); + q_->push(callback); } } diff --git a/folly/futures/QueuedImmediateExecutor.h b/folly/futures/QueuedImmediateExecutor.h index 15e2513f..d1faa7e7 100644 --- a/folly/futures/QueuedImmediateExecutor.h +++ b/folly/futures/QueuedImmediateExecutor.h @@ -27,7 +27,13 @@ namespace folly { */ class QueuedImmediateExecutor : public Executor { public: - void add(Func) override; + /// There's really only one queue per thread, no matter how many + /// QueuedImmediateExecutor objects you may have. + static void addStatic(Func); + + void add(Func func) override { + addStatic(std::move(func)); + } }; } // folly -- 2.34.1