Title: [231151] trunk/Source/WTF
Revision
231151
Author
[email protected]
Date
2018-04-29 10:29:13 -0700 (Sun, 29 Apr 2018)

Log Message

WordLock doesn't need per-thread data
https://bugs.webkit.org/show_bug.cgi?id=185119

Reviewed by Yusuke Suzuki.

The stack is per-thread data, so we can stack-allocate our ThreadData.

This eliminates malloc() and high-level WTF threading primitives from
WordLock, making WordLock more portable to non-WTF code, including
bmalloc.

(NOTE: This patch makes the bug fixed in r231148 100% reproducible.)

* wtf/WordLock.cpp:
(WTF::WordLock::lockSlow): Allocate ThreadData on the stack.

Modified Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (231150 => 231151)


--- trunk/Source/WTF/ChangeLog	2018-04-29 16:09:38 UTC (rev 231150)
+++ trunk/Source/WTF/ChangeLog	2018-04-29 17:29:13 UTC (rev 231151)
@@ -1,3 +1,21 @@
+2018-04-29  Geoffrey Garen  <[email protected]>
+
+        WordLock doesn't need per-thread data
+        https://bugs.webkit.org/show_bug.cgi?id=185119
+
+        Reviewed by Yusuke Suzuki.
+
+        The stack is per-thread data, so we can stack-allocate our ThreadData.
+
+        This eliminates malloc() and high-level WTF threading primitives from
+        WordLock, making WordLock more portable to non-WTF code, including
+        bmalloc.
+
+        (NOTE: This patch makes the bug fixed in r231148 100% reproducible.)
+
+        * wtf/WordLock.cpp:
+        (WTF::WordLock::lockSlow): Allocate ThreadData on the stack.
+
 2018-04-28  Geoffrey Garen  <[email protected]>
 
         Fixed a very unlikely race condition in WTF::WordLock

Modified: trunk/Source/WTF/wtf/WordLock.cpp (231150 => 231151)


--- trunk/Source/WTF/wtf/WordLock.cpp	2018-04-29 16:09:38 UTC (rev 231150)
+++ trunk/Source/WTF/wtf/WordLock.cpp	2018-04-29 17:29:13 UTC (rev 231151)
@@ -26,9 +26,7 @@
 #include "config.h"
 #include "WordLock.h"
 
-#include "ThreadSpecific.h"
 #include "Threading.h"
-#include "ThreadingPrimitives.h"
 #include <condition_variable>
 #include <mutex>
 #include <thread>
@@ -60,20 +58,6 @@
     ThreadData* queueTail { nullptr };
 };
 
-ThreadSpecific<ThreadData, CanBeGCThread::True>* threadData;
-
-ThreadData* myThreadData()
-{
-    static std::once_flag initializeOnce;
-    std::call_once(
-        initializeOnce,
-        [] {
-            threadData = new ThreadSpecific<ThreadData, CanBeGCThread::True>();
-        });
-
-    return *threadData;
-}
-
 } // anonymous namespace
 
 NEVER_INLINE void WordLock::lockSlow()
@@ -106,13 +90,9 @@
 
         // Need to put ourselves on the queue. Create the queue if one does not exist. This requries
         // owning the queue for a little bit. The lock that controls the queue is itself a spinlock.
-        // But before we acquire the queue spinlock, we make sure that we have a ThreadData for this
-        // thread.
-        ThreadData* me = myThreadData();
-        ASSERT(!me->shouldPark);
-        ASSERT(!me->nextInQueue);
-        ASSERT(!me->queueTail);
 
+        ThreadData me;
+
         // Reload the current word value, since some time may have passed.
         currentWordValue = m_word.load();
 
@@ -125,7 +105,7 @@
             continue;
         }
         
-        me->shouldPark = true;
+        me.shouldPark = true;
 
         // We own the queue. Nobody can enqueue or dequeue until we're done. Also, it's not possible
         // to release the WordLock while we hold the queue lock.
@@ -132,8 +112,8 @@
         ThreadData* queueHead = bitwise_cast<ThreadData*>(currentWordValue & ~queueHeadMask);
         if (queueHead) {
             // Put this thread at the end of the queue.
-            queueHead->queueTail->nextInQueue = me;
-            queueHead->queueTail = me;
+            queueHead->queueTail->nextInQueue = &me;
+            queueHead->queueTail = &me;
 
             // Release the queue lock.
             currentWordValue = m_word.load();
@@ -143,8 +123,8 @@
             m_word.store(currentWordValue & ~isQueueLockedBit);
         } else {
             // Make this thread be the queue-head.
-            queueHead = me;
-            me->queueTail = me;
+            queueHead = &me;
+            me.queueTail = &me;
 
             // Release the queue lock and install ourselves as the head. No need for a CAS loop, since
             // we own the queue lock.
@@ -164,14 +144,14 @@
         // releasing thread holds me's parkingLock.
 
         {
-            std::unique_lock<std::mutex> locker(me->parkingLock);
-            while (me->shouldPark)
-                me->parkingCondition.wait(locker);
+            std::unique_lock<std::mutex> locker(me.parkingLock);
+            while (me.shouldPark)
+                me.parkingCondition.wait(locker);
         }
 
-        ASSERT(!me->shouldPark);
-        ASSERT(!me->nextInQueue);
-        ASSERT(!me->queueTail);
+        ASSERT(!me.shouldPark);
+        ASSERT(!me.nextInQueue);
+        ASSERT(!me.queueTail);
         
         // Now we can loop around and try to acquire the lock again.
     }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to