Commit 0599cfdc by FritzFlorian

Add std::lock_guard test for spin_lock.

parent 51cc6572
Pipeline #1100 failed with stages
in 1 minute 35 seconds
......@@ -17,19 +17,8 @@ namespace pls {
public:
spin_lock(): flag_{ATOMIC_FLAG_INIT}, yield_at_tries_{1024} {};
void lock() {
int tries = 0;
while (flag_.test_and_set(std::memory_order_acquire)) {
tries++;
if (tries % yield_at_tries_ == 0) {
this_thread::yield();
}
}
}
void unlock() {
flag_.clear(std::memory_order_release);
}
void lock();
void unlock();
};
}
}
......
......@@ -3,7 +3,19 @@
namespace pls {
namespace internal {
namespace base {
// implementation in header (inlining)
void spin_lock::lock() {
int tries = 0;
while (flag_.test_and_set(std::memory_order_acquire)) {
tries++;
if (tries % yield_at_tries_ == 0) {
this_thread::yield();
}
}
}
void spin_lock::unlock() {
flag_.clear(std::memory_order_release);
}
}
}
}
......@@ -3,6 +3,7 @@
#include <pls/internal/base/spin_lock.h>
#include <vector>
#include <mutex>
using namespace pls::internal::base;
using namespace std;
......@@ -33,27 +34,49 @@ TEST_CASE( "thread state", "[internal/base/thread.h]") {
}
TEST_CASE( "spinlock protects concurrent counter", "[internal/base/spinlock.h]") {
constexpr int num_iterations = 1000000;
constexpr int num_iterations = 100000;
int shared_counter = 0;
spin_lock lock{};
auto t1 = start_thread([&] () {
for (int i = 0; i < num_iterations; i++) {
lock.lock();
shared_counter++;
lock.unlock();
}
});
auto t2 = start_thread([&] () {
for (int i = 0; i < num_iterations; i++) {
lock.lock();
shared_counter--;
lock.unlock();
}
});
SECTION( "lock can be used by itself" ) {
auto t1 = start_thread([&]() {
for (int i = 0; i < num_iterations; i++) {
lock.lock();
shared_counter++;
lock.unlock();
}
});
auto t2 = start_thread([&]() {
for (int i = 0; i < num_iterations; i++) {
lock.lock();
shared_counter--;
lock.unlock();
}
});
t1.join();
t2.join();
t1.join();
t2.join();
REQUIRE(shared_counter == 0);
}
SECTION( "lock can be used with std::lock_guard" ) {
auto t1 = start_thread([&]() {
for (int i = 0; i < num_iterations; i++) {
std::lock_guard<spin_lock> my_lock{lock};
shared_counter++;
}
});
auto t2 = start_thread([&]() {
for (int i = 0; i < num_iterations; i++) {
std::lock_guard<spin_lock> my_lock{lock};
shared_counter--;
}
});
t1.join();
t2.join();
REQUIRE(shared_counter == 0);
REQUIRE(shared_counter == 0);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment