[I now see that my question is a duplicate. I will vote to close it.]
Can one reliably test lock-free code in C++? Is there a known technique?
Can one compose a proper unit test? In lock-free-programming, are proper unit tests even possible?
I see no obvious way to force wrong lock-free code to fail reliably. Apparently, I am missing a concept.
(See also this related question.)
EXAMPLE
Concurrency wants long examples, unfortunately. I have made the below example as short as I can. The example is correct as far as I know, but suppose that you broke it—say, by changing memory_order_release
to memory_order_relaxed
. Even when broken, the example still, spuriously succeeds on my machine. With memory_order_relaxed
, the example should fail; but, for purpose of testing, I do not know how to make it fail.
Do you?
Unit testing seems doubtful when one is unable to compose a test to flunk bad code.
#include <atomic>
#include <thread>
#include <cstdlib>
#include <iostream>
const int threshold = 0x100;
const int large_integer = 0x1000;
// Gradually increase the integer to which q points until it reaches the
// threshold. Then, release.
void inflate(std::atomic_bool *const p_atom, int *const q)
{
while (*q < threshold) ++*q;
p_atom->store(true, std::memory_order_release);
}
int main()
{
std::atomic_bool atom{false};
int n{0};
// Dispatch the inflator, letting it begin gradually, in the background, to
// inflate the integer n.
std::thread inflator(inflate, &atom, &n);
// Waste some time....
for (int i = large_integer; i; --i) {}
// Spin until the inflator has released.
{
int no_of_tries = 0;
while (!atom.load(std::memory_order_acquire)) ++no_of_tries;
std::cout << "tried " << no_of_tries << " times" << std::endl;
}
// Verify that the integer n has reached the threshold.
if (n == threshold) {
std::cout << "succeeded" << std::endl;
}
else {
std::cout << "failed" << std::endl;
std::cerr << "error" << std::endl;
std::exit(1);
}
inflator.join();
return 0;
}