Search code examples
c++11concurrencyatomicmemory-model

C++ simple mutex using atomic_flag (code not working)


This is an exercise of using atomic_flag with acquire/release memory model to implement a very simple mutex. There are THREADS number of threads, and each thread increment cou LOOP number of times. The threads are synchronized with this simple mutex. However, the code throws exception in thread.join() function. Could someone please enlighten me why this does not work? Thank you in advance!

#include <atomic>
#include <thread>
#include <assert.h>
#include <vector>

using namespace std;
class mutex_simplified {
private:
    atomic_flag flag;
public:
    void lock() {
        while (flag.test_and_set(memory_order_acquire));
    }

    void unlock() {
        flag.clear(memory_order_release);
    }
};

mutex_simplified m_s;
int cou(0);
const int LOOP = 10000;
const int THREADS = 1000;
void increment() {
    for (unsigned i = 0; i < LOOP; i++) {
        m_s.lock();
        cou++;
        m_s.unlock();
    }
}

int main() {
    thread a(increment);
    thread b(increment);
    vector<thread> threads;

    for (int i = 0; i < THREADS; i++)
        threads.push_back(thread(increment));

    for (auto & t : threads) {
        t.join();
    }
    assert(cou == THREADS*LOOP);
}

Solution

  • You are not joining threads a and b. As the result, they might be still running while your program is finishing its execution.

    You should either add a.join() and b.join() somewhere, or probably just remove them as the assertion in your main function will fail if you keep them.

    Another issue is that you need to explicitly initialize atomic_flag instance in your mutex constructor. It might not cause issues in your example because global variables are zero-initialized, but this might cause issues later.