On Thursday 16 October 2025 20:35:00 LIU Hao wrote: > The last one is unnecessary. Initializing a lock doesn't require an atomic > operation; only passing it to other threads does. And even when it's > necessary to use an atomic operation, `volatile` is not sufficient for > ARM64; it has to be done with `__atomic_store_n` which compiles to an STLR > instruction.
I really was not sure about this one. I was thinking about it... I quite do not understand why the unlock and init have different behavior. Both are setting the spin lock to unlocked state. init function does not use any synchronization or barrier, but the unlock function is using barrier with release semantics. Now, when I was thinking more about it, it is really required for init and unlock to use barrier when the counterpart function (the lock one) always uses full memory barrier? (InterlockedExchangePointer uses the full memory barrier, right?) AFAK volatile just ensure that compiler does not reorder emitted instructions as part of some compiler optimizations. But volatile does not ensure any synchronization or barrier at HW level. x86 has strong ordering where I think that only store followed by load can be reordered without explicit barrier. So my understanding is that volatile on x86 has a side effect of barrier (which does not apply for arm). But is not there some possibility that compiler could reorder something? What makes me suspicious even more, why lock and unlock functions mark the memory where tk points as volatile, but the trylock and init functions do not mark it as volatile? I would expect that at least trylock and lock functions would declare variable in the same way as the variable is passed to InterlockedExchangePointer() function as is. _______________________________________________ Mingw-w64-public mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
