base_tests.cpp 2.44 KB
Newer Older
1 2 3
#include <catch.hpp>
#include <pls/internal/base/thread.h>
#include <pls/internal/base/spin_lock.h>
FritzFlorian committed
4
#include <pls/internal/base/system_details.h>
5 6

#include <vector>
7
#include <mutex>
8 9 10 11 12 13 14 15

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;

16
TEST_CASE( "thread creation and joining", "[internal/data_structures/thread.h]") {
17 18 19 20 21 22 23
    base_tests_visited = false;
    auto t1 = start_thread([]() { base_tests_visited = true; });
    t1.join();

    REQUIRE(base_tests_visited);
}

24
TEST_CASE( "thread state", "[internal/data_structures/thread.h]") {
25 26 27 28 29 30 31 32 33 34 35 36
    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});
}

37 38
int base_tests_shared_counter;

39
TEST_CASE( "spinlock protects concurrent counter", "[internal/data_structures/spinlock.h]") {
40 41
    constexpr int num_iterations = 1000000;
    base_tests_shared_counter = 0;
42 43
    spin_lock lock{};

44 45 46 47
    SECTION( "lock can be used by itself" ) {
        auto t1 = start_thread([&]() {
            for (int i = 0; i < num_iterations; i++) {
                lock.lock();
48
                base_tests_shared_counter++;
49 50 51 52 53 54
                lock.unlock();
            }
        });
        auto t2 = start_thread([&]() {
            for (int i = 0; i < num_iterations; i++) {
                lock.lock();
55
                base_tests_shared_counter--;
56 57 58
                lock.unlock();
            }
        });
59

60 61 62
        t1.join();
        t2.join();

63
        REQUIRE(base_tests_shared_counter == 0);
64 65 66 67 68 69
    }

    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};
70
                base_tests_shared_counter++;
71 72 73 74 75
            }
        });
        auto t2 = start_thread([&]() {
            for (int i = 0; i < num_iterations; i++) {
                std::lock_guard<spin_lock> my_lock{lock};
76
                base_tests_shared_counter--;
77 78 79 80 81
            }
        });

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

83
        REQUIRE(base_tests_shared_counter == 0);
84
    }
85
}