Title: [278257] trunk/Source
Revision
278257
Author
cdu...@apple.com
Date
2021-05-30 13:35:59 -0700 (Sun, 30 May 2021)

Log Message

Drop UncheckedCondition / UncheckedLock
https://bugs.webkit.org/show_bug.cgi?id=226432

Reviewed by Darin Adler.

Source/_javascript_Core:

Drop one remaining use of UncheckedLock in favor of Lock.

* jit/JITSafepoint.cpp:
* jit/JITWorklistThread.h:

Source/WTF:

Drop UncheckedCondition / UncheckedLock now that the whole codebase has been ported to
Condition / Lock, which support Clang thread safety analysis.

* wtf/Condition.h:
* wtf/Forward.h:
* wtf/Lock.cpp:
(WTF::Lock::lockSlow):
(WTF::Lock::unlockSlow):
(WTF::Lock::unlockFairlySlow):
(WTF::Lock::safepointSlow):
* wtf/Lock.h:
(WTF::assertIsHeld):
(WTF::WTF_ASSERTS_ACQUIRED_LOCK):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (278256 => 278257)


--- trunk/Source/_javascript_Core/ChangeLog	2021-05-30 19:45:09 UTC (rev 278256)
+++ trunk/Source/_javascript_Core/ChangeLog	2021-05-30 20:35:59 UTC (rev 278257)
@@ -1,3 +1,15 @@
+2021-05-30  Chris Dumez  <cdu...@apple.com>
+
+        Drop UncheckedCondition / UncheckedLock
+        https://bugs.webkit.org/show_bug.cgi?id=226432
+
+        Reviewed by Darin Adler.
+
+        Drop one remaining use of UncheckedLock in favor of Lock.
+
+        * jit/JITSafepoint.cpp:
+        * jit/JITWorklistThread.h:
+
 2021-05-30  Darin Adler  <da...@apple.com>
 
         Remove WTF::Optional synonym for std::optional, using that class template directly instead

Modified: trunk/Source/_javascript_Core/jit/JITSafepoint.cpp (278256 => 278257)


--- trunk/Source/_javascript_Core/jit/JITSafepoint.cpp	2021-05-30 19:45:09 UTC (rev 278256)
+++ trunk/Source/_javascript_Core/jit/JITSafepoint.cpp	2021-05-30 20:35:59 UTC (rev 278257)
@@ -73,7 +73,7 @@
     m_scannables.append(scannable);
 }
 
-void Safepoint::begin()
+void Safepoint::begin() WTF_IGNORES_THREAD_SAFETY_ANALYSIS
 {
     RELEASE_ASSERT(!m_didCallBegin);
     m_didCallBegin = true;

Modified: trunk/Source/_javascript_Core/jit/JITWorklistThread.h (278256 => 278257)


--- trunk/Source/_javascript_Core/jit/JITWorklistThread.h	2021-05-30 19:45:09 UTC (rev 278256)
+++ trunk/Source/_javascript_Core/jit/JITWorklistThread.h	2021-05-30 20:35:59 UTC (rev 278257)
@@ -55,7 +55,7 @@
 
     void threadIsStopping(const AbstractLocker&) final;
 
-    UncheckedLock m_rightToRun;
+    Lock m_rightToRun;
     JITWorklist& m_worklist;
     RefPtr<JITPlan> m_plan { nullptr };
     Safepoint* m_safepoint { nullptr };

Modified: trunk/Source/WTF/ChangeLog (278256 => 278257)


--- trunk/Source/WTF/ChangeLog	2021-05-30 19:45:09 UTC (rev 278256)
+++ trunk/Source/WTF/ChangeLog	2021-05-30 20:35:59 UTC (rev 278257)
@@ -1,3 +1,24 @@
+2021-05-30  Chris Dumez  <cdu...@apple.com>
+
+        Drop UncheckedCondition / UncheckedLock
+        https://bugs.webkit.org/show_bug.cgi?id=226432
+
+        Reviewed by Darin Adler.
+
+        Drop UncheckedCondition / UncheckedLock now that the whole codebase has been ported to
+        Condition / Lock, which support Clang thread safety analysis.
+
+        * wtf/Condition.h:
+        * wtf/Forward.h:
+        * wtf/Lock.cpp:
+        (WTF::Lock::lockSlow):
+        (WTF::Lock::unlockSlow):
+        (WTF::Lock::unlockFairlySlow):
+        (WTF::Lock::safepointSlow):
+        * wtf/Lock.h:
+        (WTF::assertIsHeld):
+        (WTF::WTF_ASSERTS_ACQUIRED_LOCK):
+
 2021-05-30  Darin Adler  <da...@apple.com>
 
         Remove WTF::Optional synonym for std::optional, using that class template directly instead

Modified: trunk/Source/WTF/wtf/Condition.h (278256 => 278257)


--- trunk/Source/WTF/wtf/Condition.h	2021-05-30 19:45:09 UTC (rev 278256)
+++ trunk/Source/WTF/wtf/Condition.h	2021-05-30 20:35:59 UTC (rev 278257)
@@ -40,16 +40,16 @@
 // notifyAll() require just a load and branch for the fast case where no thread is waiting.
 // This condition variable, when used with WTF::Lock, can outperform a system condition variable
 // and lock by up to 58x.
-class UncheckedCondition final {
-    WTF_MAKE_NONCOPYABLE(UncheckedCondition);
+class Condition final {
+    WTF_MAKE_NONCOPYABLE(Condition);
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    // UncheckedCondition will accept any kind of time and convert it internally, but this typedef tells
-    // you what kind of time UncheckedCondition would be able to use without conversions. However, if you
+    // Condition will accept any kind of time and convert it internally, but this typedef tells
+    // you what kind of time Condition would be able to use without conversions. However, if you
     // are unlikely to be affected by the cost of conversions, it is better to use MonotonicTime.
     using Time = ParkingLot::Time;
 
-    constexpr UncheckedCondition() = default;
+    constexpr Condition() = default;
 
     // Wait on a parking queue while releasing the given lock. It will unlock the lock just before
     // parking, and relock it upon wakeup. Returns true if we woke up due to some call to
@@ -69,47 +69,41 @@
     template<typename LockType>
     bool waitUntil(LockType& lock, const TimeWithDynamicClockType& timeout)
     {
-        bool result;
-        if (timeout < timeout.nowWithSameClock()) {
-            lock.unlock();
-            result = false;
-        } else {
-            result = ParkingLot::parkConditionally(
-                &m_hasWaiters,
-                [this] () -> bool {
-                    // Let everyone know that we will be waiting. Do this while we hold the queue lock,
-                    // to prevent races with notifyOne().
-                    m_hasWaiters.store(true);
-                    return true;
-                },
-                [&lock] () { lock.unlock(); },
-                timeout).wasUnparked;
-        }
-        lock.lock();
-        return result;
+        return waitUntilUnchecked(lock, timeout);
     }
 
+    bool waitUntil(Lock& lock, const TimeWithDynamicClockType& timeout) WTF_REQUIRES_LOCK(lock)
+    {
+        return waitUntilUnchecked(lock, timeout);
+    }
+
     // Wait until the given predicate is satisfied. Returns true if it is satisfied in the end.
     // May return early due to timeout.
     template<typename LockType, typename Functor>
-    bool waitUntil(
-        LockType& lock, const TimeWithDynamicClockType& timeout, const Functor& predicate)
+    bool waitUntil(LockType& lock, const TimeWithDynamicClockType& timeout, const Functor& predicate)
     {
-        while (!predicate()) {
-            if (!waitUntil(lock, timeout))
-                return predicate();
-        }
-        return true;
+        return waitUntilUnchecked(lock, timeout, predicate);
     }
 
+    template<typename Functor>
+    bool waitUntil(Lock& lock, const TimeWithDynamicClockType& timeout, const Functor& predicate) WTF_REQUIRES_LOCK(lock)
+    {
+        return waitUntilUnchecked(lock, timeout, predicate);
+    }
+
     // Wait until the given predicate is satisfied. Returns true if it is satisfied in the end.
     // May return early due to timeout.
     template<typename LockType, typename Functor>
-    bool waitFor(
-        LockType& lock, Seconds relativeTimeout, const Functor& predicate)
+    bool waitFor(LockType& lock, Seconds relativeTimeout, const Functor& predicate)
     {
         return waitUntil(lock, MonotonicTime::now() + relativeTimeout, predicate);
     }
+
+    template<typename Functor>
+    bool waitFor(Lock& lock, Seconds relativeTimeout, const Functor& predicate) WTF_REQUIRES_LOCK(lock)
+    {
+        return waitUntil(lock, MonotonicTime::now() + relativeTimeout, predicate);
+    }
     
     template<typename LockType>
     bool waitFor(LockType& lock, Seconds relativeTimeout)
@@ -117,6 +111,11 @@
         return waitUntil(lock, MonotonicTime::now() + relativeTimeout);
     }
 
+    bool waitFor(Lock& lock, Seconds relativeTimeout) WTF_REQUIRES_LOCK(lock)
+    {
+        return waitUntil(lock, MonotonicTime::now() + relativeTimeout);
+    }
+
     template<typename LockType>
     void wait(LockType& lock)
     {
@@ -123,6 +122,11 @@
         waitUntil(lock, Time::infinity());
     }
 
+    void wait(Lock& lock) WTF_REQUIRES_LOCK(lock)
+    {
+        waitUntil(lock, Time::infinity());
+    }
+
     template<typename LockType, typename Functor>
     void wait(LockType& lock, const Functor& predicate)
     {
@@ -130,6 +134,13 @@
             wait(lock);
     }
 
+    template<typename Functor>
+    void wait(Lock& lock, const Functor& predicate) WTF_REQUIRES_LOCK(lock)
+    {
+        while (!predicate())
+            wait(lock);
+    }
+
     // Note that this method is extremely fast when nobody is waiting. It is not necessary to try to
     // avoid calling this method. This returns true if someone was actually woken up.
     bool notifyOne()
@@ -170,64 +181,47 @@
     }
     
 private:
-    Atomic<bool> m_hasWaiters { false };
-};
-
-// A condition variable type for Lock.
-// For predicates that access the guarded variables, use assertIsHeld(lock).
-class Condition final {
-    WTF_MAKE_NONCOPYABLE(Condition);
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    constexpr Condition() = default;
-
-    bool waitUntil(Lock& lock, const TimeWithDynamicClockType& timeout) WTF_REQUIRES_LOCK(lock)
+    template<typename LockType>
+    bool waitUntilUnchecked(LockType& lock, const TimeWithDynamicClockType& timeout) WTF_IGNORES_THREAD_SAFETY_ANALYSIS
     {
-        return m_condition.waitUntil(uncheckedCast(lock), timeout);
+        bool result;
+        if (timeout < timeout.nowWithSameClock()) {
+            lock.unlock();
+            result = false;
+        } else {
+            result = ParkingLot::parkConditionally(
+                &m_hasWaiters,
+                [this] () -> bool {
+                    // Let everyone know that we will be waiting. Do this while we hold the queue lock,
+                    // to prevent races with notifyOne().
+                    m_hasWaiters.store(true);
+                    return true;
+                },
+                [&lock] () WTF_IGNORES_THREAD_SAFETY_ANALYSIS {
+                    lock.unlock();
+                },
+                timeout).wasUnparked;
+        }
+        lock.lock();
+        return result;
     }
-    template<typename Functor>
-    bool waitUntil(Lock& lock, const TimeWithDynamicClockType& timeout, const Functor& predicate) WTF_REQUIRES_LOCK(lock)
+
+    template<typename LockType, typename Functor>
+    bool waitUntilUnchecked(LockType& lock, const TimeWithDynamicClockType& timeout, const Functor& predicate) WTF_IGNORES_THREAD_SAFETY_ANALYSIS
     {
-        return m_condition.waitUntil(uncheckedCast(lock), timeout, predicate);
+        while (!predicate()) {
+            if (!waitUntil(lock, timeout))
+                return predicate();
+        }
+        return true;
     }
-    template<typename Functor>
-    bool waitFor(Lock& lock, Seconds relativeTimeout, const Functor& predicate) WTF_REQUIRES_LOCK(lock)
-    {
-        return m_condition.waitFor(uncheckedCast(lock), relativeTimeout, predicate);
-    }
-    bool waitFor(Lock& lock, Seconds relativeTimeout) WTF_REQUIRES_LOCK(lock)
-    {
-        return m_condition.waitFor(uncheckedCast(lock), relativeTimeout);
-    }
-    void wait(Lock& lock) WTF_REQUIRES_LOCK(lock)
-    {
-        m_condition.wait(uncheckedCast(lock));
-    }
-    template<typename Functor>
-    void wait(Lock& lock, const Functor& predicate) WTF_REQUIRES_LOCK(lock)
-    {
-        m_condition.wait(uncheckedCast(lock), predicate);
-    }
-    bool notifyOne()
-    {
-        return m_condition.notifyOne();
-    }
-    void notifyAll()
-    {
-        m_condition.notifyAll();
-    }
-private:
-    static UncheckedLock& uncheckedCast(Lock& lock) { return static_cast<UncheckedLock&>(lock); }
-    UncheckedCondition m_condition;
+
+    Atomic<bool> m_hasWaiters { false };
 };
 
-using StaticUncheckedCondition = UncheckedCondition;
 using StaticCondition = Condition;
 
 } // namespace WTF
 
 using WTF::Condition;
-using WTF::UncheckedCondition;
 using WTF::StaticCondition;
-using WTF::StaticUncheckedCondition;
-

Modified: trunk/Source/WTF/wtf/Forward.h (278256 => 278257)


--- trunk/Source/WTF/wtf/Forward.h	2021-05-30 19:45:09 UTC (rev 278256)
+++ trunk/Source/WTF/wtf/Forward.h	2021-05-30 20:35:59 UTC (rev 278257)
@@ -49,7 +49,6 @@
 class TextStream;
 class UniquedStringImpl;
 class URL;
-class UncheckedLock;
 class WallTime;
 
 struct AnyThreadsAccessTraits;
@@ -154,7 +153,6 @@
 using WTF::TextPosition;
 using WTF::TextStream;
 using WTF::URL;
-using WTF::UncheckedLock;
 using WTF::UniqueRef;
 using WTF::Variant;
 using WTF::Vector;

Modified: trunk/Source/WTF/wtf/Lock.cpp (278256 => 278257)


--- trunk/Source/WTF/wtf/Lock.cpp	2021-05-30 19:45:09 UTC (rev 278256)
+++ trunk/Source/WTF/wtf/Lock.cpp	2021-05-30 20:35:59 UTC (rev 278257)
@@ -39,7 +39,7 @@
 
 static constexpr bool profileLockContention = false;
 
-void UncheckedLock::lockSlow()
+void Lock::lockSlow()
 {
     if (profileLockContention)
         STACK_SHOT_PROFILE(4, 2, 5);
@@ -46,7 +46,7 @@
     DefaultLockAlgorithm::lockSlow(m_byte);
 }
 
-void UncheckedLock::unlockSlow()
+void Lock::unlockSlow()
 {
     // Heap allocations are forbidden on the certain threads (e.g. audio rendering thread) for performance reasons so we need to
     // explicitly allow the following allocation(s). In some rare cases, the unlockSlow() algorith may cause allocations.
@@ -55,7 +55,7 @@
     DefaultLockAlgorithm::unlockSlow(m_byte, DefaultLockAlgorithm::Unfair);
 }
 
-void UncheckedLock::unlockFairlySlow()
+void Lock::unlockFairlySlow()
 {
     // Heap allocations are forbidden on the certain threads (e.g. audio rendering thread) for performance reasons so we need to
     // explicitly allow the following allocation(s). In some rare cases, the unlockSlow() algorith may cause allocations.
@@ -64,7 +64,7 @@
     DefaultLockAlgorithm::unlockSlow(m_byte, DefaultLockAlgorithm::Fair);
 }
 
-void UncheckedLock::safepointSlow()
+void Lock::safepointSlow()
 {
     DefaultLockAlgorithm::safepointSlow(m_byte);
 }

Modified: trunk/Source/WTF/wtf/Lock.h (278256 => 278257)


--- trunk/Source/WTF/wtf/Lock.h	2021-05-30 19:45:09 UTC (rev 278256)
+++ trunk/Source/WTF/wtf/Lock.h	2021-05-30 20:35:59 UTC (rev 278257)
@@ -50,29 +50,35 @@
 // at worst one call to unlock() per millisecond will do a direct hand-off to the thread that is at
 // the head of the queue. When there are collisions, each collision increases the fair unlock delay
 // by one millisecond in the worst case.
-class UncheckedLock {
-    WTF_MAKE_NONCOPYABLE(UncheckedLock);
+//
+// This lock type supports thread safety analysis.
+// To annotate a member variable or a global variable with thread ownership information,
+// use lock capability annotations defined in ThreadSafetyAnalysis.h.
+class WTF_CAPABILITY_LOCK Lock {
+    WTF_MAKE_NONCOPYABLE(Lock);
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    constexpr UncheckedLock() = default;
+    constexpr Lock() = default;
 
-    void lock()
+    void lock() WTF_ACQUIRES_LOCK()
     {
         if (UNLIKELY(!DefaultLockAlgorithm::lockFastAssumingZero(m_byte)))
             lockSlow();
     }
 
-    bool tryLock()
+    bool tryLock() WTF_ACQUIRES_LOCK_IF(true) // NOLINT: Intentional deviation to support std::scoped_lock.
     {
         return DefaultLockAlgorithm::tryLock(m_byte);
     }
 
     // Need this version for std::unique_lock.
-    bool try_lock()
+    bool try_lock() WTF_ACQUIRES_LOCK_IF(true)
     {
         return tryLock();
     }
 
+    WTF_EXPORT_PRIVATE bool tryLockWithTimeout(Seconds timeout) WTF_ACQUIRES_LOCK_IF(true);
+
     // Relinquish the lock. Either one of the threads that were waiting for the lock, or some other
     // thread that happens to be running, will be able to grab the lock. This bit of unfairness is
     // called barging, and we allow it because it maximizes throughput. However, we bound how unfair
@@ -81,7 +87,7 @@
     // we check if the last time that we did a fair unlock was more than roughly 1ms ago; if so, we
     // unlock fairly. Fairness matters most for long critical sections, and this virtually
     // guarantees that long critical sections always get a fair lock.
-    void unlock()
+    void unlock() WTF_RELEASES_LOCK()
     {
         if (UNLIKELY(!DefaultLockAlgorithm::unlockFastAssumingZero(m_byte)))
             unlockSlow();
@@ -92,7 +98,7 @@
     // to be fair anyway. However, if you plan to relock the lock right after unlocking and you want
     // to ensure that some other thread runs in the meantime, this is probably the function you
     // want.
-    void unlockFairly()
+    void unlockFairly() WTF_RELEASES_LOCK()
     {
         if (UNLIKELY(!DefaultLockAlgorithm::unlockFastAssumingZero(m_byte)))
             unlockFairlySlow();
@@ -134,45 +140,6 @@
     Atomic<uint8_t> m_byte { 0 };
 };
 
-// A lock type with support for thread safety analysis.
-// To annotate a member variable or a global variable with thread ownership information,
-// use lock capability annotations defined in ThreadSafetyAnalysis.h.
-//
-// Example:
-//   class MyValue : public ThreadSafeRefCounted<MyValue>
-//   {
-//   public:
-//       void setValue(int value) { Locker holdLock { m_lock }; m_value = value;  }
-//       void maybeSetOtherValue(int value)
-//       {
-//           if (!m_lock.tryLock())
-//              return;
-//           Locker locker { AdoptLock, m_otherLock };
-//           m_otherValue = value;
-//       }
-//   private:
-//       Lock m_lock;
-//       int m_value WTF_GUARDED_BY_LOCK(m_lock) { 77 };
-//       int m_otherValue WTF_GUARDED_BY_LOCK(m_lock) { 88 };
-//   };
-class WTF_CAPABILITY_LOCK Lock : UncheckedLock {
-    WTF_MAKE_NONCOPYABLE(Lock);
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    constexpr Lock() = default;
-    void lock() WTF_ACQUIRES_LOCK() { UncheckedLock::lock(); }
-    bool tryLock() WTF_ACQUIRES_LOCK_IF(true) { return UncheckedLock::tryLock(); }
-    bool try_lock() WTF_ACQUIRES_LOCK_IF(true) { return UncheckedLock::try_lock(); } // NOLINT: Intentional deviation to support std::scoped_lock.
-    WTF_EXPORT_PRIVATE bool tryLockWithTimeout(Seconds timeout) WTF_ACQUIRES_LOCK_IF(true);
-    void unlock() WTF_RELEASES_LOCK() { UncheckedLock::unlock(); }
-    void unlockFairly() WTF_RELEASES_LOCK() { UncheckedLock::unlockFairly(); }
-    void safepoint() { UncheckedLock::safepoint(); }
-    bool isHeld() const { return UncheckedLock::isHeld(); }
-    bool isLocked() const { return UncheckedLock::isLocked(); }
-    friend class Condition;
-    friend struct TestWebKitAPI::LockInspector;
-};
-
 // Asserts that the lock is held.
 // This can be used in cases where the annotations cannot be added to the function
 // declaration.
@@ -234,11 +201,8 @@
 Locker(AdoptLockTag, Lock&) -> Locker<Lock>;
 
 using LockHolder = Locker<Lock>;
-using UncheckedLockHolder = Locker<UncheckedLock>;
 
 } // namespace WTF
 
-using WTF::UncheckedLock;
 using WTF::Lock;
 using WTF::LockHolder;
-using WTF::UncheckedLockHolder;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to