ordenação de memória com bloqueio de rotação atomic_flag
Eu estou tentando me familiarizar com os novos conceitos de ordenação de memória do c ++ 11 e acreditava que eu realmente tinha um bom entendimento sobre eles, até que tropecei na implementação de um bloqueio de giro:
#include <atomic>
namespace JayZ
{
namespace Tools
{
class SpinLock
{
private:
std::atomic_flag spin_lock;
public:
inline SpinLock( void ) : atomic_flag( ATOMIC_FLAG_INIT ) {}
inline void lock( void )
{
while( spin_lock.test_and_set( std::memory_order_acquire ) )
;
}
inline void unlock( void )
{
lock.clear( std::memory_order_release );
}
};
}
}
É, e. equivalentemente mencionado emhttp://en.cppreference.com/w/cpp/atomic/atomic_flag
e também no livro "Concurrency in Action". Eu também encontrei em algum lugar aqui no SO.
Mas eu simplesmente não entendo porque funcionaria!
Imagine que as chamadas do thread 1 lock () e test_and_set () retornam 0, pois o valor antigo -> thread 1 adquiriu o bloqueio.
Mas então o segmento 2 vem e tenta o mesmo. Agora, desde que não ocorreu nenhuma loja "store synchronization" (release, seq_cst_acq_rel) do thread 1 para o spin_lock deve ser do tipo relaxado.
Mas a partir disso, segue que não pode ser sincronizado com a leitura de spin_lock do thread 2. Isso deve permitir que o thread 2 leia o valor 0 de spin_lock e, assim, adquira o bloqueio também.
Onde está o meu erro?