22 #include <boost/optional.hpp> 23 #include <boost/thread/shared_mutex.hpp> 33 using namespace folly;
44 template <
typename Lock>
59 lock.lock_shared(token3);
60 lock.unlock_shared(token3);
61 lock.unlock_shared(token2);
62 lock.unlock_shared(token1);
67 lock.lock_shared(token1);
68 lock.lock_shared(token2);
69 lock.unlock_shared(token1);
70 lock.unlock_shared(token2);
73 lock.unlock_and_lock_shared(token1);
74 lock.lock_shared(token2);
75 lock.unlock_shared(token2);
76 lock.unlock_shared(token1);
80 runBasicTest<SharedMutexReadPriority>();
81 runBasicTest<SharedMutexWritePriority>();
82 runBasicTest<SharedMutexSuppressTSAN>();
85 template <
typename Lock>
92 typename Lock::WriteHolder holder(lock);
97 typename Lock::WriteHolder holder2(
std::move(holder));
102 typename Lock::WriteHolder holder3(
nullptr);
108 typename Lock::UpgradeHolder holder4(
std::move(holder3));
113 lock.unlock_shared(token);
116 typename Lock::WriteHolder holder5(
std::move(holder4));
121 typename Lock::ReadHolder holder6(
std::move(holder5));
126 lock.unlock_shared(token);
130 typename Lock::WriteHolder holder(lock);
135 typename Lock::ReadHolder holder(lock);
136 typename Lock::ReadHolder holder2(lock);
137 typename Lock::UpgradeHolder holder3(lock);
141 typename Lock::UpgradeHolder holder(lock);
142 typename Lock::ReadHolder holder2(lock);
143 typename Lock::ReadHolder holder3(
std::move(holder));
148 runBasicHoldersTest<SharedMutexReadPriority>();
149 runBasicHoldersTest<SharedMutexWritePriority>();
150 runBasicHoldersTest<SharedMutexSuppressTSAN>();
153 template <
typename Lock>
157 vector<SharedMutexToken>
tokens;
158 for (
int i = 0;
i < 1000; ++
i) {
159 tokens.emplace_back();
162 for (
auto& token : tokens) {
163 lock.unlock_shared(token);
173 runManyReadLocksTestWithTokens<SharedMutexReadPriority>();
174 runManyReadLocksTestWithTokens<SharedMutexWritePriority>();
175 runManyReadLocksTestWithTokens<SharedMutexSuppressTSAN>();
178 template <
typename Lock>
182 for (
int i = 0;
i < 1000; ++
i) {
185 for (
int i = 0;
i < 1000; ++
i) {
186 lock.unlock_shared();
196 runManyReadLocksTestWithoutTokens<SharedMutexReadPriority>();
197 runManyReadLocksTestWithoutTokens<SharedMutexWritePriority>();
198 runManyReadLocksTestWithoutTokens<SharedMutexSuppressTSAN>();
201 template <
typename Lock>
209 EXPECT_TRUE(lock.try_lock_shared_for(milliseconds(0)));
210 lock.unlock_shared();
211 EXPECT_TRUE(lock.try_lock_shared_for(milliseconds(-1)));
212 lock.unlock_shared();
217 lock.unlock_shared();
222 lock.unlock_shared();
226 runTimeoutInPastTest<SharedMutexReadPriority>();
227 runTimeoutInPastTest<SharedMutexWritePriority>();
228 runTimeoutInPastTest<SharedMutexSuppressTSAN>();
231 template <
class Func>
234 for (
int tries = 0; tries < 100; ++tries) {
238 if (elapsed > expectedDuration - expectedDuration / 4 &&
239 elapsed < expectedDuration + expectedDuration / 4) {
246 template <
typename Lock>
254 typename Lock::Token token;
255 EXPECT_FALSE(lock.try_lock_shared_for(milliseconds(10), token));
258 EXPECT_FALSE(lock.try_lock_upgrade_for(milliseconds(10)));
264 typename Lock::Token token;
276 typename Lock::Token token;
296 lock.unlock_shared();
299 for (
int p = 0; p < 8; ++p) {
304 for (
int p = 0; p < 8; ++p) {
305 typename Lock::ReadHolder holder1(lock);
306 typename Lock::ReadHolder holder2(lock);
307 typename Lock::ReadHolder holder3(lock);
313 runFailingTryTimeoutTest<SharedMutexReadPriority>();
314 runFailingTryTimeoutTest<SharedMutexWritePriority>();
315 runFailingTryTimeoutTest<SharedMutexSuppressTSAN>();
318 template <
typename Lock>
321 typename Lock::Token token1;
322 typename Lock::Token token2;
327 lock.unlock_shared(token1);
328 lock.unlock_upgrade();
331 lock.unlock_upgrade_and_lock();
336 lock.unlock_upgrade_and_lock_shared(token1);
338 lock.unlock_upgrade_and_lock_shared(token2);
339 lock.unlock_shared(token1);
340 lock.unlock_shared(token2);
343 lock.unlock_and_lock_upgrade();
345 lock.unlock_upgrade();
346 lock.unlock_shared(token1);
350 runBasicUpgradeTest<SharedMutexReadPriority>();
351 runBasicUpgradeTest<SharedMutexWritePriority>();
352 runBasicUpgradeTest<SharedMutexSuppressTSAN>();
360 bool exclusiveAcquired =
false;
361 auto writer = thread([&] {
363 exclusiveAcquired =
true;
389 auto writer = thread([&] {
407 template <
typename T>
412 template <
typename T>
417 template <
typename T>
419 lockable->lock_shared(token);
422 template <
typename T>
424 lockable->unlock_shared(token);
429 template <
typename T>
434 template <
typename T>
439 template <
typename T>
441 lockable->lock_shared();
444 template <
typename T>
446 lockable->unlock_shared();
451 template <
typename T>
456 template <
typename T>
461 template <
typename T>
466 template <
typename T>
476 pthread_rwlock_init(&lock_,
nullptr);
480 pthread_rwlock_destroy(&lock_);
484 pthread_rwlock_wrlock(&lock_);
488 pthread_rwlock_unlock(&lock_);
492 pthread_rwlock_rdlock(&lock_);
496 pthread_rwlock_unlock(&lock_);
504 pthread_mutex_init(&lock_,
nullptr);
508 pthread_mutex_destroy(&lock_);
512 pthread_mutex_lock(&lock_);
516 pthread_mutex_unlock(&lock_);
520 pthread_mutex_lock(&lock_);
524 pthread_mutex_unlock(&lock_);
528 template <
template <
typename>
class Atom,
typename Lock,
typename Locker>
534 int valueProtectedByLock = 10;
537 Atom<bool> go(
false);
538 Atom<bool>* goPtr = &go;
539 vector<thread>
threads(numThreads);
542 for (
size_t t = 0;
t < numThreads; ++
t) {
545 Lock*
lock = useSeparateLocks ? &privateLock : &globalLock;
547 while (!goPtr->load()) {
550 for (
size_t op =
t;
op < numOps;
op += numThreads) {
555 auto copy = valueProtectedByLock;
564 for (
auto& thr : threads) {
571 runContendedReaders<atomic, RWSpinLock, Locker>(
572 numOps, numThreads, useSeparateLocks);
577 runContendedReaders<atomic, SharedMutexWritePriority, TokenLocker>(
578 numOps, numThreads, useSeparateLocks);
583 runContendedReaders<atomic, SharedMutexWritePriority, Locker>(
584 numOps, numThreads, useSeparateLocks);
589 runContendedReaders<atomic, SharedMutexReadPriority, TokenLocker>(
590 numOps, numThreads, useSeparateLocks);
595 runContendedReaders<atomic, SharedMutexReadPriority, Locker>(
596 numOps, numThreads, useSeparateLocks);
601 runContendedReaders<atomic, RWTicketSpinLock64, Locker>(
602 numOps, numThreads, useSeparateLocks);
607 runContendedReaders<atomic, boost::shared_mutex, Locker>(
608 numOps, numThreads, useSeparateLocks);
613 runContendedReaders<atomic, PosixRWLock, Locker>(
614 numOps, numThreads, useSeparateLocks);
617 template <
template <
typename>
class Atom,
typename Lock,
typename Locker>
621 double writeFraction,
622 bool useSeparateLocks) {
626 int valueProtectedByLock = 0;
629 Atom<bool> go(
false);
630 Atom<bool>* goPtr = &go;
631 vector<thread>
threads(numThreads);
634 for (
size_t t = 0;
t < numThreads; ++
t) {
636 struct drand48_data buffer;
637 srand48_r(
t, &buffer);
638 long writeThreshold = writeFraction * 0x7fffffff;
640 Lock*
lock = useSeparateLocks ? &privateLock : &globalLock;
642 while (!goPtr->load()) {
645 for (
size_t op =
t;
op < numOps;
op += numThreads) {
647 lrand48_r(&buffer, &randVal);
648 bool writeOp = randVal < writeThreshold;
651 if (!useSeparateLocks) {
652 ++valueProtectedByLock;
657 auto v = valueProtectedByLock;
667 for (
auto& thr : threads) {
675 double writeFraction,
676 bool useSeparateLocks) {
677 runMixed<atomic, RWSpinLock, Locker>(
678 numOps, numThreads, writeFraction, useSeparateLocks);
684 double writeFraction,
685 bool useSeparateLocks) {
686 runMixed<atomic, SharedMutexWritePriority, TokenLocker>(
687 numOps, numThreads, writeFraction, useSeparateLocks);
693 double writeFraction,
694 bool useSeparateLocks) {
695 runMixed<atomic, SharedMutexWritePriority, Locker>(
696 numOps, numThreads, writeFraction, useSeparateLocks);
702 double writeFraction,
703 bool useSeparateLocks) {
704 runMixed<atomic, SharedMutexReadPriority, TokenLocker>(
705 numOps, numThreads, writeFraction, useSeparateLocks);
711 double writeFraction,
712 bool useSeparateLocks) {
713 runMixed<atomic, SharedMutexReadPriority, Locker>(
714 numOps, numThreads, writeFraction, useSeparateLocks);
720 double writeFraction,
721 bool useSeparateLocks) {
722 runMixed<atomic, RWTicketSpinLock64, Locker>(
723 numOps, numThreads, writeFraction, useSeparateLocks);
729 double writeFraction,
730 bool useSeparateLocks) {
731 runMixed<atomic, boost::shared_mutex, Locker>(
732 numOps, numThreads, writeFraction, useSeparateLocks);
738 double writeFraction,
739 bool useSeparateLocks) {
740 runMixed<atomic, PosixRWLock, Locker>(
741 numOps, numThreads, writeFraction, useSeparateLocks);
747 double writeFraction,
748 bool useSeparateLocks) {
749 runMixed<atomic, PosixMutex, Locker>(
750 numOps, numThreads, writeFraction, useSeparateLocks);
753 template <
typename Lock,
template <
typename>
class Atom>
756 Atom<int> globalExclusiveCount(0);
757 Atom<int> globalUpgradeCount(0);
758 Atom<int> globalSharedCount(0);
760 Atom<bool> go(
false);
763 Atom<int>* globalExclusiveCountPtr = &globalExclusiveCount;
764 Atom<int>* globalUpgradeCountPtr = &globalUpgradeCount;
765 Atom<int>* globalSharedCountPtr = &globalSharedCount;
766 Atom<bool>* goPtr = &go;
768 vector<thread>
threads(numThreads);
771 for (
size_t t = 0;
t < numThreads; ++
t) {
773 struct drand48_data buffer;
774 srand48_r(
t, &buffer);
776 bool exclusive =
false;
777 bool upgrade =
false;
779 bool ourGlobalTokenUsed =
false;
783 vector<SharedMutexToken> privateTokens;
785 while (!goPtr->load()) {
788 for (
size_t op =
t;
op < numOps;
op += numThreads) {
791 lrand48_r(&buffer, &randVal);
792 randVal = (long)((randVal * (
uint64_t)1000) / 0x7fffffff);
796 EXPECT_EQ(1, globalExclusiveCountPtr->load(memory_order_acquire));
797 EXPECT_EQ(0, globalUpgradeCountPtr->load(memory_order_acquire));
798 EXPECT_EQ(0, globalSharedCountPtr->load(memory_order_acquire));
801 EXPECT_EQ(0, globalExclusiveCountPtr->load(memory_order_acquire));
802 EXPECT_EQ(1, globalUpgradeCountPtr->load(memory_order_acquire));
805 EXPECT_EQ(0, globalExclusiveCountPtr->load(memory_order_acquire));
806 EXPECT_TRUE(globalSharedCountPtr->load(memory_order_acquire) > 0);
816 if (randVal < 100 && privateTokens.size() > 0) {
817 auto i = randVal % privateTokens.size();
818 privateLock.unlock_shared(privateTokens[
i]);
819 privateTokens.erase(privateTokens.begin() +
i);
822 privateLock.lock_shared(token);
823 privateTokens.push_back(token);
832 --*globalExclusiveCountPtr;
835 }
else if (randVal < 700) {
836 globalLock.unlock_and_lock_shared();
837 ++*globalSharedCountPtr;
839 }
else if (randVal < 900) {
840 globalLock.unlock_and_lock_shared(ourGlobalToken);
841 ++*globalSharedCountPtr;
843 ourGlobalTokenUsed =
true;
845 globalLock.unlock_and_lock_upgrade();
846 ++*globalUpgradeCountPtr;
849 }
else if (upgrade) {
851 --*globalUpgradeCountPtr;
853 globalLock.unlock_upgrade();
854 }
else if (randVal < 700) {
855 globalLock.unlock_upgrade_and_lock_shared();
856 ++*globalSharedCountPtr;
858 }
else if (randVal < 900) {
859 globalLock.unlock_upgrade_and_lock_shared(ourGlobalToken);
860 ++*globalSharedCountPtr;
862 ourGlobalTokenUsed =
true;
864 globalLock.unlock_upgrade_and_lock();
865 ++*globalExclusiveCountPtr;
870 --*globalSharedCountPtr;
871 if (ourGlobalTokenUsed) {
872 globalLock.unlock_shared(ourGlobalToken);
873 ourGlobalTokenUsed =
false;
875 globalLock.unlock_shared();
877 }
else if (randVal < 400) {
881 auto dt = microseconds(10 * (randVal - 100));
884 globalLock.lock_shared(ourGlobalToken);
886 }
else if (randVal < 500) {
887 shared = globalLock.try_lock_shared(ourGlobalToken);
888 }
else if (randVal < 600) {
889 shared = globalLock.try_lock_shared_for(dt, ourGlobalToken);
890 }
else if (randVal < 800) {
891 shared = globalLock.try_lock_shared_until(
895 ourGlobalTokenUsed =
true;
896 ++*globalSharedCountPtr;
898 }
else if (randVal < 800) {
900 auto dt = microseconds(10 * (randVal - 100));
902 globalLock.lock_shared();
904 }
else if (randVal < 500) {
905 shared = globalLock.try_lock_shared();
906 }
else if (randVal < 600) {
907 shared = globalLock.try_lock_shared_for(dt);
908 }
else if (randVal < 800) {
913 ++*globalSharedCountPtr;
915 }
else if (randVal < 900) {
917 globalLock.lock_upgrade();
919 ++*globalUpgradeCountPtr;
924 auto dt = microseconds(100 * (randVal - 910));
929 }
else if (randVal < 500) {
930 exclusive = globalLock.try_lock();
931 }
else if (randVal < 600) {
932 exclusive = globalLock.try_lock_for(dt);
933 }
else if (randVal < 700) {
939 ++*globalExclusiveCountPtr;
945 --*globalExclusiveCountPtr;
949 --*globalUpgradeCountPtr;
950 globalLock.unlock_upgrade();
953 --*globalSharedCountPtr;
954 if (ourGlobalTokenUsed) {
955 globalLock.unlock_shared(ourGlobalToken);
956 ourGlobalTokenUsed =
false;
958 globalLock.unlock_shared();
961 for (
auto& token : privateTokens) {
962 privateLock.unlock_shared(token);
969 for (
auto& thr : threads) {
975 for (
int pass = 0; pass < 3; ++pass) {
977 runContendedReaders<DeterministicAtomic, DSharedMutexReadPriority, Locker>(
983 for (
int pass = 0; pass < 3; ++pass) {
985 runContendedReaders<DeterministicAtomic, DSharedMutexWritePriority, Locker>(
991 for (
int pass = 0; pass < 10; ++pass) {
992 runContendedReaders<atomic, SharedMutexReadPriority, Locker>(
998 for (
int pass = 0; pass < 10; ++pass) {
999 runContendedReaders<atomic, SharedMutexWritePriority, Locker>(
1005 for (
int pass = 0; pass < 3; ++pass) {
1007 runContendedReaders<DeterministicAtomic, DSharedMutexReadPriority, Locker>(
1013 for (
int pass = 0; pass < 3; ++pass) {
1015 runContendedReaders<DeterministicAtomic, DSharedMutexWritePriority, Locker>(
1021 for (
int pass = 0; pass < 10; ++pass) {
1022 runContendedReaders<atomic, SharedMutexReadPriority, TokenLocker>(
1028 for (
int pass = 0; pass < 10; ++pass) {
1029 runContendedReaders<atomic, SharedMutexWritePriority, TokenLocker>(
1035 for (
int pass = 0; pass < 3; ++pass) {
1037 runMixed<DeterministicAtomic, DSharedMutexReadPriority, Locker>(
1038 1000, 3, 0.1,
false);
1043 for (
int pass = 0; pass < 3; ++pass) {
1045 runMixed<DeterministicAtomic, DSharedMutexWritePriority, Locker>(
1046 1000, 3, 0.1,
false);
1051 for (
int pass = 0; pass < 5; ++pass) {
1052 runMixed<atomic, SharedMutexReadPriority, TokenLocker>(
1053 10000, 32, 0.1,
false);
1058 for (
int pass = 0; pass < 5; ++pass) {
1059 runMixed<atomic, SharedMutexWritePriority, TokenLocker>(
1060 10000, 32, 0.1,
false);
1065 for (
int pass = 0; pass < 1; ++pass) {
1067 runMixed<DeterministicAtomic, DSharedMutexReadPriority, TokenLocker>(
1068 1000, 10, 0.9,
false);
1073 for (
int pass = 0; pass < 1; ++pass) {
1075 runMixed<DeterministicAtomic, DSharedMutexWritePriority, TokenLocker>(
1076 1000, 10, 0.9,
false);
1081 for (
int pass = 0; pass < 10; ++pass) {
1083 runMixed<DeterministicAtomic, DSharedMutexWritePriority, TokenLocker>(
1084 1000, 3, 1.0,
false);
1099 runMixed<atomic, SharedMutexReadPriority, TokenLocker>(
1106 runMixed<atomic, SharedMutexWritePriority, TokenLocker>(
1112 for (
int pass = 0; pass < 5; ++pass) {
1114 runAllAndValidate<DSharedMutexReadPriority, DeterministicAtomic>(1000, 8);
1121 for (
int pass = 0; pass < 5; ++pass) {
1123 runAllAndValidate<DSharedMutexWritePriority, DeterministicAtomic>(1000, 8);
1128 for (
int pass = 0; pass < 5; ++pass) {
1129 runAllAndValidate<SharedMutexReadPriority, atomic>(100000, 32);
1136 for (
int pass = 0; pass < 5; ++pass) {
1137 runAllAndValidate<SharedMutexWritePriority, atomic>(100000, 32);
1142 boost::optional<boost::optional<SharedMutexToken>>)
1148 template <
typename Lock,
template <
typename>
class Atom>
1151 double preWriteFraction,
1152 double preUpgradeFraction,
1153 size_t numSendingThreads,
1154 size_t numReceivingThreads) {
1157 auto queuePtr = &queue;
1159 Atom<bool> go(
false);
1161 Atom<int> pendingSenders(numSendingThreads);
1162 auto pendingSendersPtr = &pendingSenders;
1163 vector<thread>
threads(numSendingThreads + numReceivingThreads);
1166 for (
size_t t = 0;
t < threads.size(); ++
t) {
1168 if (
t >= numSendingThreads) {
1170 typename decltype(queue)::value_type elem;
1172 queuePtr->blockingRead(elem);
1175 queuePtr->blockingWrite(
std::move(elem));
1179 globalLock.unlock_shared(**elem);
1181 globalLock.unlock_shared();
1188 struct drand48_data buffer;
1189 srand48_r(
t, &buffer);
1191 while (!goPtr->load()) {
1194 for (
size_t op =
t;
op < numOps;
op += numSendingThreads) {
1195 long unscaledRandVal;
1196 lrand48_r(&buffer, &unscaledRandVal);
1199 double randVal = ((double)unscaledRandVal) / 0x7fffffff;
1202 bool useToken = randVal >= 0.5;
1203 randVal = (randVal - (useToken ? 0.5 : 0.0)) * 2;
1205 boost::optional<SharedMutexToken> maybeToken;
1209 if (randVal < preWriteFraction) {
1211 globalLock.unlock_and_lock_shared(token);
1212 }
else if (randVal < preWriteFraction + preUpgradeFraction / 2) {
1213 globalLock.lock_upgrade();
1214 globalLock.unlock_upgrade_and_lock_shared(token);
1215 }
else if (randVal < preWriteFraction + preUpgradeFraction) {
1216 globalLock.lock_upgrade();
1217 globalLock.unlock_upgrade_and_lock();
1218 globalLock.unlock_and_lock_shared(token);
1220 globalLock.lock_shared(token);
1224 if (randVal < preWriteFraction) {
1226 globalLock.unlock_and_lock_shared();
1227 }
else if (randVal < preWriteFraction + preUpgradeFraction / 2) {
1228 globalLock.lock_upgrade();
1229 globalLock.unlock_upgrade_and_lock_shared();
1230 }
else if (randVal < preWriteFraction + preUpgradeFraction) {
1231 globalLock.lock_upgrade();
1232 globalLock.unlock_upgrade_and_lock();
1233 globalLock.unlock_and_lock_shared();
1235 globalLock.lock_shared();
1241 queuePtr->blockingWrite(maybeToken);
1243 if (--*pendingSendersPtr == 0) {
1251 for (
auto& thr : threads) {
1260 for (
int pass = 0; pass < 1; ++pass) {
1262 runRemoteUnlock<DSharedMutexWritePriority, DeterministicAtomic>(
1263 500, 0.1, 0.1, 5, 5);
1268 for (
int pass = 0; pass < 1; ++pass) {
1270 runRemoteUnlock<DSharedMutexReadPriority, DeterministicAtomic>(
1271 500, 0.1, 0.1, 5, 5);
1279 for (
int pass = 0; pass < 10; ++pass) {
1280 runRemoteUnlock<SharedMutexWritePriority, atomic>(100000, 0.1, 0.1, 5, 5);
1289 runRemoteUnlock<SharedMutexReadPriority, atomic>(100000, 0.1, 0.1, 5, 5);
1294 for (
size_t i = 0;
i < n; ++
i) {
1301 template <
typename Lock,
template <
typename>
class Atom = atomic>
1305 pair<Lock, char[56]>
locks[3];
1310 auto availPtr = &avail;
1311 Atom<bool> go(
false);
1315 locks[0].first.lock();
1316 locks[1].first.lock();
1317 locks[2].first.lock_shared();
1322 while (!goPtr->load()) {
1325 for (
size_t i = 0;
i < numRounds; ++
i) {
1326 locks[
i % 3].first.unlock();
1327 locks[(
i + 2) % 3].
first.lock();
1333 while (!goPtr->load()) {
1336 for (
size_t i = 0;
i < numRounds; ++
i) {
1337 locks[
i % 3].first.lock_shared();
1339 locks[(
i + 2) % 3].
first.unlock_shared();
1343 while (avail.load() < 2) {
1349 for (
auto& thr : threads) {
1352 locks[numRounds % 3].first.unlock();
1353 locks[(numRounds + 1) % 3].
first.unlock();
1354 locks[(numRounds + 2) % 3].
first.unlock_shared();
1358 runPingPong<RWSpinLock>(n / scale, burnCount);
1362 runPingPong<SharedMutexWritePriority>(n / scale, burnCount);
1366 runPingPong<SharedMutexReadPriority>(n / scale, burnCount);
1370 runPingPong<RWTicketSpinLock64>(n / scale, burnCount);
1374 runPingPong<boost::shared_mutex>(n / scale, burnCount);
1378 runPingPong<PosixRWLock>(n / scale, burnCount);
1385 for (
int pass = 0; pass < 1; ++pass) {
1387 runPingPong<DSharedMutexWritePriority, DeterministicAtomic>(500, 0);
1392 for (
int pass = 0; pass < 1; ++pass) {
1394 runPingPong<DSharedMutexReadPriority, DeterministicAtomic>(500, 0);
1402 for (
int pass = 0; pass < 1; ++pass) {
1403 runPingPong<SharedMutexWritePriority, atomic>(50000, 0);
1408 for (
int pass = 0; pass < 1; ++pass) {
1409 runPingPong<SharedMutexReadPriority, atomic>(50000, 0);
1418 for (
size_t n = 0; n < iters; ++n) {
1428 for (
size_t n = 0; n < iters; ++n) {
1435 #define BENCH_BASE(...) FB_VA_GLUE(BENCHMARK_NAMED_PARAM, (__VA_ARGS__)) 1436 #define BENCH_REL(...) FB_VA_GLUE(BENCHMARK_RELATIVE_NAMED_PARAM, (__VA_ARGS__)) 1453 BENCH_REL(shmtx_wr_pri_reads, 2thread, 2, false)
1454 BENCH_REL(shmtx_w_bare_reads, 2thread, 2, false)
1455 BENCH_REL(shmtx_rd_pri_reads, 2thread, 2, false)
1456 BENCH_REL(shmtx_r_bare_reads, 2thread, 2, false)
1457 BENCH_REL(folly_ticket_reads, 2thread, 2, false)
1458 BENCH_REL(boost_shared_reads, 2thread, 2, false)
1459 BENCH_REL(pthrd_rwlock_reads, 2thread, 2, false)
1460 BENCHMARK_DRAW_LINE();
1461 BENCH_BASE(folly_rwspin_reads, 4thread, 4, false)
1462 BENCH_REL(shmtx_wr_pri_reads, 4thread, 4, false)
1463 BENCH_REL(shmtx_w_bare_reads, 4thread, 4, false)
1464 BENCH_REL(shmtx_rd_pri_reads, 4thread, 4, false)
1465 BENCH_REL(shmtx_r_bare_reads, 4thread, 4, false)
1466 BENCH_REL(folly_ticket_reads, 4thread, 4, false)
1467 BENCH_REL(boost_shared_reads, 4thread, 4, false)
1468 BENCH_REL(pthrd_rwlock_reads, 4thread, 4, false)
1469 BENCHMARK_DRAW_LINE();
1470 BENCH_BASE(folly_rwspin_reads, 8thread, 8, false)
1471 BENCH_REL(shmtx_wr_pri_reads, 8thread, 8, false)
1472 BENCH_REL(shmtx_w_bare_reads, 8thread, 8, false)
1473 BENCH_REL(shmtx_rd_pri_reads, 8thread, 8, false)
1474 BENCH_REL(shmtx_r_bare_reads, 8thread, 8, false)
1475 BENCH_REL(folly_ticket_reads, 8thread, 8, false)
1476 BENCH_REL(boost_shared_reads, 8thread, 8, false)
1477 BENCH_REL(pthrd_rwlock_reads, 8thread, 8, false)
1478 BENCHMARK_DRAW_LINE();
1479 BENCH_BASE(folly_rwspin_reads, 16thread, 16, false)
1480 BENCH_REL(shmtx_wr_pri_reads, 16thread, 16, false)
1481 BENCH_REL(shmtx_w_bare_reads, 16thread, 16, false)
1482 BENCH_REL(shmtx_rd_pri_reads, 16thread, 16, false)
1483 BENCH_REL(shmtx_r_bare_reads, 16thread, 16, false)
1484 BENCH_REL(folly_ticket_reads, 16thread, 16, false)
1485 BENCH_REL(boost_shared_reads, 16thread, 16, false)
1486 BENCH_REL(pthrd_rwlock_reads, 16thread, 16, false)
1487 BENCHMARK_DRAW_LINE();
1488 BENCH_BASE(folly_rwspin_reads, 32thread, 32, false)
1489 BENCH_REL(shmtx_wr_pri_reads, 32thread, 32, false)
1490 BENCH_REL(shmtx_w_bare_reads, 32thread, 32, false)
1491 BENCH_REL(shmtx_rd_pri_reads, 32thread, 32, false)
1492 BENCH_REL(shmtx_r_bare_reads, 32thread, 32, false)
1493 BENCH_REL(folly_ticket_reads, 32thread, 32, false)
1494 BENCH_REL(boost_shared_reads, 32thread, 32, false)
1495 BENCH_REL(pthrd_rwlock_reads, 32thread, 32, false)
1496 BENCHMARK_DRAW_LINE();
1497 BENCH_BASE(folly_rwspin_reads, 64thread, 64, false)
1498 BENCH_REL(shmtx_wr_pri_reads, 64thread, 64, false)
1499 BENCH_REL(shmtx_w_bare_reads, 64thread, 64, false)
1500 BENCH_REL(shmtx_rd_pri_reads, 64thread, 64, false)
1501 BENCH_REL(shmtx_r_bare_reads, 64thread, 64, false)
1502 BENCH_REL(folly_ticket_reads, 64thread, 64, false)
1503 BENCH_REL(boost_shared_reads, 64thread, 64, false)
1504 BENCH_REL(pthrd_rwlock_reads, 64thread, 64, false)
1511 BENCHMARK_DRAW_LINE();
1512 BENCHMARK_DRAW_LINE();
1520 BENCHMARK_DRAW_LINE();
1521 BENCH_BASE(folly_rwspin, 2thread_all_write, 2, 1.0, false)
1522 BENCH_REL(shmtx_wr_pri, 2thread_all_write, 2, 1.0, false)
1523 BENCH_REL(shmtx_rd_pri, 2thread_all_write, 2, 1.0, false)
1524 BENCH_REL(folly_ticket, 2thread_all_write, 2, 1.0, false)
1525 BENCH_REL(boost_shared, 2thread_all_write, 2, 1.0, false)
1526 BENCH_REL(pthrd_rwlock, 2thread_all_write, 2, 1.0, false)
1527 BENCH_REL(pthrd_mutex_, 2thread_all_write, 2, 1.0, false)
1528 BENCHMARK_DRAW_LINE();
1529 BENCH_BASE(folly_rwspin, 4thread_all_write, 4, 1.0, false)
1530 BENCH_REL(shmtx_wr_pri, 4thread_all_write, 4, 1.0, false)
1531 BENCH_REL(shmtx_rd_pri, 4thread_all_write, 4, 1.0, false)
1532 BENCH_REL(folly_ticket, 4thread_all_write, 4, 1.0, false)
1533 BENCH_REL(boost_shared, 4thread_all_write, 4, 1.0, false)
1534 BENCH_REL(pthrd_rwlock, 4thread_all_write, 4, 1.0, false)
1535 BENCH_REL(pthrd_mutex_, 4thread_all_write, 4, 1.0, false)
1536 BENCHMARK_DRAW_LINE();
1537 BENCH_BASE(folly_rwspin, 8thread_all_write, 8, 1.0, false)
1538 BENCH_REL(shmtx_wr_pri, 8thread_all_write, 8, 1.0, false)
1539 BENCH_REL(shmtx_rd_pri, 8thread_all_write, 8, 1.0, false)
1540 BENCH_REL(folly_ticket, 8thread_all_write, 8, 1.0, false)
1541 BENCH_REL(boost_shared, 8thread_all_write, 8, 1.0, false)
1542 BENCH_REL(pthrd_rwlock, 8thread_all_write, 8, 1.0, false)
1543 BENCH_REL(pthrd_mutex_, 8thread_all_write, 8, 1.0, false)
1544 BENCHMARK_DRAW_LINE();
1545 BENCH_BASE(folly_rwspin, 16thread_all_write, 16, 1.0, false)
1546 BENCH_REL(shmtx_wr_pri, 16thread_all_write, 16, 1.0, false)
1547 BENCH_REL(shmtx_rd_pri, 16thread_all_write, 16, 1.0, false)
1548 BENCH_REL(folly_ticket, 16thread_all_write, 16, 1.0, false)
1549 BENCH_REL(boost_shared, 16thread_all_write, 16, 1.0, false)
1550 BENCH_REL(pthrd_rwlock, 16thread_all_write, 16, 1.0, false)
1551 BENCH_REL(pthrd_mutex_, 16thread_all_write, 16, 1.0, false)
1552 BENCHMARK_DRAW_LINE();
1553 BENCH_BASE(folly_rwspin, 32thread_all_write, 32, 1.0, false)
1554 BENCH_REL(shmtx_wr_pri, 32thread_all_write, 32, 1.0, false)
1555 BENCH_REL(shmtx_rd_pri, 32thread_all_write, 32, 1.0, false)
1556 BENCH_REL(folly_ticket, 32thread_all_write, 32, 1.0, false)
1557 BENCH_REL(boost_shared, 32thread_all_write, 32, 1.0, false)
1558 BENCH_REL(pthrd_rwlock, 32thread_all_write, 32, 1.0, false)
1559 BENCH_REL(pthrd_mutex_, 32thread_all_write, 32, 1.0, false)
1560 BENCHMARK_DRAW_LINE();
1561 BENCH_BASE(folly_rwspin, 64thread_all_write, 64, 1.0, false)
1562 BENCH_REL(shmtx_wr_pri, 64thread_all_write, 64, 1.0, false)
1563 BENCH_REL(shmtx_rd_pri, 64thread_all_write, 64, 1.0, false)
1564 BENCH_REL(folly_ticket, 64thread_all_write, 64, 1.0, false)
1565 BENCH_REL(boost_shared, 64thread_all_write, 64, 1.0, false)
1566 BENCH_REL(pthrd_rwlock, 64thread_all_write, 64, 1.0, false)
1567 BENCH_REL(pthrd_mutex_, 64thread_all_write, 64, 1.0, false)
1571 BENCHMARK_DRAW_LINE();
1572 BENCHMARK_DRAW_LINE();
1573 BENCH_BASE(folly_rwspin, 1thread_10pct_write, 1, 0.10, false)
1574 BENCH_REL(shmtx_wr_pri, 1thread_10pct_write, 1, 0.10, false)
1575 BENCH_REL(shmtx_rd_pri, 1thread_10pct_write, 1, 0.10, false)
1576 BENCH_REL(folly_ticket, 1thread_10pct_write, 1, 0.10, false)
1577 BENCH_REL(boost_shared, 1thread_10pct_write, 1, 0.10, false)
1578 BENCH_REL(pthrd_rwlock, 1thread_10pct_write, 1, 0.10, false)
1579 BENCHMARK_DRAW_LINE();
1580 BENCH_BASE(folly_rwspin, 2thread_10pct_write, 2, 0.10, false)
1581 BENCH_REL(shmtx_wr_pri, 2thread_10pct_write, 2, 0.10, false)
1582 BENCH_REL(shmtx_rd_pri, 2thread_10pct_write, 2, 0.10, false)
1583 BENCH_REL(folly_ticket, 2thread_10pct_write, 2, 0.10, false)
1584 BENCH_REL(boost_shared, 2thread_10pct_write, 2, 0.10, false)
1585 BENCH_REL(pthrd_rwlock, 2thread_10pct_write, 2, 0.10, false)
1586 BENCHMARK_DRAW_LINE();
1587 BENCH_BASE(folly_rwspin, 4thread_10pct_write, 4, 0.10, false)
1588 BENCH_REL(shmtx_wr_pri, 4thread_10pct_write, 4, 0.10, false)
1589 BENCH_REL(shmtx_rd_pri, 4thread_10pct_write, 4, 0.10, false)
1590 BENCH_REL(folly_ticket, 4thread_10pct_write, 4, 0.10, false)
1591 BENCH_REL(boost_shared, 4thread_10pct_write, 4, 0.10, false)
1592 BENCH_REL(pthrd_rwlock, 4thread_10pct_write, 4, 0.10, false)
1593 BENCHMARK_DRAW_LINE();
1594 BENCH_BASE(folly_rwspin, 8thread_10pct_write, 8, 0.10, false)
1595 BENCH_REL(shmtx_wr_pri, 8thread_10pct_write, 8, 0.10, false)
1596 BENCH_REL(shmtx_rd_pri, 8thread_10pct_write, 8, 0.10, false)
1597 BENCH_REL(folly_ticket, 8thread_10pct_write, 8, 0.10, false)
1598 BENCH_REL(boost_shared, 8thread_10pct_write, 8, 0.10, false)
1599 BENCH_REL(pthrd_rwlock, 8thread_10pct_write, 8, 0.10, false)
1600 BENCHMARK_DRAW_LINE();
1601 BENCH_BASE(folly_rwspin, 16thread_10pct_write, 16, 0.10, false)
1602 BENCH_REL(shmtx_wr_pri, 16thread_10pct_write, 16, 0.10, false)
1603 BENCH_REL(shmtx_rd_pri, 16thread_10pct_write, 16, 0.10, false)
1604 BENCH_REL(folly_ticket, 16thread_10pct_write, 16, 0.10, false)
1605 BENCH_REL(boost_shared, 16thread_10pct_write, 16, 0.10, false)
1606 BENCH_REL(pthrd_rwlock, 16thread_10pct_write, 16, 0.10, false)
1607 BENCHMARK_DRAW_LINE();
1608 BENCH_BASE(folly_rwspin, 32thread_10pct_write, 32, 0.10, false)
1609 BENCH_REL(shmtx_wr_pri, 32thread_10pct_write, 32, 0.10, false)
1610 BENCH_REL(shmtx_rd_pri, 32thread_10pct_write, 32, 0.10, false)
1611 BENCH_REL(folly_ticket, 32thread_10pct_write, 32, 0.10, false)
1612 BENCH_REL(boost_shared, 32thread_10pct_write, 32, 0.10, false)
1613 BENCH_REL(pthrd_rwlock, 32thread_10pct_write, 32, 0.10, false)
1614 BENCHMARK_DRAW_LINE();
1615 BENCH_BASE(folly_rwspin, 64thread_10pct_write, 64, 0.10, false)
1616 BENCH_REL(shmtx_wr_pri, 64thread_10pct_write, 64, 0.10, false)
1617 BENCH_REL(shmtx_rd_pri, 64thread_10pct_write, 64, 0.10, false)
1618 BENCH_REL(folly_ticket, 64thread_10pct_write, 64, 0.10, false)
1619 BENCH_REL(boost_shared, 64thread_10pct_write, 64, 0.10, false)
1620 BENCH_REL(pthrd_rwlock, 64thread_10pct_write, 64, 0.10, false)
1625 BENCHMARK_DRAW_LINE();
1626 BENCHMARK_DRAW_LINE();
1627 BENCH_BASE(folly_rwspin, 1thread_1pct_write, 1, 0.01, false)
1628 BENCH_REL(shmtx_wr_pri, 1thread_1pct_write, 1, 0.01, false)
1632 BENCH_REL(folly_ticket, 1thread_1pct_write, 1, 0.01, false)
1633 BENCH_REL(boost_shared, 1thread_1pct_write, 1, 0.01, false)
1634 BENCH_REL(pthrd_rwlock, 1thread_1pct_write, 1, 0.01, false)
1635 BENCHMARK_DRAW_LINE();
1636 BENCH_BASE(folly_rwspin, 2thread_1pct_write, 2, 0.01, false)
1637 BENCH_REL(shmtx_wr_pri, 2thread_1pct_write, 2, 0.01, false)
1638 BENCH_REL(shmtx_w_bare, 2thread_1pct_write, 2, 0.01, false)
1639 BENCH_REL(shmtx_rd_pri, 2thread_1pct_write, 2, 0.01, false)
1640 BENCH_REL(shmtx_r_bare, 2thread_1pct_write, 2, 0.01, false)
1641 BENCH_REL(folly_ticket, 2thread_1pct_write, 2, 0.01, false)
1642 BENCH_REL(boost_shared, 2thread_1pct_write, 2, 0.01, false)
1643 BENCH_REL(pthrd_rwlock, 2thread_1pct_write, 2, 0.01, false)
1644 BENCHMARK_DRAW_LINE();
1645 BENCH_BASE(folly_rwspin, 4thread_1pct_write, 4, 0.01, false)
1646 BENCH_REL(shmtx_wr_pri, 4thread_1pct_write, 4, 0.01, false)
1647 BENCH_REL(shmtx_w_bare, 4thread_1pct_write, 4, 0.01, false)
1648 BENCH_REL(shmtx_rd_pri, 4thread_1pct_write, 4, 0.01, false)
1649 BENCH_REL(shmtx_r_bare, 4thread_1pct_write, 4, 0.01, false)
1650 BENCH_REL(folly_ticket, 4thread_1pct_write, 4, 0.01, false)
1651 BENCH_REL(boost_shared, 4thread_1pct_write, 4, 0.01, false)
1652 BENCH_REL(pthrd_rwlock, 4thread_1pct_write, 4, 0.01, false)
1653 BENCHMARK_DRAW_LINE();
1654 BENCH_BASE(folly_rwspin, 8thread_1pct_write, 8, 0.01, false)
1655 BENCH_REL(shmtx_wr_pri, 8thread_1pct_write, 8, 0.01, false)
1656 BENCH_REL(shmtx_w_bare, 8thread_1pct_write, 8, 0.01, false)
1657 BENCH_REL(shmtx_rd_pri, 8thread_1pct_write, 8, 0.01, false)
1658 BENCH_REL(shmtx_r_bare, 8thread_1pct_write, 8, 0.01, false)
1659 BENCH_REL(folly_ticket, 8thread_1pct_write, 8, 0.01, false)
1660 BENCH_REL(boost_shared, 8thread_1pct_write, 8, 0.01, false)
1661 BENCH_REL(pthrd_rwlock, 8thread_1pct_write, 8, 0.01, false)
1662 BENCHMARK_DRAW_LINE();
1663 BENCH_BASE(folly_rwspin, 16thread_1pct_write, 16, 0.01, false)
1664 BENCH_REL(shmtx_wr_pri, 16thread_1pct_write, 16, 0.01, false)
1665 BENCH_REL(shmtx_w_bare, 16thread_1pct_write, 16, 0.01, false)
1666 BENCH_REL(shmtx_rd_pri, 16thread_1pct_write, 16, 0.01, false)
1667 BENCH_REL(shmtx_r_bare, 16thread_1pct_write, 16, 0.01, false)
1668 BENCH_REL(folly_ticket, 16thread_1pct_write, 16, 0.01, false)
1669 BENCH_REL(boost_shared, 16thread_1pct_write, 16, 0.01, false)
1670 BENCH_REL(pthrd_rwlock, 16thread_1pct_write, 16, 0.01, false)
1671 BENCHMARK_DRAW_LINE();
1672 BENCH_BASE(folly_rwspin, 32thread_1pct_write, 32, 0.01, false)
1673 BENCH_REL(shmtx_wr_pri, 32thread_1pct_write, 32, 0.01, false)
1674 BENCH_REL(shmtx_w_bare, 32thread_1pct_write, 32, 0.01, false)
1675 BENCH_REL(shmtx_rd_pri, 32thread_1pct_write, 32, 0.01, false)
1676 BENCH_REL(shmtx_r_bare, 32thread_1pct_write, 32, 0.01, false)
1677 BENCH_REL(folly_ticket, 32thread_1pct_write, 32, 0.01, false)
1678 BENCH_REL(boost_shared, 32thread_1pct_write, 32, 0.01, false)
1679 BENCH_REL(pthrd_rwlock, 32thread_1pct_write, 32, 0.01, false)
1680 BENCHMARK_DRAW_LINE();
1681 BENCH_BASE(folly_rwspin, 64thread_1pct_write, 64, 0.01, false)
1682 BENCH_REL(shmtx_wr_pri, 64thread_1pct_write, 64, 0.01, false)
1683 BENCH_REL(shmtx_w_bare, 64thread_1pct_write, 64, 0.01, false)
1684 BENCH_REL(shmtx_rd_pri, 64thread_1pct_write, 64, 0.01, false)
1685 BENCH_REL(shmtx_r_bare, 64thread_1pct_write, 64, 0.01, false)
1686 BENCH_REL(folly_ticket, 64thread_1pct_write, 64, 0.01, false)
1687 BENCH_REL(boost_shared, 64thread_1pct_write, 64, 0.01, false)
1688 BENCH_REL(pthrd_rwlock, 64thread_1pct_write, 64, 0.01, false)
1693 BENCHMARK_DRAW_LINE();
1694 BENCH_BASE(folly_rwspin, 2thr_2lock_50pct_write, 2, 0.50, true)
1695 BENCH_REL(shmtx_wr_pri, 2thr_2lock_50pct_write, 2, 0.50, true)
1696 BENCH_REL(shmtx_rd_pri, 2thr_2lock_50pct_write, 2, 0.50, true)
1698 BENCH_REL(shmtx_wr_pri, 4thr_4lock_50pct_write, 4, 0.50, true)
1699 BENCH_REL(shmtx_rd_pri, 4thr_4lock_50pct_write, 4, 0.50, true)
1700 BENCH_BASE(folly_rwspin, 8thr_8lock_50pct_write, 8, 0.50, true)
1701 BENCH_REL(shmtx_wr_pri, 8thr_8lock_50pct_write, 8, 0.50, true)
1702 BENCH_REL(shmtx_rd_pri, 8thr_8lock_50pct_write, 8, 0.50, true)
1703 BENCH_BASE(folly_rwspin, 16thr_16lock_50pct_write, 16, 0.50, true)
1704 BENCH_REL(shmtx_wr_pri, 16thr_16lock_50pct_write, 16, 0.50, true)
1705 BENCH_REL(shmtx_rd_pri, 16thr_16lock_50pct_write, 16, 0.50, true)
1706 BENCH_BASE(folly_rwspin, 32thr_32lock_50pct_write, 32, 0.50, true)
1707 BENCH_REL(shmtx_wr_pri, 32thr_32lock_50pct_write, 32, 0.50, true)
1708 BENCH_REL(shmtx_rd_pri, 32thr_32lock_50pct_write, 32, 0.50, true)
1709 BENCH_BASE(folly_rwspin, 64thr_64lock_50pct_write, 64, 0.50, true)
1710 BENCH_REL(shmtx_wr_pri, 64thr_64lock_50pct_write, 64, 0.50, true)
1711 BENCH_REL(shmtx_rd_pri, 64thr_64lock_50pct_write, 64, 0.50, true)
1712 BENCHMARK_DRAW_LINE();
1713 BENCH_BASE(folly_rwspin, 2thr_2lock_10pct_write, 2, 0.10, true)
1714 BENCH_REL(shmtx_wr_pri, 2thr_2lock_10pct_write, 2, 0.10, true)
1715 BENCH_REL(shmtx_rd_pri, 2thr_2lock_10pct_write, 2, 0.10, true)
1716 BENCH_BASE(folly_rwspin, 4thr_4lock_10pct_write, 4, 0.10, true)
1717 BENCH_REL(shmtx_wr_pri, 4thr_4lock_10pct_write, 4, 0.10, true)
1718 BENCH_REL(shmtx_rd_pri, 4thr_4lock_10pct_write, 4, 0.10, true)
1719 BENCH_BASE(folly_rwspin, 8thr_8lock_10pct_write, 8, 0.10, true)
1720 BENCH_REL(shmtx_wr_pri, 8thr_8lock_10pct_write, 8, 0.10, true)
1721 BENCH_REL(shmtx_rd_pri, 8thr_8lock_10pct_write, 8, 0.10, true)
1722 BENCH_BASE(folly_rwspin, 16thr_16lock_10pct_write, 16, 0.10, true)
1723 BENCH_REL(shmtx_wr_pri, 16thr_16lock_10pct_write, 16, 0.10, true)
1724 BENCH_REL(shmtx_rd_pri, 16thr_16lock_10pct_write, 16, 0.10, true)
1725 BENCH_BASE(folly_rwspin, 32thr_32lock_10pct_write, 32, 0.10, true)
1726 BENCH_REL(shmtx_wr_pri, 32thr_32lock_10pct_write, 32, 0.10, true)
1727 BENCH_REL(shmtx_rd_pri, 32thr_32lock_10pct_write, 32, 0.10, true)
1728 BENCH_BASE(folly_rwspin, 64thr_64lock_10pct_write, 64, 0.10, true)
1729 BENCH_REL(shmtx_wr_pri, 64thr_64lock_10pct_write, 64, 0.10, true)
1730 BENCH_REL(shmtx_rd_pri, 64thr_64lock_10pct_write, 64, 0.10, true)
1731 BENCHMARK_DRAW_LINE();
1732 BENCH_BASE(folly_rwspin, 2thr_2lock_1pct_write, 2, 0.01, true)
1733 BENCH_REL(shmtx_wr_pri, 2thr_2lock_1pct_write, 2, 0.01, true)
1734 BENCH_REL(shmtx_rd_pri, 2thr_2lock_1pct_write, 2, 0.01, true)
1735 BENCH_BASE(folly_rwspin, 4thr_4lock_1pct_write, 4, 0.01, true)
1736 BENCH_REL(shmtx_wr_pri, 4thr_4lock_1pct_write, 4, 0.01, true)
1737 BENCH_REL(shmtx_rd_pri, 4thr_4lock_1pct_write, 4, 0.01, true)
1738 BENCH_BASE(folly_rwspin, 8thr_8lock_1pct_write, 8, 0.01, true)
1739 BENCH_REL(shmtx_wr_pri, 8thr_8lock_1pct_write, 8, 0.01, true)
1740 BENCH_REL(shmtx_rd_pri, 8thr_8lock_1pct_write, 8, 0.01, true)
1741 BENCH_BASE(folly_rwspin, 16thr_16lock_1pct_write, 16, 0.01, true)
1742 BENCH_REL(shmtx_wr_pri, 16thr_16lock_1pct_write, 16, 0.01, true)
1743 BENCH_REL(shmtx_rd_pri, 16thr_16lock_1pct_write, 16, 0.01, true)
1744 BENCH_BASE(folly_rwspin, 32thr_32lock_1pct_write, 32, 0.01, true)
1745 BENCH_REL(shmtx_wr_pri, 32thr_32lock_1pct_write, 32, 0.01, true)
1746 BENCH_REL(shmtx_rd_pri, 32thr_32lock_1pct_write, 32, 0.01, true)
1747 BENCH_BASE(folly_rwspin, 64thr_64lock_1pct_write, 64, 0.01, true)
1748 BENCH_REL(shmtx_wr_pri, 64thr_64lock_1pct_write, 64, 0.01, true)
1749 BENCH_REL(shmtx_rd_pri, 64thr_64lock_1pct_write, 64, 0.01, true)
1757 BENCHMARK_DRAW_LINE();
1758 BENCHMARK_DRAW_LINE();
1765 BENCHMARK_DRAW_LINE();
1768 BENCH_REL(shmtx_r_bare_ping_pong, burn100k, 100, 100000)
1769 BENCH_REL(folly_ticket_ping_pong, burn100k, 100, 100000)
1770 BENCH_REL(boost_shared_ping_pong, burn100k, 100, 100000)
1771 BENCH_REL(pthrd_rwlock_ping_pong, burn100k, 100, 100000)
1772 BENCHMARK_DRAW_LINE();
1775 BENCH_REL(shmtx_r_bare_ping_pong, burn300k, 100, 300000)
1776 BENCH_REL(folly_ticket_ping_pong, burn300k, 100, 300000)
1777 BENCH_REL(boost_shared_ping_pong, burn300k, 100, 300000)
1778 BENCH_REL(pthrd_rwlock_ping_pong, burn300k, 100, 300000)
1779 BENCHMARK_DRAW_LINE();
1782 BENCH_REL(shmtx_r_bare_ping_pong, burn1M, 1000, 1000000)
1783 BENCH_REL(folly_ticket_ping_pong, burn1M, 1000, 1000000)
1784 BENCH_REL(boost_shared_ping_pong, burn1M, 1000, 1000000)
1785 BENCH_REL(pthrd_rwlock_ping_pong, burn1M, 1000, 1000000)
2126 (void)folly_rwspin_reads;
2127 (void)shmtx_wr_pri_reads;
2128 (void)shmtx_w_bare_reads;
2129 (void)shmtx_rd_pri_reads;
2130 (void)shmtx_r_bare_reads;
2131 (void)folly_ticket_reads;
2132 (void)boost_shared_reads;
2133 (void)pthrd_rwlock_reads;
2143 (void)folly_rwspin_ping_pong;
2144 (void)shmtx_w_bare_ping_pong;
2145 (void)shmtx_r_bare_ping_pong;
2146 (void)folly_ticket_ping_pong;
2147 (void)boost_shared_ping_pong;
2148 (void)pthrd_rwlock_ping_pong;
2151 gflags::ParseCommandLineFlags(&argc, &argv,
true);
void runManyReadLocksTestWithoutTokens()
static std::unique_ptr< SSLLock[]> & locks()
static void shmtx_r_bare_ping_pong(size_t n, size_t scale, size_t burnCount)
static void runPingPong(size_t numRounds, size_t burnCount)
constexpr bool kIsSanitizeThread
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_
static void shmtx_w_bare_reads(uint32_t numOps, size_t numThreads, bool useSeparateLocks)
static void runMixed(size_t numOps, size_t numThreads, double writeFraction, bool useSeparateLocks)
int main(int argc, char **argv)
#define EXPECT_EQ(val1, val2)
#define BENCHMARK_SUSPEND
static void shmtx_r_bare(uint32_t numOps, size_t numThreads, double writeFraction, bool useSeparateLocks)
std::chrono::steady_clock::time_point now()
constexpr detail::Map< Move > move
void lock_shared(T *lockable)
void runTimeoutInPastTest()
void runFailingTryTimeoutTest()
constexpr bool kIsSanitizeAddress
static void folly_rwspin_reads(uint32_t numOps, size_t numThreads, bool useSeparateLocks)
false false folly_ticket_reads
static std::thread thread(Func &&func, Args &&...args)
—— Concurrent Priority Queue Implementation ——
static void boost_shared_ping_pong(size_t n, size_t scale, size_t burnCount)
void runManyReadLocksTestWithTokens()
static void shmtx_w_bare(uint32_t numOps, size_t numThreads, double writeFraction, bool useSeparateLocks)
false false false pthrd_rwlock_reads
std::vector< std::thread::id > threads
static void runContendedReaders(size_t numOps, size_t numThreads, bool useSeparateLocks)
static void pthrd_mutex_(size_t numOps, size_t numThreads, double writeFraction, bool useSeparateLocks)
constexpr std::decay< T >::type copy(T &&value) noexcept(noexcept(typename std::decay< T >::type(std::forward< T >(value))))
void runBasicHoldersTest()
static std::function< size_t(size_t)> uniform(uint64_t seed)
bool funcHasDuration(milliseconds expectedDuration, Func func)
static void folly_rwspin_ping_pong(size_t n, size_t scale, size_t burnCount)
auto lock(Synchronized< D, M > &synchronized, Args &&...args)
static void boost_shared(size_t numOps, size_t numThreads, double writeFraction, bool useSeparateLocks)
FOLLY_ASSUME_FBVECTOR_COMPATIBLE(boost::optional< boost::optional< SharedMutexToken >>) template< typename Lock
void unlock_shared(T *lockable)
static std::function< size_t(size_t)> uniformSubset(uint64_t seed, size_t n=2, size_t m=64)
TEST(ProgramOptionsTest, Errors)
#define EXPECT_TRUE(condition)
class Atom static void runRemoteUnlock(size_t numOps, double preWriteFraction, double preUpgradeFraction, size_t numSendingThreads, size_t numReceivingThreads)
void unlock_shared(T *lockable)
BENCHMARK(fbFollyGlobalBenchmarkBaseline)
static std::size_t adjustReps(std::size_t reps)
bool runBenchmarksOnFlag()
void runBasicUpgradeTest()
static void burn(size_t n)
SharedMutexImpl< true, void, DeterministicAtomic, true > DSharedMutexReadPriority
GTEST_API_ void InitGoogleTest(int *argc, char **argv)
#define EXPECT_FALSE(condition)
static void join(std::thread &child)
void lock_shared(T *lockable)
SharedMutexImpl< false, void, DeterministicAtomic, true > DSharedMutexWritePriority
static void boost_shared_reads(uint32_t numOps, size_t numThreads, bool useSeparateLocks)
void unlock_shared(T *lockable)
DeterministicSchedule DSched
static void runAllAndValidate(size_t numOps, size_t numThreads)
static void shmtx_r_bare_reads(uint32_t numOps, size_t numThreads, bool useSeparateLocks)
static const char tokens[256]
auto doNotOptimizeAway(const T &datum) -> typename std::enable_if< !detail::DoNotOptimizeAwayNeedsIndirect< T >::value >::type
void lock_shared(T *lockable)
constexpr detail::First first