From 2c208e6936378fc06222fe72abf50b9867ef8ed2 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Wed, 1 Jul 2020 22:52:41 +0200 Subject: [PATCH] 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. --- ChangeLog | 7 +++++++ lib/pthread-spin.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/ChangeLog b/ChangeLog index 06044eef96..e599b214be 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2020-07-01 Bruno Haible + + 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 pthread-spin: Optimize fallback for GCC versions >= 4.7. diff --git a/lib/pthread-spin.c b/lib/pthread-spin.c index 1f73f130be..c13105046d 100644 --- a/lib/pthread-spin.c +++ b/lib/pthread-spin.c @@ -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: + */ + +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. */ -- 2.39.5