[WTF] Remove XXXLockBase since constexpr constructor can initialize static variables...
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Dec 2017 03:52:09 +0000 (03:52 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Dec 2017 03:52:09 +0000 (03:52 +0000)
https://bugs.webkit.org/show_bug.cgi?id=180495

Reviewed by Mark Lam.

Very nice feature of C++11 is that constexpr constructor can initialize static global variables
without calling global constructors. We do not need to have XXXLockBase with derived XXXLock
class since StaticXXXLock can have constructors as long as it is constexpr.
We remove bunch of these classes, and set `XXXLock() = default;` explicitly for readability.
C++11's default constructor is constexpr as long as its member's default constructor / default
initializer is constexpr.

* wtf/Condition.h:
(WTF::ConditionBase::construct): Deleted.
(WTF::ConditionBase::waitUntil): Deleted.
(WTF::ConditionBase::waitFor): Deleted.
(WTF::ConditionBase::wait): Deleted.
(WTF::ConditionBase::notifyOne): Deleted.
(WTF::ConditionBase::notifyAll): Deleted.
(WTF::Condition::Condition): Deleted.
* wtf/CountingLock.h:
(WTF::CountingLock::CountingLock): Deleted.
(WTF::CountingLock::~CountingLock): Deleted.
* wtf/Lock.cpp:
(WTF::Lock::lockSlow):
(WTF::Lock::unlockSlow):
(WTF::Lock::unlockFairlySlow):
(WTF::Lock::safepointSlow):
(WTF::LockBase::lockSlow): Deleted.
(WTF::LockBase::unlockSlow): Deleted.
(WTF::LockBase::unlockFairlySlow): Deleted.
(WTF::LockBase::safepointSlow): Deleted.
* wtf/Lock.h:
(WTF::LockBase::construct): Deleted.
(WTF::LockBase::lock): Deleted.
(WTF::LockBase::tryLock): Deleted.
(WTF::LockBase::try_lock): Deleted.
(WTF::LockBase::unlock): Deleted.
(WTF::LockBase::unlockFairly): Deleted.
(WTF::LockBase::safepoint): Deleted.
(WTF::LockBase::isHeld const): Deleted.
(WTF::LockBase::isLocked const): Deleted.
(WTF::LockBase::isFullyReset const): Deleted.
(WTF::Lock::Lock): Deleted.
* wtf/ReadWriteLock.cpp:
(WTF::ReadWriteLock::readLock):
(WTF::ReadWriteLock::readUnlock):
(WTF::ReadWriteLock::writeLock):
(WTF::ReadWriteLock::writeUnlock):
(WTF::ReadWriteLockBase::construct): Deleted.
(WTF::ReadWriteLockBase::readLock): Deleted.
(WTF::ReadWriteLockBase::readUnlock): Deleted.
(WTF::ReadWriteLockBase::writeLock): Deleted.
(WTF::ReadWriteLockBase::writeUnlock): Deleted.
* wtf/ReadWriteLock.h:
(WTF::ReadWriteLock::read):
(WTF::ReadWriteLock::write):
(WTF::ReadWriteLockBase::ReadLock::tryLock): Deleted.
(WTF::ReadWriteLockBase::ReadLock::lock): Deleted.
(WTF::ReadWriteLockBase::ReadLock::unlock): Deleted.
(WTF::ReadWriteLockBase::WriteLock::tryLock): Deleted.
(WTF::ReadWriteLockBase::WriteLock::lock): Deleted.
(WTF::ReadWriteLockBase::WriteLock::unlock): Deleted.
(WTF::ReadWriteLockBase::read): Deleted.
(WTF::ReadWriteLockBase::write): Deleted.
(WTF::ReadWriteLock::ReadWriteLock): Deleted.
* wtf/RecursiveLockAdapter.h:
(WTF::RecursiveLockAdapter::RecursiveLockAdapter): Deleted.
* wtf/WordLock.cpp:
(WTF::WordLock::lockSlow):
(WTF::WordLock::unlockSlow):
(WTF::WordLockBase::lockSlow): Deleted.
(WTF::WordLockBase::unlockSlow): Deleted.
* wtf/WordLock.h:
(WTF::WordLockBase::lock): Deleted.
(WTF::WordLockBase::unlock): Deleted.
(WTF::WordLockBase::isHeld const): Deleted.
(WTF::WordLockBase::isLocked const): Deleted.
(WTF::WordLockBase::isFullyReset const): Deleted.
(WTF::WordLock::WordLock): Deleted.
* wtf/WorkQueue.cpp:

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

Source/WTF/ChangeLog
Source/WTF/wtf/Condition.h
Source/WTF/wtf/CountingLock.h
Source/WTF/wtf/Lock.cpp
Source/WTF/wtf/Lock.h
Source/WTF/wtf/ReadWriteLock.cpp
Source/WTF/wtf/ReadWriteLock.h
Source/WTF/wtf/RecursiveLockAdapter.h
Source/WTF/wtf/WordLock.cpp
Source/WTF/wtf/WordLock.h
Source/WTF/wtf/WorkQueue.cpp [changed mode: 0755->0644]

index 78c8d01..764f4fc 100644 (file)
@@ -1,3 +1,87 @@
+2017-12-06  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [WTF] Remove XXXLockBase since constexpr constructor can initialize static variables without calling global constructors
+        https://bugs.webkit.org/show_bug.cgi?id=180495
+
+        Reviewed by Mark Lam.
+
+        Very nice feature of C++11 is that constexpr constructor can initialize static global variables
+        without calling global constructors. We do not need to have XXXLockBase with derived XXXLock
+        class since StaticXXXLock can have constructors as long as it is constexpr.
+        We remove bunch of these classes, and set `XXXLock() = default;` explicitly for readability.
+        C++11's default constructor is constexpr as long as its member's default constructor / default
+        initializer is constexpr.
+
+        * wtf/Condition.h:
+        (WTF::ConditionBase::construct): Deleted.
+        (WTF::ConditionBase::waitUntil): Deleted.
+        (WTF::ConditionBase::waitFor): Deleted.
+        (WTF::ConditionBase::wait): Deleted.
+        (WTF::ConditionBase::notifyOne): Deleted.
+        (WTF::ConditionBase::notifyAll): Deleted.
+        (WTF::Condition::Condition): Deleted.
+        * wtf/CountingLock.h:
+        (WTF::CountingLock::CountingLock): Deleted.
+        (WTF::CountingLock::~CountingLock): Deleted.
+        * wtf/Lock.cpp:
+        (WTF::Lock::lockSlow):
+        (WTF::Lock::unlockSlow):
+        (WTF::Lock::unlockFairlySlow):
+        (WTF::Lock::safepointSlow):
+        (WTF::LockBase::lockSlow): Deleted.
+        (WTF::LockBase::unlockSlow): Deleted.
+        (WTF::LockBase::unlockFairlySlow): Deleted.
+        (WTF::LockBase::safepointSlow): Deleted.
+        * wtf/Lock.h:
+        (WTF::LockBase::construct): Deleted.
+        (WTF::LockBase::lock): Deleted.
+        (WTF::LockBase::tryLock): Deleted.
+        (WTF::LockBase::try_lock): Deleted.
+        (WTF::LockBase::unlock): Deleted.
+        (WTF::LockBase::unlockFairly): Deleted.
+        (WTF::LockBase::safepoint): Deleted.
+        (WTF::LockBase::isHeld const): Deleted.
+        (WTF::LockBase::isLocked const): Deleted.
+        (WTF::LockBase::isFullyReset const): Deleted.
+        (WTF::Lock::Lock): Deleted.
+        * wtf/ReadWriteLock.cpp:
+        (WTF::ReadWriteLock::readLock):
+        (WTF::ReadWriteLock::readUnlock):
+        (WTF::ReadWriteLock::writeLock):
+        (WTF::ReadWriteLock::writeUnlock):
+        (WTF::ReadWriteLockBase::construct): Deleted.
+        (WTF::ReadWriteLockBase::readLock): Deleted.
+        (WTF::ReadWriteLockBase::readUnlock): Deleted.
+        (WTF::ReadWriteLockBase::writeLock): Deleted.
+        (WTF::ReadWriteLockBase::writeUnlock): Deleted.
+        * wtf/ReadWriteLock.h:
+        (WTF::ReadWriteLock::read):
+        (WTF::ReadWriteLock::write):
+        (WTF::ReadWriteLockBase::ReadLock::tryLock): Deleted.
+        (WTF::ReadWriteLockBase::ReadLock::lock): Deleted.
+        (WTF::ReadWriteLockBase::ReadLock::unlock): Deleted.
+        (WTF::ReadWriteLockBase::WriteLock::tryLock): Deleted.
+        (WTF::ReadWriteLockBase::WriteLock::lock): Deleted.
+        (WTF::ReadWriteLockBase::WriteLock::unlock): Deleted.
+        (WTF::ReadWriteLockBase::read): Deleted.
+        (WTF::ReadWriteLockBase::write): Deleted.
+        (WTF::ReadWriteLock::ReadWriteLock): Deleted.
+        * wtf/RecursiveLockAdapter.h:
+        (WTF::RecursiveLockAdapter::RecursiveLockAdapter): Deleted.
+        * wtf/WordLock.cpp:
+        (WTF::WordLock::lockSlow):
+        (WTF::WordLock::unlockSlow):
+        (WTF::WordLockBase::lockSlow): Deleted.
+        (WTF::WordLockBase::unlockSlow): Deleted.
+        * wtf/WordLock.h:
+        (WTF::WordLockBase::lock): Deleted.
+        (WTF::WordLockBase::unlock): Deleted.
+        (WTF::WordLockBase::isHeld const): Deleted.
+        (WTF::WordLockBase::isLocked const): Deleted.
+        (WTF::WordLockBase::isFullyReset const): Deleted.
+        (WTF::WordLock::WordLock): Deleted.
+        * wtf/WorkQueue.cpp:
+
 2017-12-05  Stephan Szabo  <stephan.szabo@sony.com>
 
         Switch windows build to Visual Studio 2017
index fcf32c8..f533689 100644 (file)
@@ -41,20 +41,16 @@ namespace WTF {
 // one byte of memory. notifyOne() and 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.
-
-// This is a struct without a constructor or destructor so that it can be statically initialized.
-// Use Lock in instance variables.
-struct ConditionBase {
+class Condition {
+    WTF_MAKE_NONCOPYABLE(Condition);
+public:
     // 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.
-    typedef ParkingLot::Time Time;
-    
-    void construct()
-    {
-        m_hasWaiters.store(false);
-    }
-    
+    using Time = ParkingLot::Time;
+
+    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
     // notifyOne() or notifyAll(). Returns false if we woke up due to a timeout. Note that this form
@@ -174,19 +170,10 @@ struct ConditionBase {
     }
     
 private:
-    Atomic<bool> m_hasWaiters;
-};
-
-class Condition : public ConditionBase {
-    WTF_MAKE_NONCOPYABLE(Condition);
-public:
-    Condition()
-    {
-        construct();
-    }
+    Atomic<bool> m_hasWaiters { false };
 };
 
-typedef ConditionBase StaticCondition;
+using StaticCondition = Condition;
 
 } // namespace WTF
 
index d0e8353..0c471b9 100644 (file)
@@ -55,6 +55,9 @@ namespace WTF {
 // The latter is important for us because some GC paths are known to be sensitive to fences on ARM.
 
 class CountingLock {
+    WTF_MAKE_NONCOPYABLE(CountingLock);
+    WTF_MAKE_FAST_ALLOCATED;
+
     typedef unsigned LockType;
     
     static constexpr LockType isHeldBit = 1;
@@ -77,14 +80,7 @@ class CountingLock {
     typedef LockAlgorithm<LockType, isHeldBit, hasParkedBit, LockHooks> ExclusiveAlgorithm;
     
 public:
-    CountingLock()
-    {
-        m_word.storeRelaxed(0);
-    }
-    
-    ~CountingLock()
-    {
-    }
+    CountingLock() = default;
     
     bool tryLock()
     {
@@ -265,7 +261,7 @@ private:
         return result;
     }
     
-    Atomic<LockType> m_word;
+    Atomic<LockType> m_word { 0 };
 };
 
 } // namespace WTF
index e877fa0..7ff1005 100644 (file)
@@ -33,24 +33,24 @@ namespace WTF {
 
 static constexpr bool profileLockContention = false;
 
-void LockBase::lockSlow()
+void Lock::lockSlow()
 {
     if (profileLockContention)
         STACK_SHOT_PROFILE(4, 2, 5);
     DefaultLockAlgorithm::lockSlow(m_byte);
 }
 
-void LockBase::unlockSlow()
+void Lock::unlockSlow()
 {
     DefaultLockAlgorithm::unlockSlow(m_byte, DefaultLockAlgorithm::Unfair);
 }
 
-void LockBase::unlockFairlySlow()
+void Lock::unlockFairlySlow()
 {
     DefaultLockAlgorithm::unlockSlow(m_byte, DefaultLockAlgorithm::Fair);
 }
 
-void LockBase::safepointSlow()
+void Lock::safepointSlow()
 {
     DefaultLockAlgorithm::safepointSlow(m_byte);
 }
index 95a0ba6..631de96 100644 (file)
@@ -48,15 +48,12 @@ typedef LockAlgorithm<uint8_t, 1, 2> DefaultLockAlgorithm;
 // 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 Lock {
+    WTF_MAKE_NONCOPYABLE(Lock);
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    Lock() = default;
 
-// This is a struct without a constructor or destructor so that it can be statically initialized.
-// Use Lock in instance variables.
-struct LockBase {
-    void construct()
-    {
-        m_byte.store(0, std::memory_order_relaxed);
-    }
-    
     void lock()
     {
         if (UNLIKELY(!DefaultLockAlgorithm::lockFastAssumingZero(m_byte)))
@@ -132,21 +129,11 @@ private:
         return !m_byte.load();
     }
 
-    Atomic<uint8_t> m_byte;
-};
-
-class Lock : public LockBase {
-    WTF_MAKE_NONCOPYABLE(Lock);
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    Lock()
-    {
-        construct();
-    }
+    Atomic<uint8_t> m_byte { 0 };
 };
 
-typedef LockBase StaticLock;
-typedef Locker<LockBase> LockHolder;
+using StaticLock = Lock;
+using LockHolder = Locker<Lock>;
 
 } // namespace WTF
 
index 4622765..e0d7982 100644 (file)
 
 namespace WTF {
 
-void ReadWriteLockBase::construct()
-{
-    m_lock.construct();
-    m_cond.construct();
-    m_isWriteLocked = false;
-    m_numReaders = 0;
-    m_numWaitingWriters = 0;
-}
-
-void ReadWriteLockBase::readLock()
+void ReadWriteLock::readLock()
 {
     auto locker = holdLock(m_lock);
     while (m_isWriteLocked || m_numWaitingWriters)
@@ -47,7 +38,7 @@ void ReadWriteLockBase::readLock()
     m_numReaders++;
 }
 
-void ReadWriteLockBase::readUnlock()
+void ReadWriteLock::readUnlock()
 {
     auto locker = holdLock(m_lock);
     m_numReaders--;
@@ -55,7 +46,7 @@ void ReadWriteLockBase::readUnlock()
         m_cond.notifyAll();
 }
 
-void ReadWriteLockBase::writeLock()
+void ReadWriteLock::writeLock()
 {
     auto locker = holdLock(m_lock);
     while (m_isWriteLocked || m_numReaders) {
@@ -66,7 +57,7 @@ void ReadWriteLockBase::writeLock()
     m_isWriteLocked = true;
 }
 
-void ReadWriteLockBase::writeUnlock()
+void ReadWriteLock::writeUnlock()
 {
     auto locker = holdLock(m_lock);
     m_isWriteLocked = false;
index 953c4f2..67f3094 100644 (file)
@@ -35,9 +35,12 @@ namespace WTF {
 // read().unlock() if the work inside the critical section is short. The more cores participate in reading,
 // the longer the read critical section has to be for this locking scheme to be profitable.
 
-struct ReadWriteLockBase {
-    WTF_EXPORT_PRIVATE void construct();
-    
+class ReadWriteLock {
+    WTF_MAKE_NONCOPYABLE(ReadWriteLock);
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    ReadWriteLock() = default;
+
     // It's easiest to read lock like this:
     // 
     //     auto locker = holdLock(rwLock.read());
@@ -58,40 +61,31 @@ struct ReadWriteLockBase {
     WriteLock& write();
 
 private:
-    // These fields must work when zero-filled, so that StaticReadWriteLock works.
-    LockBase m_lock;
-    ConditionBase m_cond;
-    bool m_isWriteLocked;
-    unsigned m_numReaders;
-    unsigned m_numWaitingWriters;
+    Lock m_lock;
+    Condition m_cond;
+    bool m_isWriteLocked { false };
+    unsigned m_numReaders { 0 };
+    unsigned m_numWaitingWriters { 0 };
 };
 
-class ReadWriteLockBase::ReadLock : public ReadWriteLockBase {
+class ReadWriteLock::ReadLock : public ReadWriteLock {
 public:
     bool tryLock() { return false; }
     void lock() { readLock(); }
     void unlock() { readUnlock(); }
 };
 
-class ReadWriteLockBase::WriteLock : public ReadWriteLockBase {
+class ReadWriteLock::WriteLock : public ReadWriteLock {
 public:
     bool tryLock() { return false; }
     void lock() { writeLock(); }
     void unlock() { writeUnlock(); }
 };
     
-inline ReadWriteLockBase::ReadLock& ReadWriteLockBase::read() { return *static_cast<ReadLock*>(this); }
-inline ReadWriteLockBase::WriteLock& ReadWriteLockBase::write() { return *static_cast<WriteLock*>(this); }
-
-class ReadWriteLock : public ReadWriteLockBase {
-public:
-    ReadWriteLock()
-    {
-        construct();
-    }
-};
+inline ReadWriteLock::ReadLock& ReadWriteLock::read() { return *static_cast<ReadLock*>(this); }
+inline ReadWriteLock::WriteLock& ReadWriteLock::write() { return *static_cast<WriteLock*>(this); }
 
-typedef ReadWriteLockBase StaticReadWriteLock;
+using StaticReadWriteLock = ReadWriteLock;
 
 } // namespace WTF
 
index d4feb37..031384d 100644 (file)
@@ -32,10 +32,8 @@ namespace WTF {
 template<typename LockType>
 class RecursiveLockAdapter {
 public:
-    RecursiveLockAdapter()
-    {
-    }
-    
+    RecursiveLockAdapter() = default;
+
     void lock()
     {
         Thread& me = Thread::current();
index 9e8fb9b..0189e58 100644 (file)
@@ -76,7 +76,7 @@ ThreadData* myThreadData()
 
 } // anonymous namespace
 
-NEVER_INLINE void WordLockBase::lockSlow()
+NEVER_INLINE void WordLock::lockSlow()
 {
     unsigned spinCount = 0;
 
@@ -177,7 +177,7 @@ NEVER_INLINE void WordLockBase::lockSlow()
     }
 }
 
-NEVER_INLINE void WordLockBase::unlockSlow()
+NEVER_INLINE void WordLock::unlockSlow()
 {
     // The fast path can fail either because of spurious weak CAS failure, or because someone put a
     // thread on the queue, or the queue lock is held. If the queue lock is held, it can only be
index 52191ee..7a90f8b 100644 (file)
@@ -46,7 +46,12 @@ namespace WTF {
 // PrintStream uses this so that ParkingLot and Lock can use PrintStream. This means that if you
 // try to use dataLog to debug this code, you will have a bad time.
 
-struct WordLockBase {
+class WordLock {
+    WTF_MAKE_NONCOPYABLE(WordLock);
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    WordLock() = default;
+
     void lock()
     {
         if (LIKELY(m_word.compareExchangeWeak(0, isLockedBit, std::memory_order_acquire))) {
@@ -93,20 +98,11 @@ protected:
         return !m_word.load();
     }
 
-    Atomic<uintptr_t> m_word;
-};
-
-class WordLock : public WordLockBase {
-    WTF_MAKE_NONCOPYABLE(WordLock);
-public:
-    WordLock()
-    {
-        m_word.store(0, std::memory_order_relaxed);
-    }
+    Atomic<uintptr_t> m_word { 0 };
 };
 
-typedef WordLockBase StaticWordLock;
-typedef Locker<WordLockBase> WordLockHolder;
+using StaticWordLock = WordLock;
+using WordLockHolder = Locker<WordLock>;
 
 } // namespace WTF
 
old mode 100755 (executable)
new mode 100644 (file)