WTF should have a compact Condition object to use with Lock
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 13 Aug 2015 20:42:11 +0000 (20:42 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 13 Aug 2015 20:42:11 +0000 (20:42 +0000)
commit57085663827bc8e58230b4938912f9395dd18f52
tree8d1648d70f250b98a9f46db7742039e73fb0da8a
parent643c0e538bc4763c8875ba1aea789dfc45913246
WTF should have a compact Condition object to use with Lock
https://bugs.webkit.org/show_bug.cgi?id=147986

Reviewed by Geoffrey Garen.

Source/WTF:

Adds a condition variable implementation based on ParkingLot, called simply WTF::Condition.
It can be used with WTF::Lock or actually any lock implementation. It should even work with
WTF::SpinLock, WTF::Mutex, or std::mutex. Best of all, Condition only requires one byte.

ParkingLot almost contained all of the functionality needed to implemenet wait/notify. We
could have implemented Condition using a 32-bit (or even 64-bit) version that protects
against a notify that happens just before we park. But, this changes the ParkingLot API to
give us the ability to run some code between when ParkingLot enqueues the current thread
and when it actually sleeps. This callback is called with no locks held, so it can call
unlock() on any kind of lock, so long as that lock's unlock() method doesn't recurse into
ParkingLot::parkConditionally(). That seems unlikely; unlock() is more likely to call
ParkingLot::unparkOne() or unparkAll(). WTF::Lock will never call parkConditionally()
inside unlock(), so WTF::Lock is definitely appropriate for use with Condition.

Condition supports most of the API that std::condition_variable supports. It does some
things to try to reduce footgun potential. The preferred timeout form is waitUntil() which
takes an absolute time from the steady_clock. The only relative timeout form also takes a
predicate callback, so it's impossible to write the subtly incorrect
"while (...) wait_for(...)" idiom.

This patch doesn't actually introduce any uses of WTF::Condition other than the unit tests.
I'll start switching code over to using WTF::Condition in another patch.

* WTF.vcxproj/WTF.vcxproj:
* WTF.xcodeproj/project.pbxproj:
* wtf/CMakeLists.txt:
* wtf/Condition.h: Added.
(WTF::Condition::Condition):
(WTF::Condition::waitUntil):
(WTF::Condition::waitFor):
(WTF::Condition::wait):
(WTF::Condition::notifyOne):
(WTF::Condition::notifyAll):
* wtf/Lock.cpp:
(WTF::LockBase::unlockSlow): Make this useful assertion be a release assertion. It catches cases where you unlock the lock even though you don't hold it.
* wtf/ParkingLot.cpp:
(WTF::ParkingLot::parkConditionally): Add the beforeSleep() callback.
(WTF::ParkingLot::unparkOne):
* wtf/ParkingLot.h:
(WTF::ParkingLot::compareAndPark):

Tools:

Add a test for WTF::Condition.

* TestWebKitAPI/CMakeLists.txt:
* TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj:
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WTF/Condition.cpp: Added.
(TestWebKitAPI::TEST):
* TestWebKitAPI/Tests/WTF/Lock.cpp:
(TestWebKitAPI::runLockTest): Change the name of the thread.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@188400 268f45cc-cd09-0410-ab3c-d52691b4dbfc
14 files changed:
Source/WTF/ChangeLog
Source/WTF/WTF.vcxproj/WTF.vcxproj
Source/WTF/WTF.xcodeproj/project.pbxproj
Source/WTF/wtf/CMakeLists.txt
Source/WTF/wtf/Condition.h [new file with mode: 0644]
Source/WTF/wtf/Lock.cpp
Source/WTF/wtf/ParkingLot.cpp
Source/WTF/wtf/ParkingLot.h
Tools/ChangeLog
Tools/TestWebKitAPI/CMakeLists.txt
Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WTF/Condition.cpp [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WTF/Lock.cpp