Legacy `__sync_*` GCC built-in functions for memory access [1] are
deprecated and MSVC doesn't provide them.
Consequently, use Windows' Interlocked Variable Access [2] functions
instead.

[1]: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fsync-Builtins.html
[2]: 
https://learn.microsoft.com/en-us/windows/win32/sync/interlocked-variable-access

Signed-off-by: Antonin Décimo <anto...@tarides.com>
---
 mingw-w64-libraries/winpthreads/src/mutex.c    | 15 +++++++--------
 mingw-w64-libraries/winpthreads/src/spinlock.c |  4 ++--
 2 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/mingw-w64-libraries/winpthreads/src/mutex.c 
b/mingw-w64-libraries/winpthreads/src/mutex.c
index 514219821..866e18d94 100644
--- a/mingw-w64-libraries/winpthreads/src/mutex.c
+++ b/mingw-w64-libraries/winpthreads/src/mutex.c
@@ -79,7 +79,7 @@ mutex_impl_init(pthread_mutex_t *m, mutex_impl_t *mi)
   new_mi->event = NULL;
   new_mi->rec_lock = 0;
   new_mi->owner = (DWORD)-1;
-  if (__sync_bool_compare_and_swap(m, (pthread_mutex_t)mi, 
(pthread_mutex_t)new_mi)) {
+  if (InterlockedCompareExchangePointer((PVOID volatile *)m, new_mi, mi) == 
mi) {
     return new_mi;
   } else {
     /* Someone created the struct before us. */
@@ -112,8 +112,7 @@ pthread_mutex_lock_intern (pthread_mutex_t *m, DWORD 
timeout)
   mutex_impl_t *mi = mutex_impl(m);
   if (mi == NULL)
     return ENOMEM;
-
-  mutex_state_t old_state = __sync_lock_test_and_set(&mi->state, Locked);
+  mutex_state_t old_state = InterlockedExchange((long *)&mi->state, Locked);
   if (unlikely(old_state != Unlocked)) {
     /* The mutex is already locked. */
 
@@ -124,7 +123,7 @@ pthread_mutex_lock_intern (pthread_mutex_t *m, DWORD 
timeout)
            recursively.  We could rewrite by doing compare-and-swap instead of
            test-and-set the first time, but it would lead to more code
            duplication and add a conditional branch to the critical path. */
-        __sync_bool_compare_and_swap(&mi->state, Locked, old_state);
+        InterlockedCompareExchange((long *)&mi->state, old_state, Locked);
         if (mi->type == Recursive) {
           mi->rec_lock++;
           return 0;
@@ -147,7 +146,7 @@ pthread_mutex_lock_intern (pthread_mutex_t *m, DWORD 
timeout)
           return ENOMEM;    /* Probably accurate enough. */
         }
       }
-      if (!__sync_bool_compare_and_swap(&mi->event, NULL, ev)) {
+      if (InterlockedCompareExchangePointer(&mi->event, ev, NULL) != NULL) {
         /* Someone created the event before us. */
         CloseHandle(ev);
       }
@@ -155,7 +154,7 @@ pthread_mutex_lock_intern (pthread_mutex_t *m, DWORD 
timeout)
 
     /* At this point, mi->event is non-NULL. */
 
-    while (__sync_lock_test_and_set(&mi->state, Waiting) != Unlocked) {
+    while (InterlockedExchange((long *)&mi->state, Waiting) != Unlocked) {
       /* For timed locking attempts, it is possible (although unlikely)
          that we are woken up but someone else grabs the lock before us,
          and we have to go back to sleep again. In that case, the total
@@ -219,7 +218,7 @@ int pthread_mutex_unlock(pthread_mutex_t *m)
     }
     mi->owner = (DWORD)-1;
   }
-  if (unlikely(__sync_lock_test_and_set(&mi->state, Unlocked) == Waiting)) {
+  if (unlikely(InterlockedExchange((long *)&mi->state, Unlocked) == Waiting)) {
     if (!SetEvent(mi->event))
       return EPERM;
   }
@@ -232,7 +231,7 @@ int pthread_mutex_trylock(pthread_mutex_t *m)
   if (mi == NULL)
     return ENOMEM;
 
-  if (__sync_bool_compare_and_swap(&mi->state, Unlocked, Locked)) {
+  if (InterlockedCompareExchange((long *)&mi->state, Locked, Unlocked) == 
Unlocked) {
     if (mi->type != Normal)
       mi->owner = GetCurrentThreadId();
     return 0;
diff --git a/mingw-w64-libraries/winpthreads/src/spinlock.c 
b/mingw-w64-libraries/winpthreads/src/spinlock.c
index 384c98970..224c5a06e 100644
--- a/mingw-w64-libraries/winpthreads/src/spinlock.c
+++ b/mingw-w64-libraries/winpthreads/src/spinlock.c
@@ -50,7 +50,7 @@ int
 pthread_spin_lock (pthread_spinlock_t *lock)
 {
   volatile spinlock_word_t *lk = (volatile spinlock_word_t *)lock;
-  while (unlikely(__sync_lock_test_and_set(lk, 0) == 0))
+  while (unlikely(InterlockedExchangePointer((PVOID volatile *)lk, 0) == 0))
     do {
       YieldProcessor();
     } while (*lk == 0);
@@ -61,7 +61,7 @@ int
 pthread_spin_trylock (pthread_spinlock_t *lock)
 {
   spinlock_word_t *lk = (spinlock_word_t *)lock;
-  return __sync_lock_test_and_set(lk, 0) == 0 ? EBUSY : 0;
+  return InterlockedExchangePointer((PVOID volatile *)lk, 0) == 0 ? EBUSY : 0;
 }
 
 
-- 
2.43.0



_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to