Skip to content

Commit

Permalink
Add a test for shared ticket lock
Browse files Browse the repository at this point in the history
  • Loading branch information
ademakov committed May 17, 2019
1 parent 3a73240 commit 95bb1bf
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 2 deletions.
7 changes: 6 additions & 1 deletion evenk/spinlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,13 @@ class shared_ticket_lock : non_copyable
}

private:
#if EVENK_SHARED_TICKET_TESTING
#pragma message("using very small shared ticket size to trigger possible bugs with more probability")
using base_type = std::uint8_t;
#else
using base_type = std::uint32_t;
static constexpr base_type shared_step = 1 << 16;
#endif
static constexpr base_type shared_step = 1 << (8 * sizeof(base_type) / 2);
static constexpr base_type exclusive_mask = shared_step - 1;
static constexpr base_type exclusive_step = 1;

Expand Down
4 changes: 3 additions & 1 deletion tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
AM_CPPFLAGS = -I$(top_srcdir)
AM_CXXFLAGS = -Wall -Wextra

noinst_PROGRAMS = lock-bench queue-bench \
noinst_PROGRAMS = lock-bench shared-lock-test queue-bench \
task-test thread-test thread_pool-test

lock_bench_SOURCES = lock-bench.cc

shared_lock_test_SOURCES = shared-lock-test.cc

queue_bench_SOURCES = queue-bench.cc

task_test_SOURCES = task-test.cc
Expand Down
62 changes: 62 additions & 0 deletions tests/shared-lock-test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#define EVENK_SHARED_TICKET_TESTING 1

#include "evenk/spinlock.h"
#include "evenk/thread.h"

#include <iostream>

static constexpr std::size_t test_count = 20 * 1000;

static constexpr std::size_t table_size = 8;

static constexpr std::size_t thread_num = 10;
static_assert(thread_num < 16, "for testing purposes shared_ticket_lock is intentionally restricted to at most 15 threads.");

struct entry
{
alignas(64) std::int_fast32_t value;
} table[table_size];

evenk::shared_ticket_lock table_lock;

void
thread_routine(std::size_t thread_idx)
{
for (std::size_t i = 1; i <= test_count; i++) {
table_lock.lock_shared();
const std::int_fast32_t value = table[0].value;
for (std::size_t j = 1; j < table_size; j++) {
if (value != table[j].value)
return;
}
table_lock.unlock_shared();

table_lock.lock();
if ((i % 1000) == 0)
std::cout << "thread #" << thread_idx << " " << i << "\n";
for (std::size_t j = 0; j < table_size; j++)
table[j].value++;
table_lock.unlock();
}
}

int
main()
{
evenk::thread thread_array[thread_num];
for (std::size_t i = 0; i < thread_num; i++)
thread_array[i] = evenk::thread(thread_routine, i);
for (std::size_t i = 0; i < thread_num; i++)
thread_array[i].join();

for (std::size_t j = 0; j < table_size; j++) {
if (table[j].value != test_count * thread_num) {
std::cout << "FAILED\n";
return 1;
}
std::cout << "entry #" << j << ": table[j].value=" << table[j].value << ": ok\n";
}

std::cout << "passed\n";
return 0;
}

0 comments on commit 95bb1bf

Please sign in to comment.