Update lock benchmarks
authorjfbastien@apple.com <jfbastien@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 28 Jul 2017 02:17:37 +0000 (02:17 +0000)
committerjfbastien@apple.com <jfbastien@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 28 Jul 2017 02:17:37 +0000 (02:17 +0000)
https://bugs.webkit.org/show_bug.cgi?id=174907

Reviewed by Filip Pizlo.

* benchmarks/ConditionSpeedTest.cpp:
(main):
* benchmarks/LockFairnessTest.cpp:
* benchmarks/LockSpeedTest.cpp:
* benchmarks/ToyLocks.h:

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

Source/WTF/ChangeLog
Source/WTF/benchmarks/ConditionSpeedTest.cpp
Source/WTF/benchmarks/LockFairnessTest.cpp
Source/WTF/benchmarks/LockSpeedTest.cpp
Source/WTF/benchmarks/ToyLocks.h

index 4be36e7..a815cff 100644 (file)
@@ -1,3 +1,16 @@
+2017-07-27  JF Bastien  <jfbastien@apple.com>
+
+        Update lock benchmarks
+        https://bugs.webkit.org/show_bug.cgi?id=174907
+
+        Reviewed by Filip Pizlo.
+
+        * benchmarks/ConditionSpeedTest.cpp:
+        (main):
+        * benchmarks/LockFairnessTest.cpp:
+        * benchmarks/LockSpeedTest.cpp:
+        * benchmarks/ToyLocks.h:
+
 2017-07-26  Brian Burg  <bburg@apple.com>
 
         Remove WEB_TIMING feature flag
index 4c3bd54..3c8b9a6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  */
 
 // On Mac, you can build this like so:
-// clang++ -o ConditionSpeedTest Source/WTF/benchmarks/ConditionSpeedTest.cpp -O3 -W -ISource/WTF -LWebKitBuild/Release -lWTF -framework Foundation -licucore -std=c++11
+// xcrun clang++ -o ConditionSpeedTest Source/WTF/benchmarks/ConditionSpeedTest.cpp -O3 -W -ISource/WTF -ISource/WTF/icu -LWebKitBuild/Release -lWTF -framework Foundation -licucore -std=c++14 -fvisibility=hidden
 
 #include "config.h"
 
+#include "ToyLocks.h"
+#include <condition_variable>
 #include <mutex>
 #include <thread>
+#include <type_traits>
 #include <unistd.h>
 #include <wtf/Condition.h>
 #include <wtf/CurrentTime.h>
@@ -57,13 +60,20 @@ NO_RETURN void usage()
     exit(1);
 }
 
-template<typename Functor, typename ConditionType, typename LockType>
-void wait(ConditionType& condition, LockType& lock, const Functor& predicate)
+template<typename Functor, typename ConditionType, typename LockType, typename std::enable_if<!std::is_same<ConditionType, std::condition_variable>::value>::type* = nullptr>
+void wait(ConditionType& condition, LockType& lock, std::unique_lock<LockType>&, const Functor& predicate)
 {
     while (!predicate())
         condition.wait(lock);
 }
 
+template<typename Functor, typename ConditionType, typename LockType, typename std::enable_if<std::is_same<ConditionType, std::condition_variable>::value>::type* = nullptr>
+void wait(ConditionType& condition, LockType&, std::unique_lock<LockType>& locker, const Functor& predicate)
+{
+    while (!predicate())
+        condition.wait(locker);
+}
+
 template<typename LockType, typename ConditionType, typename NotifyFunctor, typename NotifyAllFunctor>
 void runTest(
     unsigned numProducers,
@@ -95,7 +105,7 @@ void runTest(
                     {
                         std::unique_lock<LockType> locker(lock);
                         wait(
-                            emptyCondition, lock,
+                            emptyCondition, lock, locker,
                             [&] () {
                                 if (verbose)
                                     dataLog(toString(Thread::current(), ": Checking consumption predicate with shouldContinue = ", shouldContinue, ", queue.size() == ", queue.size(), "\n"));
@@ -126,7 +136,7 @@ void runTest(
                     {
                         std::unique_lock<LockType> locker(lock);
                         wait(
-                            fullCondition, lock,
+                            fullCondition, lock, locker,
                             [&] () {
                                 if (verbose)
                                     dataLog(toString(Thread::current(), ": Checking production predicate with shouldContinue = ", shouldContinue, ", queue.size() == ", queue.size(), "\n"));
@@ -150,8 +160,8 @@ void runTest(
     }
     notifyAll(emptyCondition);
 
-    for (ThreadIdentifier threadIdentifier : consumerThreads)
-        waitForThreadCompletion(threadIdentifier);
+    for (auto& threadIdentifier : consumerThreads)
+        threadIdentifier->waitForCompletion();
 
     RELEASE_ASSERT(numProducers * numMessagesPerProducer == received.size());
     std::sort(received.begin(), received.end());
@@ -199,7 +209,7 @@ int main(int argc, char** argv)
     if (!strcmp(argv[1], "lock") || !strcmp(argv[1], "all")) {
         runBenchmark<Lock, Condition>(
             "WTF Lock NotifyOne",
-            [&] (Condition& condition, bool mustNotify) {
+            [&] (Condition& condition, bool) {
                 condition.notifyOne();
             },
             [&] (Condition& condition) {
@@ -217,22 +227,22 @@ int main(int argc, char** argv)
         didRun = true;
     }
     if (!strcmp(argv[1], "mutex") || !strcmp(argv[1], "all")) {
-        runBenchmark<Mutex, ThreadCondition>(
-            "Platform Mutex NotifyOne",
-            [&] (ThreadCondition& condition, bool mustNotify) {
-                condition.signal();
+        runBenchmark<std::mutex, std::condition_variable>(
+            "std::mutex NotifyOne",
+            [&] (std::condition_variable& condition, bool) {
+                condition.notify_one();
             },
-            [&] (ThreadCondition& condition) {
-                condition.broadcast();
+            [&] (std::condition_variable& condition) {
+                condition.notify_all();
             });
-        runBenchmark<Mutex, ThreadCondition>(
-            "Platform Mutex NotifyAll",
-            [&] (ThreadCondition& condition, bool mustNotify) {
+        runBenchmark<std::mutex, std::condition_variable>(
+            "std::mutex NotifyAll",
+            [&] (std::condition_variable& condition, bool mustNotify) {
                 if (mustNotify)
-                    condition.broadcast();
+                    condition.notify_all();
             },
-            [&] (ThreadCondition& condition) {
-                condition.broadcast();
+            [&] (std::condition_variable& condition) {
+                condition.notify_all();
             });
         didRun = true;
     }
index 68ce84c..0c34653 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -24,7 +24,7 @@
  */
 
 // On Mac, you can build this like so:
-// xcrun clang++ -o LockFairnessTest Source/WTF/benchmarks/LockFairnessTest.cpp -O3 -W -ISource/WTF -ISource/WTF/benchmarks -LWebKitBuild/Release -lWTF -framework Foundation -licucore -std=c++11 -fvisibility=hidden
+// xcrun clang++ -o LockFairnessTest Source/WTF/benchmarks/LockFairnessTest.cpp -O3 -W -ISource/WTF -ISource/WTF/icu -ISource/WTF/benchmarks -LWebKitBuild/Release -lWTF -framework Foundation -licucore -std=c++14 -fvisibility=hidden
 
 #include "config.h"
 
@@ -32,6 +32,7 @@
 #include <thread>
 #include <unistd.h>
 #include <wtf/CommaPrinter.h>
+#include <wtf/Compiler.h>
 #include <wtf/CurrentTime.h>
 #include <wtf/DataLog.h>
 #include <wtf/HashMap.h>
@@ -48,7 +49,7 @@ namespace {
 
 NO_RETURN void usage()
 {
-    printf("Usage: LockFairnessTest yieldspinlock|pausespinlock|wordlock|lock|barginglock|bargingwordlock|thunderlock|thunderwordlock|cascadelock|cascadewordlockhandofflock|mutex|all <num threads> <seconds per test> <microseconds in critical section>\n");
+    printf("Usage: LockFairnessTest yieldspinlock|pausespinlock|wordlock|lock|barginglock|bargingwordlock|thunderlock|thunderwordlock|cascadelock|cascadewordlockhandofflock|unfairlock|mutex|all <num threads> <seconds per test> <microseconds in critical section>\n");
     exit(1);
 }
 
index 0d6235d..419ff5e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -24,7 +24,7 @@
  */
 
 // On Mac, you can build this like so:
-// xcrun clang++ -o LockSpeedTest Source/WTF/benchmarks/LockSpeedTest.cpp -O3 -W -ISource/WTF -ISource/WTF/benchmarks -LWebKitBuild/Release -lWTF -framework Foundation -licucore -std=c++11 -fvisibility=hidden
+// xcrun clang++ -o LockSpeedTest Source/WTF/benchmarks/LockSpeedTest.cpp -O3 -W -ISource/WTF -ISource/WTF/icu -ISource/WTF/benchmarks -LWebKitBuild/Release -lWTF -framework Foundation -licucore -std=c++14 -fvisibility=hidden
 
 #include "config.h"
 
@@ -53,7 +53,7 @@ double secondsPerTest;
     
 NO_RETURN void usage()
 {
-    printf("Usage: LockSpeedTest yieldspinlock|pausespinlock|wordlock|lock|barginglock|bargingwordlock|thunderlock|thunderwordlock|cascadelock|cascadewordlock|handofflock|mutex|all <num thread groups> <num threads per group> <work per critical section> <work between critical sections> <spin limit> <seconds per test>\n");
+    printf("Usage: LockSpeedTest yieldspinlock|pausespinlock|wordlock|lock|barginglock|bargingwordlock|thunderlock|thunderwordlock|cascadelock|cascadewordlock|handofflock|unfairlock|mutex|all <num thread groups> <num threads per group> <work per critical section> <work between critical sections> <spin limit> <seconds per test>\n");
     exit(1);
 }
 
index 090ad96..bacad2e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #ifndef ToyLocks_h
 #define ToyLocks_h
 
+#include <mutex>
 #include <thread>
 #include <wtf/Atomics.h>
 #include <wtf/Lock.h>
 #include <wtf/ParkingLot.h>
 #include <wtf/WordLock.h>
 
+#if __has_include(<os/lock.h>)
+#include <os/lock.h>
+#define HAS_UNFAIR_LOCK
+#endif
+
 #if defined(EXTRA_LOCKS) && EXTRA_LOCKS
 #include <synchronic>
 #endif
@@ -467,6 +473,21 @@ private:
     Atomic<unsigned> m_state;
 };
 
+#ifdef HAS_UNFAIR_LOCK
+class UnfairLock {
+    os_unfair_lock l = OS_UNFAIR_LOCK_INIT;
+public:
+    void lock()
+    {
+        os_unfair_lock_lock(&l);
+    }
+    void unlock()
+    {
+        os_unfair_lock_unlock(&l);
+    }
+};
+#endif
+
 template<typename Benchmark>
 void runEverything(const char* what)
 {
@@ -498,8 +519,12 @@ void runEverything(const char* what)
         Benchmark::template run<CascadeLock<uint32_t>>("WordCascadeLock");
     if (!strcmp(what, "handofflock") || !strcmp(what, "all"))
         Benchmark::template run<HandoffLock>("HandoffLock");
+#ifdef HAS_UNFAIR_LOCK
+    if (!strcmp(what, "unfairlock") || !strcmp(what, "all"))
+        Benchmark::template run<UnfairLock>("UnfairLock");
+#endif
     if (!strcmp(what, "mutex") || !strcmp(what, "all"))
-        Benchmark::template run<Mutex>("PlatformMutex");
+        Benchmark::template run<std::mutex>("std::mutex");
 }
 
 } // anonymous namespace