> And old code has
>
>     while (unlikely(InterlockedExchangePointer((PVOID*)lk, 0) == 0))
>       YieldProcessor();
>
> which effects a huge amount of cache pressure. This can be much better:
>
>     while (unlikely(InterlockedExchangePointer((PVOID*)lk, 0) == 0))
>      for (int i = 0; i != 100; ++i)
>         YieldProcessor();
>
> The magic number 100 is, of course, an arbitrary choice. I believe you can 
> find a better one basing on
> benchmark results on your hardware.

Usually spin locks read the value without fences, then attempt a swap when the 
retrieved value is "good". This ensures that cache lines aren't locked in 
exclusive mode for no reason.

retry:
  while (ReadPointerNoFence((PVOID*)lk) == 0))
    YieldProcessor();
  If (InterlockedExchangePointer((PVOID*)lk, 0) == 0)
    goto retry;

We could implement ReadPointerNoFence in winnt.h, however for the time being a 
volatile access will work just fine:

retry:
  while (*(void * volatile *)lk == 0)
    YieldProcessor();
  If (InterlockedExchangePointer((PVOID*)lk, 0) == 0)
    goto retry;

Best Regards,
Luca
________________________________
Da: Kirill Makurin <[email protected]>
Inviato: lunedì 11 maggio 2026 16:25
A: [email protected] 
<[email protected]>
Oggetto: Re: [Mingw-w64-public] winpthreads: fix XFAIL tests and provide new 
spinlock implementation

> I think this spinlock implementation is over-complicated. Since 
> `pthread_spinlock_t` is just an integer,
> you can store the ID of the owner thread in there.

I wanted to finalize and send these patches on Saturday, but other things 
kicked in. Earlier today while double-checking everything, I realized that we 
really just can store thread ID in `pthread_spinlock_t`. Anyway, I sent the 
patches with implementation that I had ready. I'll send updated implementation 
in the coming days.

> And old code has
>
>     while (unlikely(InterlockedExchangePointer((PVOID*)lk, 0) == 0))
>       YieldProcessor();
>
> which effects a huge amount of cache pressure. This can be much better:
>
>     while (unlikely(InterlockedExchangePointer((PVOID*)lk, 0) == 0))
>      for (int i = 0; i != 100; ++i)
>         YieldProcessor();
>
> The magic number 100 is, of course, an arbitrary choice. I believe you can 
> find a better one basing on
> benchmark results on your hardware.

I'm not sure about it... I feel like number which gives good results for one 
hardware may give completely different results on another.

- Kirill Makurin

_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to