base_tests.cpp 1.48 KB
Newer Older
1
#include <catch.hpp>
2

3 4
#include "pls/internal/base/spin_lock.h"
#include "pls/internal/base/system_details.h"
5 6

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

using namespace pls::internal::base;

static bool base_tests_visited;
static int base_tests_local_value_one;
14
static std::vector<int> base_tests_local_value_two;
15

16 17
int base_tests_shared_counter;

18 19 20 21 22 23
TEST_CASE("spinlock protects concurrent counter", "[internal/data_structures/spinlock.h]") {
  constexpr int num_iterations = 1000000;
  base_tests_shared_counter = 0;
  spin_lock lock{};

  SECTION("lock can be used by itself") {
24
    std::thread t1{[&]() {
25 26 27 28 29
      for (int i = 0; i < num_iterations; i++) {
        lock.lock();
        base_tests_shared_counter++;
        lock.unlock();
      }
30
    }};
31
    std::thread t2{[&]() {
32 33 34 35 36
      for (int i = 0; i < num_iterations; i++) {
        lock.lock();
        base_tests_shared_counter--;
        lock.unlock();
      }
37
    }};
38 39 40 41 42 43 44 45

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

    REQUIRE(base_tests_shared_counter == 0);
  }

  SECTION("lock can be used with std::lock_guard") {
46
    std::thread t1{[&]() {
47 48 49 50
      for (int i = 0; i < num_iterations; i++) {
        std::lock_guard<spin_lock> my_lock{lock};
        base_tests_shared_counter++;
      }
51
    }};
52
    std::thread t2{[&]() {
53 54 55 56
      for (int i = 0; i < num_iterations; i++) {
        std::lock_guard<spin_lock> my_lock{lock};
        base_tests_shared_counter--;
      }
57
    }};
58 59 60 61 62 63

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

    REQUIRE(base_tests_shared_counter == 0);
  }
64
}