Fix up bmalloc's PerThread for use on Linux
authorggaren@apple.com <ggaren@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 5 Jan 2015 23:33:54 +0000 (23:33 +0000)
committerggaren@apple.com <ggaren@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 5 Jan 2015 23:33:54 +0000 (23:33 +0000)
https://bugs.webkit.org/show_bug.cgi?id=139804

Reviewed by Anders Carlsson.

The previous implementation was a bit slow.

* bmalloc/PerThread.h:
(bmalloc::PerThreadStorage<Cache>::get):
(bmalloc::PerThreadStorage::get):
(bmalloc::PerThreadStorage::init): Added a catch-all cross-platform Unix
way to do fast per-thread access without taking a lock every time. This
probably works on all the platforms we care about, and it matches other
techniques we use elsewhere in WebKit.

(bmalloc::PerThread<T>::getFastCase): Removed the conditional from
this class because PerThreadStorage now encapsulates everything that
needs to be conditional.

(bmalloc::PerThreadStorage::initSharedKeyIfNeeded): Deleted.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@177931 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/bmalloc/ChangeLog
Source/bmalloc/bmalloc/PerThread.h

index 88fbede..a036ea5 100644 (file)
@@ -1,3 +1,26 @@
+2015-01-05  Geoffrey Garen  <ggaren@apple.com>
+
+        Fix up bmalloc's PerThread for use on Linux
+        https://bugs.webkit.org/show_bug.cgi?id=139804
+
+        Reviewed by Anders Carlsson.
+
+        The previous implementation was a bit slow.
+
+        * bmalloc/PerThread.h:
+        (bmalloc::PerThreadStorage<Cache>::get):
+        (bmalloc::PerThreadStorage::get):
+        (bmalloc::PerThreadStorage::init): Added a catch-all cross-platform Unix
+        way to do fast per-thread access without taking a lock every time. This
+        probably works on all the platforms we care about, and it matches other
+        techniques we use elsewhere in WebKit.
+
+        (bmalloc::PerThread<T>::getFastCase): Removed the conditional from
+        this class because PerThreadStorage now encapsulates everything that
+        needs to be conditional.
+
+        (bmalloc::PerThreadStorage::initSharedKeyIfNeeded): Deleted.
+
 2014-12-26  Dan Bernstein  <mitz@apple.com>
 
         <rdar://problem/19348208> REGRESSION (r177027): iOS builds use the wrong toolchain
index d0a2516..02f07e1 100644 (file)
@@ -50,17 +50,21 @@ private:
     static void destructor(void*);
 };
 
-class Cache;
+#if defined(__has_include) && __has_include(<System/pthread_machdep.h>)
 
+class Cache;
 template<typename T> struct PerThreadStorage;
 
-#if defined(__has_include) && __has_include(<System/pthread_machdep.h>)
 // For now, we only support PerThread<Cache>. We can expand to other types by
 // using more keys.
-
 template<> struct PerThreadStorage<Cache> {
     static const pthread_key_t key = __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY0;
-    static void* get() { return _pthread_getspecific_direct(key); }
+
+    static void* get()
+    {
+        return _pthread_getspecific_direct(key);
+    }
+
     static void init(void* object, void (*destructor)(void*))
     {
         _pthread_setspecific_direct(key, object);
@@ -71,52 +75,36 @@ template<> struct PerThreadStorage<Cache> {
 #else
 
 template<typename T> struct PerThreadStorage {
-#if BCOMPILER_SUPPORTS(CXX_THREAD_LOCAL)
-    static __thread void* object;
-#endif
-    static pthread_key_t key;
-    static std::once_flag onceFlag;
-
+    static bool s_didInitialize;
+    static pthread_key_t s_key;
+    static std::once_flag s_onceFlag;
+    
     static void* get()
     {
-#if BCOMPILER_SUPPORTS(CXX_THREAD_LOCAL)
-        return object;
-#else
-        return pthread_getspecific(key);
-#endif
-    }
-
-    static void initSharedKeyIfNeeded(void (*destructor)(void*))
-    {
-        std::call_once(onceFlag, [destructor]() {
-            pthread_key_create(&key, destructor);
-        });
+        if (!s_didInitialize)
+            return nullptr;
+        return pthread_getspecific(s_key);
     }
-
+    
     static void init(void* object, void (*destructor)(void*))
     {
-        initSharedKeyIfNeeded(destructor);
-        pthread_setspecific(key, object);
-#if BCOMPILER_SUPPORTS(CXX_THREAD_LOCAL)
-        PerThreadStorage<Cache>::object = object;
-#endif
+        std::call_once(s_onceFlag, [destructor]() {
+            pthread_key_create(&s_key, destructor);
+            s_didInitialize = true;
+        });
+        pthread_setspecific(s_key, object);
     }
 };
 
-#if BCOMPILER_SUPPORTS(CXX_THREAD_LOCAL)
-template<typename T> __thread void* PerThreadStorage<T>::object;
-#endif
-template<typename T> pthread_key_t PerThreadStorage<T>::key;
-template<typename T> std::once_flag PerThreadStorage<T>::onceFlag;
+template<typename T> bool PerThreadStorage<T>::s_didInitialize;
+template<typename T> pthread_key_t PerThreadStorage<T>::s_key;
+template<typename T> std::once_flag PerThreadStorage<T>::s_onceFlag;
 
 #endif // defined(__has_include) && __has_include(<System/pthread_machdep.h>)
 
 template<typename T>
 INLINE T* PerThread<T>::getFastCase()
 {
-#if (!defined(__has_include) || !__has_include(<System/pthread_machdep.h>)) && !BCOMPILER_SUPPORTS(CXX_THREAD_LOCAL)
-    PerThreadStorage<T>::initSharedKeyIfNeeded(destructor);
-#endif
     return static_cast<T*>(PerThreadStorage<T>::get());
 }