From b7912274c8c83eba09064ad943359252a32eeb85 Mon Sep 17 00:00:00 2001 From: Sean Cannella Date: Tue, 30 Dec 2014 10:01:11 -0800 Subject: [PATCH] Don't use FOLLY_TLS on Android 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: 5265754, 5907613 Signature: t1:1760569:1419955865:afe8f35dadda85393492ac9331e9f62a74f4fdad --- folly/Portability.h | 3 ++- folly/detail/ThreadLocalDetail.h | 26 +++++++++++++++++++------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/folly/Portability.h b/folly/Portability.h index f35e3bbb..87dbe256 100644 --- a/folly/Portability.h +++ b/folly/Portability.h @@ -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) diff --git a/folly/detail/ThreadLocalDetail.h b/folly/detail/ThreadLocalDetail.h index 6b7a2944..4f08acd5 100644 --- a/folly/detail/ThreadLocalDetail.h +++ b/folly/detail/ThreadLocalDetail.h @@ -30,6 +30,18 @@ #include #include +// 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* 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 FOLLY_TLS ThreadEntry StaticMeta::threadEntry_{nullptr, 0, nullptr, nullptr}; -- 2.34.1