This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 2/2] S390: Test if lock is free before using atomic instruction in spin-lock.


This patch changes the behaviour of pthread_spin_lock on s390:
Instead of spinning on the lock with compare-and-swap instruction,
the atomic_compare_and_exchange_bool_acq macro is used.
The s390 atomic_compare_and_exchange_bool_acq macro called with constant
zero as oldval first compares the lock with normal instructions.  If it is
free the compare-and-swap instruction is used to aquire the lock.  While
the lock is held by one cpu another cpu will not exclusively lock the
memory of the lock in a loop.  If the lock is unlocked by another cpu
it is observed by the normal instruction and the lock is acquired
with a compare-and-swap instruction.

ChangeLog:

	* sysdeps/s390/nptl/pthread_spin_lock.c:
	Use atomic_compare_and_exchange_bool_acq macro instead of
	inline assembly.
	* sysdeps/s390/nptl/pthread_spin_trylock.c: Likewise.
---
 sysdeps/s390/nptl/pthread_spin_lock.c    | 13 +++++++------
 sysdeps/s390/nptl/pthread_spin_trylock.c | 12 +++++-------
 2 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/sysdeps/s390/nptl/pthread_spin_lock.c b/sysdeps/s390/nptl/pthread_spin_lock.c
index def6a24..9c06949 100644
--- a/sysdeps/s390/nptl/pthread_spin_lock.c
+++ b/sysdeps/s390/nptl/pthread_spin_lock.c
@@ -21,12 +21,13 @@
 int
 pthread_spin_lock (pthread_spinlock_t *lock)
 {
-  int oldval;
+  /* The s390 atomic_compare_and_exchange_bool_acq macro called with constant
+     zero as oldval first compares the lock with normal instructions.  If it is
+     free the compare-and-swap instruction is used to aquire the lock.  While
+     the lock is held by one cpu another cpu will not exclusively lock the
+     memory of the lock in a loop.  */
+  while (atomic_compare_and_exchange_bool_acq (lock, 1, 0))
+    ;
 
-  __asm__ __volatile__ ("0: lhi %0,0\n"
-			"   cs  %0,%2,%1\n"
-			"   jl  0b"
-			: "=&d" (oldval), "=Q" (*lock)
-			: "d" (1), "m" (*lock) : "cc" );
   return 0;
 }
diff --git a/sysdeps/s390/nptl/pthread_spin_trylock.c b/sysdeps/s390/nptl/pthread_spin_trylock.c
index 4c00e08..d9e88ef 100644
--- a/sysdeps/s390/nptl/pthread_spin_trylock.c
+++ b/sysdeps/s390/nptl/pthread_spin_trylock.c
@@ -22,11 +22,9 @@
 int
 pthread_spin_trylock (pthread_spinlock_t *lock)
 {
-  int old;
-
-  __asm__ __volatile__ ("cs %0,%3,%1"
-			: "=d" (old), "=Q" (*lock)
-			: "0" (0), "d" (1), "m" (*lock) : "cc" );
-
-  return old != 0 ? EBUSY : 0;
+  /* The s390 atomic_compare_and_exchange_bool_acq macro called with constant
+     zero as oldval first compares the lock with normal instructions.  If it is
+     free the compare-and-swap instruction is used to aquire the lock.  */
+  return __glibc_unlikely (atomic_compare_and_exchange_bool_acq (lock, 1, 0))
+    ? EBUSY : 0;
 }
-- 
2.5.5


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]