Testing atomic lock

Hello everyone,

I tried to implement a mcs lock. Now I would like to test if it works and how it behaves in different situations. After playing around with threads for roughly 10hours I`m none the wiser.
What is the general approach to test such a lock? Nothing crazy just the basics(if there is such a thing).
Thanks in advance.


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
#include <iostream>
#include <atomic>
#include <thread>
#include <vector>

struct qnode {
  std::atomic<qnode *> next;
  std::atomic<bool> wait;
};

class mcs_lock {

  std::atomic<qnode *> tail;

public:
  void acquire(qnode *n) {
    n->next.store(nullptr);
    n->wait.store(true);

    qnode *prev = tail.exchange(n, std::memory_order_acq_rel);

    if (prev) {
      prev->next.store(n, std::memory_order_release);

      //spin
      while (n->wait.load(std::memory_order_acquire)) {
        ;
      }
    }
  }

  void release(qnode *n) {
    qnode *succ = n->next.load(std::memory_order_acquire);

    if (!succ) {
          auto expected = n;
          if (tail.compare_exchange_strong(expected, nullptr, std::memory_order_acq_rel)) {
            return;
          }

          do {
            succ = n->next.load(std::memory_order_acquire);
          } while (succ == nullptr);
        }

    succ->wait.store(false, std::memory_order_release);
  }

};
Since synchronization errors are non-deterministic, your only option to test it is to execute the operation in parallel until you can get it to fail. Understanding "fail" to mean that the state of the program does not match the rules you defined. The more times you test it without failing the more certainty you'll have that it's correct, approaching 100% certainty asymptotically, obviously.
Thanks for the response. Is it better to do the entire testing in the main function, or should I create a seperate class just for testing?
testing should be whatever costs you the least time and energy. Make a new main program file / project that pulls in the necessary and test on the side, if its easier. Do it in main if its small and main isnt really 'in place' yet. Try to avoid making anything new and complicated, -- what code tests the test code problem...

there are loads of advanced test frameworks out there too, that can test full on programs and more. But basic unit testing should be kept as simple as you can to get it done.
Last edited on
Ok, thank you for the explanation, I will try to keep it simple.
Topic archived. No new replies allowed.