Domanda

Is it possible (in theory) for a thread to execute an acquire on one CPU, then immediately get preempted and resumed on another CPU for which the acquire was never executed (and therefore never synchronized per the release-acquire semantics)?

For ex. consider the following code which uses C++11 atomics and release-acquire memory-ordering to perform a lock-free thread-safe initialization:

if ( false == _initFlag.load(memory_order_acquire) ) {
    _foo = ...; // initialize global
    _bar = ...; // initialize global
    ... = ...; // initialize more globals
    _initFlag.store(true, memory_order_release);
}
// use the initialized values ...

If _initFlag.load(memory_order_acquire) returns true, then the calling thread will know that the initialized values of _foo, _bar, etc... are visible (propagated) to the CPU on which it is currently executing. But what if the thread is preempted immediately afterward and moved to another CPU?..

Does the C++11 standard guarantee the new CPU will be synchronized? Are there any implementations or architectures that might be vulnerable to this type of race condition?

È stato utile?

Soluzione

It is possible for it to get pre-empted and moved to another CPU after the acquire, but as far as I'm aware, the O/S has to ensure that any explicit memory ordering is preserved (this is probably something it keeps in the thread state). Otherwise, there'd be very little chance of anything running reliably in a multi-cpu environment.

I think the standard assumes that to be the case, on the basis it has to.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top