On Wednesday 22 October 2025 11:07:43 LIU Hao wrote: > 在 2025-10-22 03:58, Pali Rohár 写道: > > 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. > > After a lock is initialized, it may be passed to other threads > > * via some shared data structure, with proper locking, or > * directly or indirectly, as the user-defined argument to > `pthread_create()`. > > Either operation is guarantee that the lock is properly synchronized between > these threads, and without this operation the lock is not accessible to > other threads. When the creator thread itself accesses the lock, no > synchronization is required. > > That is, the lock can be initialized as an ordinary datum. > > > > 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?) > > The lock operation should probably be an acquire barrier instead of a full > barrier, but on x86 an atomic read-modify-write operation is always a full > barrier. > > On ARM64 the memory order applies to the write part of the atomic operation: > https://gcc.godbolt.org/z/GWev5vWqh > > > > 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). > > This looks mostly correct. > > `volatile` means the operation has an effect that is unknown to the > compiler, as if it was accessing global memory; and that's why it could be > abused for synchronization. I think we had better not abuse `volatile` for > this purpose. > > > > But is not there some possibility that compiler could reorder something? > > Initialization (of fields of a struct, for example) can happen in any order, > or even be combined to SIMD operations. It doesn't matter. > > > > 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. > > Those need not be `volatile`. > > > -- > Best regards, > LIU Hao
Thank you very much for information. So from this information it looks like that the volatile keyword is not required on more places in mingw-w64-libraries/winpthreads/src/spinlock.c file. Would you have a time to revisit that file? _______________________________________________ Mingw-w64-public mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
