base_tests.cpp 1.58 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
#include <catch.hpp>
#include <pls/internal/base/thread.h>
#include <pls/internal/base/spin_lock.h>

#include <vector>

using namespace pls::internal::base;
using namespace std;

static bool base_tests_visited;
static int base_tests_local_value_one;
static vector<int> base_tests_local_value_two;

TEST_CASE( "thread creation and joining", "[internal/base/thread.h]") {
    base_tests_visited = false;
    auto t1 = start_thread([]() { base_tests_visited = true; });
    t1.join();

    REQUIRE(base_tests_visited);
}

TEST_CASE( "thread state", "[internal/base/thread.h]") {
    int state_one = 1;
    vector<int> state_two{1, 2};

    auto t1 = start_thread([]() { base_tests_local_value_one = *this_thread::state<int>(); }, &state_one);
    auto t2 = start_thread([]() { base_tests_local_value_two = *this_thread::state<vector<int>>(); }, &state_two);
    t1.join();
    t2.join();

    REQUIRE(base_tests_local_value_one == 1);
    REQUIRE(base_tests_local_value_two == vector<int>{1, 2});
}

TEST_CASE( "spinlock protects concurrent counter", "[internal/base/spinlock.h]") {
    constexpr int num_iterations = 1000000;
    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();
        }
    });

    t1.join();
    t2.join();

    REQUIRE(shared_counter == 0);
}