forked from boostorg/unordered
Add explicit tests for rw_spinlock
This commit is contained in:
committed by
Peter Dimov
parent
6ee93f17e4
commit
0d2eaa0b21
@ -140,6 +140,7 @@ foa_tests(SOURCES exception/merge_exception_tests.cpp)
|
||||
|
||||
# CFOA tests
|
||||
|
||||
cfoa_tests(SOURCES cfoa/rw_spinlock_tests.cpp)
|
||||
cfoa_tests(SOURCES cfoa/latch_tests.cpp)
|
||||
cfoa_tests(SOURCES cfoa/insert_tests.cpp)
|
||||
cfoa_tests(SOURCES cfoa/erase_tests.cpp)
|
||||
|
@ -177,6 +177,7 @@ alias foa_tests :
|
||||
|
||||
local CFOA_TESTS =
|
||||
latch_tests
|
||||
rw_spinlock_tests
|
||||
insert_tests
|
||||
erase_tests
|
||||
try_emplace_tests
|
||||
|
255
test/cfoa/rw_spinlock_tests.cpp
Normal file
255
test/cfoa/rw_spinlock_tests.cpp
Normal file
@ -0,0 +1,255 @@
|
||||
// Copyright 2023 Peter Dimov
|
||||
// Copyright 2023 Christian Mazakas
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include "helpers.hpp"
|
||||
|
||||
#include <boost/unordered/detail/foa/rw_spinlock.hpp>
|
||||
#include <boost/compat/shared_lock.hpp>
|
||||
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
using boost::unordered::detail::foa::rw_spinlock;
|
||||
|
||||
static int count = 0;
|
||||
|
||||
UNORDERED_AUTO_TEST (rw_spinlock_test) {
|
||||
rw_spinlock sp, sp2;
|
||||
|
||||
sp.lock();
|
||||
sp2.lock();
|
||||
sp.unlock();
|
||||
sp2.unlock();
|
||||
|
||||
{
|
||||
std::lock_guard<rw_spinlock> lock(sp);
|
||||
std::lock_guard<rw_spinlock> lock2(sp2);
|
||||
}
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (rw_spinlock_test2) {
|
||||
rw_spinlock sp, sp2;
|
||||
|
||||
BOOST_TEST(sp.try_lock());
|
||||
BOOST_TEST(!sp.try_lock());
|
||||
BOOST_TEST(sp2.try_lock());
|
||||
BOOST_TEST(!sp.try_lock());
|
||||
BOOST_TEST(!sp2.try_lock());
|
||||
sp.unlock();
|
||||
sp2.unlock();
|
||||
|
||||
sp.lock();
|
||||
BOOST_TEST(!sp.try_lock());
|
||||
sp2.lock();
|
||||
BOOST_TEST(!sp.try_lock());
|
||||
BOOST_TEST(!sp2.try_lock());
|
||||
sp.unlock();
|
||||
sp2.unlock();
|
||||
|
||||
{
|
||||
std::lock_guard<rw_spinlock> lock(sp);
|
||||
BOOST_TEST(!sp.try_lock());
|
||||
std::lock_guard<rw_spinlock> lock2(sp2);
|
||||
BOOST_TEST(!sp.try_lock());
|
||||
BOOST_TEST(!sp2.try_lock());
|
||||
}
|
||||
}
|
||||
|
||||
void f(rw_spinlock& sp, int n)
|
||||
{
|
||||
for (int i = 0; i < n; ++i) {
|
||||
std::lock_guard<rw_spinlock> lock(sp);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (rw_spinlock_test3) {
|
||||
count = 0;
|
||||
|
||||
rw_spinlock sp;
|
||||
|
||||
int const N = 1000000; // iterations
|
||||
int const M = 8; // threads
|
||||
|
||||
std::thread th[M];
|
||||
|
||||
for (int i = 0; i < M; ++i) {
|
||||
th[i] = std::thread([=, &sp] { f(sp, N); });
|
||||
}
|
||||
|
||||
for (int i = 0; i < M; ++i) {
|
||||
th[i].join();
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ(count, N * M);
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (rw_spinlock_test4) {
|
||||
rw_spinlock sp, sp2;
|
||||
|
||||
sp.lock();
|
||||
sp2.lock_shared();
|
||||
sp2.lock_shared();
|
||||
|
||||
sp.unlock();
|
||||
sp2.unlock_shared();
|
||||
sp2.unlock_shared();
|
||||
|
||||
{
|
||||
std::lock_guard<rw_spinlock> lock(sp);
|
||||
boost::compat::shared_lock<rw_spinlock> lock2(sp2);
|
||||
boost::compat::shared_lock<rw_spinlock> lock3(sp2);
|
||||
}
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (rw_spinlock_test5) {
|
||||
rw_spinlock sp;
|
||||
|
||||
{
|
||||
BOOST_TEST(sp.try_lock_shared());
|
||||
BOOST_TEST(sp.try_lock_shared());
|
||||
sp.unlock_shared();
|
||||
sp.unlock_shared();
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST(sp.try_lock());
|
||||
BOOST_TEST(!sp.try_lock_shared());
|
||||
sp.unlock();
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<rw_spinlock> lock(sp);
|
||||
BOOST_TEST(!sp.try_lock_shared());
|
||||
}
|
||||
|
||||
{
|
||||
boost::compat::shared_lock<rw_spinlock> lock(sp);
|
||||
BOOST_TEST(!sp.try_lock());
|
||||
BOOST_TEST(sp.try_lock_shared());
|
||||
sp.unlock_shared();
|
||||
}
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (rw_spinlock_test6) {
|
||||
count = 0;
|
||||
|
||||
rw_spinlock sp;
|
||||
|
||||
int const N = 1000000; // total iterations
|
||||
int const M = 8; // threads
|
||||
|
||||
std::thread th[M];
|
||||
|
||||
for (int i = 0; i < M; ++i) {
|
||||
int n = N;
|
||||
th[i] = std::thread([n, &sp] {
|
||||
for (;;) {
|
||||
{
|
||||
boost::compat::shared_lock<rw_spinlock> lock(sp);
|
||||
if (count >= n)
|
||||
break;
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<rw_spinlock> lock(sp);
|
||||
if (count >= n)
|
||||
break;
|
||||
++count;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (int i = 0; i < M; ++i) {
|
||||
th[i].join();
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ(count, N);
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (rw_spinlock_test7) {
|
||||
rw_spinlock sp;
|
||||
|
||||
int const N = 1000000; // total iterations
|
||||
int const M = 8; // threads
|
||||
|
||||
std::thread th[M];
|
||||
|
||||
for (int i = 0; i < M; ++i) {
|
||||
int n = N;
|
||||
th[i] = std::thread([=, &sp] {
|
||||
for (;;) {
|
||||
int oldc;
|
||||
|
||||
{
|
||||
boost::compat::shared_lock<rw_spinlock> lock(sp);
|
||||
if (count >= n)
|
||||
break;
|
||||
oldc = count;
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<rw_spinlock> lock(sp);
|
||||
if (count == oldc)
|
||||
++count;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (int i = 0; i < M; ++i) {
|
||||
th[i].join();
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ(count, N);
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST (rw_spinlock_test8) {
|
||||
count = 0;
|
||||
|
||||
rw_spinlock sp;
|
||||
|
||||
int const N = 1000; // total iterations
|
||||
int const M = 4; // threads
|
||||
|
||||
std::thread th[M];
|
||||
|
||||
for (int i = 0; i < M; ++i) {
|
||||
int k = i;
|
||||
int m = M;
|
||||
int n = N;
|
||||
|
||||
th[i] = std::thread([k, m, n, &sp] {
|
||||
for (int j = 0; j < n; ++j) {
|
||||
int oldc;
|
||||
|
||||
for (;;) {
|
||||
{
|
||||
boost::compat::shared_lock<rw_spinlock> lock(sp);
|
||||
oldc = count;
|
||||
}
|
||||
|
||||
if (oldc % m == k)
|
||||
break;
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<rw_spinlock> lock(sp);
|
||||
if (count == oldc)
|
||||
++count;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (int i = 0; i < M; ++i) {
|
||||
th[i].join();
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ(count, N * M);
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
Reference in New Issue
Block a user