mardi 1 septembre 2015

Does relaxed memory order effect can be extended to after performing-thread's life?

Let's say inside a C++11 program, we have a main thread named A that launches an asynchronous thread named B. Inside thread B, we perform an atomic store on an atomic variable with std::memory_order_relaxed memory order. Then thread A joins with thread B. Then thread A launches another thread named C that performs an atomic load operation with std::memory_order_relaxed memory order. Is it possible that thread C loaded content is different from the content written by thread B? In other words, does relaxed memory consistency here extends to even after the life of a thread?

To try this, I wrote a simple program and ran it with many tries. The program does not report a mismatch. I'm thinking since thread A imposes an order in launch of threads, mismatch cannot happen. However, I'm not sure of it.

#include <atomic>
#include <iostream>
#include <future>

int main() {

    static const int nTests = 100000;
    std::atomic<int> myAtomic( 0 );

    auto storeFunc = [&]( int inNum ){
        myAtomic.store( inNum, std::memory_order_relaxed );
    };

    auto loadFunc = [&]() {
        return myAtomic.load( std::memory_order_relaxed );
    };

    for( int ttt = 1; ttt <= nTests; ++ttt ) {
        auto writingThread = std::async( std::launch::async, storeFunc, ttt );
        writingThread.get();
        auto readingThread = std::async( std::launch::async, loadFunc );
        auto readVal = readingThread.get();
        if( readVal != ttt ) {
            std::cout << "mismatch!\t" << ttt << "\t!=\t" << readVal << "\n";
            return 1;
        }
    }

    std::cout << "done.\n";
    return 0;

}

Aucun commentaire:

Enregistrer un commentaire