+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.
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. */