Don't use FOLLY_TLS on Android
authorSean Cannella <seanc@fb.com>
Tue, 30 Dec 2014 18:01:11 +0000 (10:01 -0800)
committerAjit Banerjee <ajitb@fb.com>
Wed, 7 Jan 2015 20:24:35 +0000 (12:24 -0800)
Summary:
emutls as far as StaticMeta needs to use it is broken on
Android as well due to unspecified pthread_key cleanup order between the
emulated __thread and our manual uses of it. Use the alternative that we
use on __APPLE__ there as well.

Test Plan: compiled and ran consuming code on Android

Reviewed By: dancol@fb.com

Subscribers: fma, shikong, kmdent, benyluo, ranjeeth, subodh, folly-diffs@

FB internal diff: D1760569

Tasks: 52657545907613

Signature: t1:1760569:1419955865:afe8f35dadda85393492ac9331e9f62a74f4fdad

folly/Portability.h
folly/detail/ThreadLocalDetail.h

index f35e3bbb9d8daf8048005bb5b8699d3b230a6954..87dbe2569314fc239f4ed779c1fd56d66e12d15f 100644 (file)
@@ -152,7 +152,8 @@ struct MaxAlign { char c; } __attribute__((__aligned__));
 /* Platform specific TLS support
  * gcc implements __thread
  * msvc implements __declspec(thread)
- * the semantics are the same (but remember __thread is broken on apple)
+ * the semantics are the same
+ * (but remember __thread has different semantics when using emutls (ex. apple))
  */
 #if defined(_MSC_VER)
 # define FOLLY_TLS __declspec(thread)
index 6b7a29443313d6a2546189a19c2957702cb54378..4f08acd587b53e6780755466661df7abbee312f4 100644 (file)
 #include <folly/Exception.h>
 #include <folly/Malloc.h>
 
+// In general, emutls cleanup is not guaranteed to play nice with the way
+// StaticMeta mixes direct pthread calls and the use of __thread. This has
+// caused problems on multiple platforms so don't use __thread there.
+//
+// XXX: Ideally we would instead determine if emutls is in use at runtime as it
+// is possible to configure glibc on Linux to use emutls regardless.
+#if !__APPLE__ && !__ANDROID__
+#define FOLLY_TLD_USE_FOLLY_TLS 1
+#else
+#undef FOLLY_TLD_USE_FOLLY_TLS
+#endif
+
 namespace folly {
 namespace threadlocal_detail {
 
@@ -185,7 +197,7 @@ struct StaticMeta {
     t->next = t->prev = t;
   }
 
-#if !__APPLE__
+#ifdef FOLLY_TLD_USE_FOLLY_TLS
   static FOLLY_TLS ThreadEntry threadEntry_;
 #endif
   static StaticMeta<Tag>* inst_;
@@ -210,7 +222,7 @@ struct StaticMeta {
   }
 
   static ThreadEntry* getThreadEntry() {
-#if !__APPLE__
+#ifdef FOLLY_TLD_USE_FOLLY_TLS
     return &threadEntry_;
 #else
     ThreadEntry* threadEntry =
@@ -245,7 +257,7 @@ struct StaticMeta {
 
   static void onThreadExit(void* ptr) {
     auto& meta = instance();
-#if !__APPLE__
+#ifdef FOLLY_TLD_USE_FOLLY_TLS
     ThreadEntry* threadEntry = getThreadEntry();
 
     DCHECK_EQ(ptr, &meta);
@@ -275,8 +287,8 @@ struct StaticMeta {
     threadEntry->elements = nullptr;
     pthread_setspecific(meta.pthreadKey_, nullptr);
 
-#if __APPLE__
-    // Allocated in getThreadEntry(); free it
+#ifndef FOLLY_TLD_USE_FOLLY_TLS
+    // Allocated in getThreadEntry() when not using folly TLS; free it
     delete threadEntry;
 #endif
   }
@@ -415,7 +427,7 @@ struct StaticMeta {
 
     free(reallocated);
 
-#if !__APPLE__
+#ifdef FOLLY_TLD_USE_FOLLY_TLS
     if (prevCapacity == 0) {
       pthread_setspecific(meta.pthreadKey_, &meta);
     }
@@ -432,7 +444,7 @@ struct StaticMeta {
   }
 };
 
-#if !__APPLE__
+#ifdef FOLLY_TLD_USE_FOLLY_TLS
 template <class Tag>
 FOLLY_TLS ThreadEntry StaticMeta<Tag>::threadEntry_{nullptr, 0,
                                                     nullptr, nullptr};