Bug 1399031 - Add a Tls{Get,Set}Value-based ThreadLocal implementation for Windows. r=froydnj
authorMike Hommey <mh+mozilla@glandium.org>
Tue, 12 Sep 2017 16:04:17 +0900
changeset 430257 47efe55def9e4a4e26b33e941fbc0c4a73112aed
parent 430256 a6e26c4c5704e3ed1969ff903d7396b946247786
child 430258 3025f5550677377d6234f296dc0d903b4da8176c
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1399031
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1399031 - Add a Tls{Get,Set}Value-based ThreadLocal implementation for Windows. r=froydnj
mfbt/ThreadLocal.h
--- a/mfbt/ThreadLocal.h
+++ b/mfbt/ThreadLocal.h
@@ -63,36 +63,69 @@ namespace detail {
  * }
  *
  * // Set the TLS value
  * tlsKey.set(123);
  *
  * // Get the TLS value
  * int value = tlsKey.get();
  */
-#ifndef XP_WIN
+
+// 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
+{
+  typedef uintptr_t Type;
+};
+
+template<typename S>
+struct Helper<S *>
+{
+  typedef S *Type;
+};
+
+#ifdef XP_WIN
+/* Despite not being used for MOZ_THREAD_LOCAL, we expose an implementation for
+ * Windows for cases where it's not desirable to use thread_local */
 template<typename T>
 class ThreadLocalKeyStorage
 {
-  // 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
-  {
-    typedef uintptr_t Type;
-  };
+public:
+  ThreadLocalKeyStorage()
+    : mKey(TLS_OUT_OF_INDEXES)
+  {}
+
+  inline bool initialized() const {
+    return mKey != TLS_OUT_OF_INDEXES;
+  }
+
+  inline void init() {
+    mKey = TlsAlloc();
+  }
 
-  template<typename S>
-  struct Helper<S *>
-  {
-    typedef S *Type;
-  };
+  inline T get() const {
+    void* h = TlsGetValue(mKey);
+    return static_cast<T>(reinterpret_cast<typename Helper<T>::Type>(h));
+  }
 
+  inline bool set(const T aValue) {
+    void* h = reinterpret_cast<void*>(static_cast<typename Helper<T>::Type>(aValue));
+    return TlsSetValue(mKey, h);
+  }
+
+private:
+  unsigned long mKey;
+};
+#else
+template<typename T>
+class ThreadLocalKeyStorage
+{
 public:
   ThreadLocalKeyStorage()
     : mKey(0), mInited(false)
   {}
 
   inline bool initialized() const {
     return mInited;
   }