mercredi 26 juin 2019

Is this acquire fence observed?

This question is about standalone fences in C++

In an attempt to encapsulate the use of acquire and release fences, I have written the following code:

#include <thread>
#include <atomic>
#include <cassert>

class sync {
    std::atomic<bool> flag{false};

public:
    void release()
    {
        std::atomic_thread_fence(std::memory_order_release);
        flag.store(true, std::memory_order_relaxed);
    }

    bool acquire()
    {
        return flag.load(std::memory_order_relaxed);
        std::atomic_thread_fence(std::memory_order_acquire); // Is this acquire fence observed by the application ?
    }
};

int main()
{
    sync s;
    int data = 0;

    std::thread t1{[&] { data = 12; s.release(); }};
    std::thread t2{[&] { if (s.acquire()) assert(data==12); }};

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

I believe that the fences are positioned correctly ('release' before the store and 'acquire' after the load).

I am not sure if the load/acquire actually works.
Since the acquire fence is after the load/return statement, I am wondering if it is taken into account at all.

Is this use of acquire fence correct ?

Aucun commentaire:

Enregistrer un commentaire