2

[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;
}
thb
  • 13,796
  • 3
  • 40
  • 68

0 Answers0