Bug 1348419 - Use thread_local on XP_WIN and XP_MACOSX; r?froydnj draft
authorTom Tromey <tom@tromey.com>
Wed, 22 Mar 2017 12:04:21 -0600
changeset 563749 492b54c16cddea29323583c408a69f5c2c6ab6db
parent 561392 ad206b7a264422e4d468db356931b0a0c3fa7bb6
child 624564 d26c22ba0ce8ec9c28be84dd0c9f7479fb16cdd3
push id54405
push userbmo:ttromey@mozilla.com
push dateMon, 17 Apr 2017 18:17:48 +0000
reviewersfroydnj
bugs1348419
milestone55.0a1
Bug 1348419 - Use thread_local on XP_WIN and XP_MACOSX; r?froydnj MozReview-Commit-ID: 75dTUk27p94
js/src/jsutil.cpp
mfbt/ThreadLocal.h
--- a/js/src/jsutil.cpp
+++ b/js/src/jsutil.cpp
@@ -34,17 +34,17 @@ using mozilla::PodArrayZero;
 /* For OOM testing functionality in Utility.h. */
 namespace js {
 
 mozilla::Atomic<AutoEnterOOMUnsafeRegion*> AutoEnterOOMUnsafeRegion::owner_;
 
 namespace oom {
 
 JS_PUBLIC_DATA(uint32_t) targetThread = 0;
-JS_PUBLIC_DATA(MOZ_THREAD_LOCAL(uint32_t)) threadType;
+MOZ_THREAD_LOCAL(uint32_t) threadType;
 JS_PUBLIC_DATA(uint64_t) maxAllocations = UINT64_MAX;
 JS_PUBLIC_DATA(uint64_t) counter = 0;
 JS_PUBLIC_DATA(bool) failAlways = true;
 
 bool
 InitThreadType(void) {
     return threadType.init();
 }
--- a/mfbt/ThreadLocal.h
+++ b/mfbt/ThreadLocal.h
@@ -4,30 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* Cross-platform lightweight thread local data wrappers. */
 
 #ifndef mozilla_ThreadLocal_h
 #define mozilla_ThreadLocal_h
 
-#if defined(XP_WIN)
-// This file will get included in any file that wants to add a profiler mark.
-// In order to not bring <windows.h> together we could include windef.h and
-// winbase.h which are sufficient to get the prototypes for the Tls* functions.
-// # include <windef.h>
-// # include <winbase.h>
-// Unfortunately, even including these headers causes us to add a bunch of ugly
-// stuff to our namespace e.g #define CreateEvent CreateEventW
-extern "C" {
-__declspec(dllimport) void* __stdcall TlsGetValue(unsigned long);
-__declspec(dllimport) int __stdcall TlsSetValue(unsigned long, void*);
-__declspec(dllimport) unsigned long __stdcall TlsAlloc();
-}
-#else
+#if !defined(XP_WIN)
 #  include <pthread.h>
 #  include <signal.h>
 #endif
 
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/TypeTraits.h"
 
@@ -39,17 +26,17 @@ namespace mozilla {
 #if defined(XP_WIN)
 typedef unsigned long sig_safe_t;
 #else
 typedef sig_atomic_t sig_safe_t;
 #endif
 
 namespace detail {
 
-#if defined(HAVE_THREAD_TLS_KEYWORD)
+#if defined(HAVE_THREAD_TLS_KEYWORD) || defined(XP_WIN) || defined(XP_MACOSX)
 #define MOZ_HAS_THREAD_LOCAL
 #endif
 
 /*
  * Thread Local Storage helpers.
  *
  * Usage:
  *
@@ -86,21 +73,17 @@ namespace detail {
  *
  * // Get the TLS value
  * int value = tlsKey.get();
  */
 template<typename T>
 class ThreadLocal
 {
 #ifndef MOZ_HAS_THREAD_LOCAL
-#if defined(XP_WIN)
-  typedef unsigned long key_t;
-#else
   typedef pthread_key_t key_t;
-#endif
 
   // Integral types narrower than void* must be extended to avoid
   // warnings from valgrind on some platforms.  This helper type
   // achieves that without penalizing the common case of ThreadLocals
   // instantiated using a pointer type.
   template<typename S>
   struct Helper
   {
@@ -156,67 +139,58 @@ ThreadLocal<T>::init()
   static_assert(sizeof(T) <= sizeof(void*),
                 "mozilla::ThreadLocal can't be used for types larger than "
                 "a pointer");
 
 #ifdef MOZ_HAS_THREAD_LOCAL
   return true;
 #else
   if (!initialized()) {
-#ifdef XP_WIN
-    mKey = TlsAlloc();
-    mInited = mKey != 0xFFFFFFFFUL; // TLS_OUT_OF_INDEXES
-#else
     mInited = !pthread_key_create(&mKey, nullptr);
-#endif
   }
   return mInited;
 #endif
 }
 
 template<typename T>
 inline T
 ThreadLocal<T>::get() const
 {
 #ifdef MOZ_HAS_THREAD_LOCAL
   return mValue;
 #else
   MOZ_ASSERT(initialized());
   void* h;
-#ifdef XP_WIN
-  h = TlsGetValue(mKey);
-#else
   h = pthread_getspecific(mKey);
-#endif
   return static_cast<T>(reinterpret_cast<typename Helper<T>::Type>(h));
 #endif
 }
 
 template<typename T>
 inline void
 ThreadLocal<T>::set(const T aValue)
 {
 #ifdef MOZ_HAS_THREAD_LOCAL
   mValue = aValue;
 #else
   MOZ_ASSERT(initialized());
   void* h = reinterpret_cast<void*>(static_cast<typename Helper<T>::Type>(aValue));
-#ifdef XP_WIN
-  bool succeeded = TlsSetValue(mKey, h);
-#else
   bool succeeded = !pthread_setspecific(mKey, h);
-#endif
   if (!succeeded) {
     MOZ_CRASH();
   }
 #endif
 }
 
 #ifdef MOZ_HAS_THREAD_LOCAL
+#if defined(XP_WIN) || defined(XP_MACOSX)
+#define MOZ_THREAD_LOCAL(TYPE) thread_local mozilla::detail::ThreadLocal<TYPE>
+#else
 #define MOZ_THREAD_LOCAL(TYPE) __thread mozilla::detail::ThreadLocal<TYPE>
+#endif
 #else
 #define MOZ_THREAD_LOCAL(TYPE) mozilla::detail::ThreadLocal<TYPE>
 #endif
 
 } // namespace detail
 } // namespace mozilla
 
 #endif /* mozilla_ThreadLocal_h */