Yes, the else branch covers GNU-style Windows builds. The current
mingw-w64 winnt.h doesn't provide ReadAcquire, so I used
__atomic_load_n there.

InterlockedCompareExchange(&mp->initstate, 0, 0) would provide a
common implementation with a full memory barrier. It would also put a
compare-exchange operation back on the initialized fast path. Avoiding
that was the reason for the split; I haven't benchmarked the
difference.

I haven't identified a common load-only Windows primitive in the
headers checked. I suggest keeping the load-only paths unless you'd
prefer the simpler common API path.

Best,

Harrison

On Tue, 13 Oct 2026 11:03:21 +0300, Heikki Linnakangas <[email protected]> wrote:
> On 13/10/2026 02:37, [email protected] wrote:
> > Heikki, do the acquire loads and separate pthread_once work address
> > your concerns?
>
> Yeah.
>
> > +   /* Acquire the initialization state without a read-modify-write. */
> > +#ifdef _MSC_VER
> > +   if (ReadAcquire(&mp->initstate) != 1)
> > +#else
> > +   if (__atomic_load_n(&mp->initstate, __ATOMIC_ACQUIRE) != 1)
> > +#endif
>
> Hmm, so ReadAcquire is only available on Visual Studio, and the
> else-branch is for mingw builds? Is there no atomic read intrinsic
> similar InterlockedCompareExchange() that would work on both?
>
> - Heikki


Reply via email to