]> Savannah Git Hosting - gnulib.git/commitdiff
pthread-spin: Add optimized fallback for GCC versions >= 4.1, < 4.7.
authorBruno Haible <bruno@clisp.org>
Wed, 1 Jul 2020 20:52:41 +0000 (22:52 +0200)
committerBruno Haible <bruno@clisp.org>
Wed, 1 Jul 2020 20:52:41 +0000 (22:52 +0200)
* lib/pthread-spin.c (pthread_spin_init, pthread_spin_lock,
pthread_spin_trylock, pthread_spin_unlock): For GCC >= 4.1, < 4.7, use
an implementation based on other GCC built-ins.

ChangeLog
lib/pthread-spin.c

index 06044eef96df81a90f952250a10f99de1736b62e..e599b214bebc046e0d391e5cf5166787b2326725 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2020-07-01  Bruno Haible  <bruno@clisp.org>
+
+       pthread-spin: Add optimized fallback for GCC versions >= 4.1, < 4.7.
+       * lib/pthread-spin.c (pthread_spin_init, pthread_spin_lock,
+       pthread_spin_trylock, pthread_spin_unlock): For GCC >= 4.1, < 4.7, use
+       an implementation based on other GCC built-ins.
+
 2020-07-01  Bruno Haible  <bruno@clisp.org>
 
        pthread-spin: Optimize fallback for GCC versions >= 4.7.
index 1f73f130be1bf3a339f59a0323925b1bfad4a570..c13105046d2d6215d28920bf7c530a49d3ab88b2 100644 (file)
@@ -162,6 +162,52 @@ pthread_spin_destroy (pthread_spinlock_t *lock)
   return 0;
 }
 
+# elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
+/* Use GCC built-ins (available in GCC >= 4.1).
+   Documentation:
+   <https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html>  */
+
+int
+pthread_spin_init (pthread_spinlock_t *lock,
+                   int shared_across_processes _GL_UNUSED)
+{
+  * (volatile unsigned int *) lock = 0;
+  __sync_synchronize ();
+  return 0;
+}
+
+int
+pthread_spin_lock (pthread_spinlock_t *lock)
+{
+  /* Wait until *lock becomes 0, then replace it with 1.  */
+  while (__sync_val_compare_and_swap ((unsigned int *) lock, 0, 1) != 0)
+    ;
+  return 0;
+}
+
+int
+pthread_spin_trylock (pthread_spinlock_t *lock)
+{
+  if (__sync_val_compare_and_swap ((unsigned int *) lock, 0, 1) != 0)
+    return EBUSY;
+  return 0;
+}
+
+int
+pthread_spin_unlock (pthread_spinlock_t *lock)
+{
+  /* If *lock is 1, then replace it with 0.  */
+  if (__sync_val_compare_and_swap ((unsigned int *) lock, 1, 0) != 1)
+    abort ();
+  return 0;
+}
+
+int
+pthread_spin_destroy (pthread_spinlock_t *lock)
+{
+  return 0;
+}
+
 # else
 /* Emulate a spin lock through a mutex.  */