commit 2110f18d944bcb018f57d35b1efe19b9b5f78b1a
Author: Stefan Liebler <stli@linux.vnet.ibm.com>
Date:   Wed Feb 15 10:19:27 2017 +0100

    Optimize generic spinlock code and use C11 like atomic macros.
    
    This patch optimizes the generic spinlock code.
    
    The type pthread_spinlock_t is a typedef to volatile int on all archs.
    Passing a volatile pointer to the atomic macros can lead to extra stores
    and loads to stack if such a macro creates a temporary variable by using
    "__typeof (*(mem)) tmp;".  Thus, those macros which are used by spinlock code -
    atomic_exchange_acquire, atomic_load_relaxed,
    atomic_compare_exchange_weak_acquire - have to be adjusted.
    According to the comment from  Szabolcs Nagy, the type of a cast expression is
    unqualified (see http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_423.htm):
    __typeof ((__typeof (*(mem)) *(mem)) tmp;
    This patch adjusts those macros in include/atomic.h.
    
    The atomic macros are replaced by the C11 like atomic macros and thus
    the code is aligned to it.  The pthread_spin_unlock implementation is now
    using release memory order instead of sequentially consistent memory order.
    The issue with passed volatile int pointers applies to the C11 like atomic
    macros as well as the ones used before.
    
    I've added a glibc_likely hint to the first atomic exchange in
    pthread_spin_lock in order to return immediately to the caller if the lock is
    free.  Without the hint, there is an additional jump if the lock is free.
    
    I've added the atomic_spin_nop macro within the loop of plain reads.
    The plain reads are also realized by C11 like atomic_load_relaxed macro.
    
    For pthread_spin_trylock, a machine-specific version can define
    SPIN_TRYLOCK_LOAD_AND_TEST_BEFORE_XCHG to 1 if an explicit test if
    lock is free is optimal.
    
    An architecture which wants to use the generic spinlock implementation
    has to create the file pthread_spin_parameters.h with the definition of
    the following parameter macros instead of creating a wrapper file which
    includes nptl/pthread_spin_lock.c:
    SPIN_LOCK_READS_BETWEEN_CMPXCHG
    SPIN_TRYLOCK_LOAD_AND_TEST_BEFORE_XCHG
    
    ChangeLog:
    
    	* NEWS: Mention new spinlock implementation.
    	* include/atomic.h:
    	(__atomic_val_bysize): Cast type to omit volatile qualifier.
    	(atomic_exchange_acq): Likewise.
    	(atomic_load_relaxed): Likewise.
    	* nptl/pthread_spin_init.c (pthread_spin_init):
    	Use atomic_store_relaxed.
    	* nptl/pthread_spin_lock.c (pthread_spin_lock):
    	Use C11-like atomic macros.
    	* nptl/pthread_spin_trylock.c
    	(pthread_spin_trylock): Likewise.  Use an explicit load and
    	test if lock is free before exchange,  if new macro
    	SPIN_TRYLOCK_LOAD_AND_TEST_BEFORE_XCHG macro is set to one.
    	* nptl/pthread_spin_unlock.c (pthread_spin_unlock):
    	Use atomic_store_release.
    	* nptl/pthread_spin_parameters.h: New File.
    	* sysdeps/aarch64/nptl/pthread_spin_lock.c: Delete File.
    	* sysdeps/aarch64/nptl/pthread_spin_parameters.h: New File.
    	* sysdeps/arm/nptl/pthread_spin_lock.c: Delete File.
    	* sysdeps/arm/nptl/pthread_spin_parameters.h: New File.
    	* sysdeps/hppa/nptl/pthread_spin_lock.c: Delete File.
    	* sysdeps/hppa/nptl/pthread_spin_parameters.h: New File.
    	* sysdeps/m68k/nptl/pthread_spin_lock.c: Delete File.
    	* sysdeps/m68k/nptl/pthread_spin_parameters.h: New File.
    	* sysdeps/microblaze/nptl/pthread_spin_lock.c: Delete File.
    	* sysdeps/microblaze/nptl/pthread_spin_parameters.h: New File.
    	* sysdeps/mips/nptl/pthread_spin_lock.c: Delete File.
    	* sysdeps/mips/nptl/pthread_spin_parameters.h: New File.
    	* sysdeps/nios2/nptl/pthread_spin_lock.c: Delete File.
    	* sysdeps/nios2/nptl/pthread_spin_parameters.h: New File.

diff --git a/NEWS b/NEWS
index b5a401c..b85b734 100644
--- a/NEWS
+++ b/NEWS
@@ -7,7 +7,9 @@ using `glibc' in the "product" field.
 
 Version 2.26
 
-[Add important changes here]
+* The new generic spinlock implementation uses C11 like atomics.
+  The pthread_spin_unlock implementation is now using release
+  memory order instead of sequentially consistent memory order.
 
 Security related changes:
 
diff --git a/include/atomic.h b/include/atomic.h
index 7f32640..770db4a 100644
--- a/include/atomic.h
+++ b/include/atomic.h
@@ -54,7 +54,7 @@
    and following args.  */
 #define __atomic_val_bysize(pre, post, mem, ...)			      \
   ({									      \
-    __typeof (*mem) __atg1_result;					      \
+    __typeof ((__typeof (*(mem))) *(mem)) __atg1_result;		      \
     if (sizeof (*mem) == 1)						      \
       __atg1_result = pre##_8_##post (mem, __VA_ARGS__);		      \
     else if (sizeof (*mem) == 2)					      \
@@ -162,9 +162,9 @@
 /* Store NEWVALUE in *MEM and return the old value.  */
 #ifndef atomic_exchange_acq
 # define atomic_exchange_acq(mem, newvalue) \
-  ({ __typeof (*(mem)) __atg5_oldval;					      \
+  ({ __typeof ((__typeof (*(mem))) *(mem)) __atg5_oldval;		      \
      __typeof (mem) __atg5_memp = (mem);				      \
-     __typeof (*(mem)) __atg5_value = (newvalue);			      \
+     __typeof ((__typeof (*(mem))) *(mem)) __atg5_value = (newvalue);	      \
 									      \
      do									      \
        __atg5_oldval = *__atg5_memp;					      \
@@ -668,7 +668,7 @@ void __atomic_link_error (void);
 
 # ifndef atomic_load_relaxed
 #  define atomic_load_relaxed(mem) \
-   ({ __typeof (*(mem)) __atg100_val;					      \
+   ({ __typeof ((__typeof (*(mem))) *(mem)) __atg100_val;		      \
    __asm ("" : "=r" (__atg100_val) : "0" (*(mem)));			      \
    __atg100_val; })
 # endif
diff --git a/nptl/pthread_spin_init.c b/nptl/pthread_spin_init.c
index 01dec5e..fe30913 100644
--- a/nptl/pthread_spin_init.c
+++ b/nptl/pthread_spin_init.c
@@ -22,6 +22,7 @@
 int
 pthread_spin_init (pthread_spinlock_t *lock, int pshared)
 {
-  *lock = 0;
+  /* Relaxed MO is fine because this is an initializing store.  */
+  atomic_store_relaxed (lock, 0);
   return 0;
 }
diff --git a/nptl/pthread_spin_lock.c b/nptl/pthread_spin_lock.c
index 4d03b78..65d34a3 100644
--- a/nptl/pthread_spin_lock.c
+++ b/nptl/pthread_spin_lock.c
@@ -18,15 +18,7 @@
 
 #include <atomic.h>
 #include "pthreadP.h"
-
-/* A machine-specific version can define SPIN_LOCK_READS_BETWEEN_CMPXCHG
-  to the number of plain reads that it's optimal to spin on between uses
-  of atomic_compare_and_exchange_val_acq.  If spinning forever is optimal
-  then use -1.  If no plain reads here would ever be optimal, use 0.  */
-#ifndef SPIN_LOCK_READS_BETWEEN_CMPXCHG
-# warning machine-dependent file should define SPIN_LOCK_READS_BETWEEN_CMPXCHG
-# define SPIN_LOCK_READS_BETWEEN_CMPXCHG 1000
-#endif
+#include <pthread_spin_parameters.h>
 
 int
 pthread_spin_lock (pthread_spinlock_t *lock)
@@ -37,10 +29,14 @@ pthread_spin_lock (pthread_spinlock_t *lock)
      when the lock is locked.
      We assume that the first try mostly will be successful, and we use
      atomic_exchange.  For the subsequent tries we use
-     atomic_compare_and_exchange.  */
-  if (atomic_exchange_acq (lock, 1) == 0)
+     atomic_compare_and_exchange.
+     We use acquire MO to synchronize-with the release MO store in
+     pthread_spin_unlock, and thus ensure that prior critical sections
+     happen-before this critical section.  */
+  if (__glibc_likely (atomic_exchange_acquire (lock, 1) == 0))
     return 0;
 
+  int val;
   do
     {
       /* The lock is contended and we need to wait.  Going straight back
@@ -50,20 +46,39 @@ pthread_spin_lock (pthread_spinlock_t *lock)
 	 On the other hand, we do want to update memory state on the local core
 	 once in a while to avoid spinning indefinitely until some event that
 	 will happen to update local memory as a side-effect.  */
-      if (SPIN_LOCK_READS_BETWEEN_CMPXCHG >= 0)
+
+#if SPIN_LOCK_READS_BETWEEN_CMPXCHG >= 0
+      /* Use at most SPIN_LOCK_READS_BETWEEN_CMPXCHG relaxed MO reads between
+	 the atomic compare and exchanges.  */
+      int wait;
+      for (wait = 0; wait < SPIN_LOCK_READS_BETWEEN_CMPXCHG;  wait ++)
 	{
-	  int wait = SPIN_LOCK_READS_BETWEEN_CMPXCHG;
+	  atomic_spin_nop ();
 
-	  while (*lock != 0 && wait > 0)
-	    --wait;
+	  val = atomic_load_relaxed (lock);
+	  if (val == 0)
+	    break;
 	}
-      else
+
+      /* Set expected value to zero for the next compare and exchange.  */
+      val = 0;
+
+#else /* SPIN_LOCK_READS_BETWEEN_CMPXCHG < 0  */
+      /* Use relaxed MO reads until we observe the lock to not be acquired
+	 anymore.  */
+      do
 	{
-	  while (*lock != 0)
-	    ;
+	  atomic_spin_nop ();
+
+	  val = atomic_load_relaxed (lock);
 	}
+      while (val != 0);
+
+#endif
+      /* We need acquire memory order here for the same reason as mentioned
+	 for the first try to lock the spinlock.  */
     }
-  while (atomic_compare_and_exchange_val_acq (lock, 1, 0) != 0);
+  while (!atomic_compare_exchange_weak_acquire (lock, &val, 1));
 
   return 0;
 }
diff --git a/nptl/pthread_spin_parameters.h b/nptl/pthread_spin_parameters.h
new file mode 100644
index 0000000..6cde482
--- /dev/null
+++ b/nptl/pthread_spin_parameters.h
@@ -0,0 +1,35 @@
+/* Parameters for generic pthread_spinlock_t implementation.  Generic version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* A machine-specific version can define SPIN_LOCK_READS_BETWEEN_CMPXCHG
+   to the number of plain reads that it's optimal to spin on between uses
+   of atomic_compare_exchange_weak_acquire.  If spinning forever is optimal,
+   then use -1.  If no plain reads here would ever be optimal, use 0.  */
+#ifndef SPIN_LOCK_READS_BETWEEN_CMPXCHG
+# warning machine-dependent file should define SPIN_LOCK_READS_BETWEEN_CMPXCHG
+# define SPIN_LOCK_READS_BETWEEN_CMPXCHG 1000
+#endif
+
+/* A machine-specific version can define SPIN_TRYLOCK_LOAD_AND_TEST_BEFORE_XCHG
+   to 1 if an explicit load and test if lock is not acquired before executing
+   atomic_exchange_acquire is optimal.  Define to 0 to execute
+   atomic_exchange_acquire without an additional load and test.  */
+#ifndef SPIN_TRYLOCK_LOAD_AND_TEST_BEFORE_XCHG
+# warning machine-dependent file should define SPIN_TRYLOCK_LOAD_AND_TEST_BEFORE_XCHG
+# define SPIN_TRYLOCK_LOAD_AND_TEST_BEFORE_XCHG 0
+#endif
diff --git a/nptl/pthread_spin_trylock.c b/nptl/pthread_spin_trylock.c
index 593bba3..1e22843 100644
--- a/nptl/pthread_spin_trylock.c
+++ b/nptl/pthread_spin_trylock.c
@@ -19,9 +19,28 @@
 #include <errno.h>
 #include <atomic.h>
 #include "pthreadP.h"
+#include <pthread_spin_parameters.h>
 
 int
 pthread_spin_trylock (pthread_spinlock_t *lock)
 {
-  return atomic_exchange_acq (lock, 1) ? EBUSY : 0;
+  /* We use acquire MO to synchronize-with the release MO store in
+     pthread_spin_unlock, and thus ensure that prior critical sections
+     happen-before this critical section.  */
+#if SPIN_TRYLOCK_LOAD_AND_TEST_BEFORE_XCHG == 1
+  /* Load and test the spinlock and only try to acquire the lock if it has
+     not been acquired.  */
+  int val = atomic_load_relaxed (lock);
+  if (__glibc_likely (val == 0 && atomic_exchange_acquire (lock, 1) == 0))
+    return 0;
+#elif SPIN_TRYLOCK_LOAD_AND_TEST_BEFORE_XCHG == 0
+  /* Try to acquire the lock, which succeeds if the lock had not been
+     acquired.  */
+  if (__glibc_likely (atomic_exchange_acquire (lock, 1) == 0))
+    return 0;
+#else
+# error SPIN_TRYLOCK_LOAD_AND_TEST_BEFORE_XCHG has to be defined to 0 or 1
+#endif
+
+  return EBUSY;
 }
diff --git a/nptl/pthread_spin_unlock.c b/nptl/pthread_spin_unlock.c
index 5fd73e5..f83b696 100644
--- a/nptl/pthread_spin_unlock.c
+++ b/nptl/pthread_spin_unlock.c
@@ -23,7 +23,9 @@
 int
 pthread_spin_unlock (pthread_spinlock_t *lock)
 {
-  atomic_full_barrier ();
-  *lock = 0;
+  /* The atomic_store_release synchronizes-with the atomic_exchange_acquire
+     or atomic_compare_exchange_weak_acquire in pthread_spin_lock /
+     pthread_spin_trylock.  */
+  atomic_store_release (lock, 0);
   return 0;
 }
diff --git a/sysdeps/aarch64/nptl/pthread_spin_lock.c b/sysdeps/aarch64/nptl/pthread_spin_lock.c
deleted file mode 100644
index fcfcb40..0000000
--- a/sysdeps/aarch64/nptl/pthread_spin_lock.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Copyright (C) 2008-2017 Free Software Foundation, Inc.
-
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public License as
-   published by the Free Software Foundation; either version 2.1 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#define SPIN_LOCK_READS_BETWEEN_CMPXCHG 1000
-
-/* We can't use the normal "#include <nptl/pthread_spin_lock.c>" because
-   it will resolve to this very file.  Using "sysdeps/.." as reference to the
-   top level directory does the job.  */
-#include <sysdeps/../nptl/pthread_spin_lock.c>
diff --git a/sysdeps/aarch64/nptl/pthread_spin_parameters.h b/sysdeps/aarch64/nptl/pthread_spin_parameters.h
new file mode 100644
index 0000000..5fd319c
--- /dev/null
+++ b/sysdeps/aarch64/nptl/pthread_spin_parameters.h
@@ -0,0 +1,22 @@
+/* Parameters for generic pthread_spinlock_t implementation.  aarch64 version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define SPIN_LOCK_READS_BETWEEN_CMPXCHG 1000
+#define SPIN_TRYLOCK_LOAD_AND_TEST_BEFORE_XCHG 0
+
+#include_next <pthread_spin_parameters.h>
diff --git a/sysdeps/arm/nptl/pthread_spin_lock.c b/sysdeps/arm/nptl/pthread_spin_lock.c
deleted file mode 100644
index 037b3b8..0000000
--- a/sysdeps/arm/nptl/pthread_spin_lock.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Copyright (C) 2008-2017 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library.  If not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#define SPIN_LOCK_READS_BETWEEN_CMPXCHG 1000
-
-/* We can't use the normal "#include <nptl/pthread_spin_lock.c>" because
-   it will resolve to this very file.  Using "sysdeps/.." as reference to the
-   top level directory does the job.  */
-#include <sysdeps/../nptl/pthread_spin_lock.c>
diff --git a/sysdeps/arm/nptl/pthread_spin_parameters.h b/sysdeps/arm/nptl/pthread_spin_parameters.h
new file mode 100644
index 0000000..3f8285a
--- /dev/null
+++ b/sysdeps/arm/nptl/pthread_spin_parameters.h
@@ -0,0 +1,22 @@
+/* Parameters for generic pthread_spinlock_t implementation.  arm version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define SPIN_LOCK_READS_BETWEEN_CMPXCHG 1000
+#define SPIN_TRYLOCK_LOAD_AND_TEST_BEFORE_XCHG 0
+
+#include_next <pthread_spin_parameters.h>
diff --git a/sysdeps/hppa/nptl/pthread_spin_lock.c b/sysdeps/hppa/nptl/pthread_spin_lock.c
deleted file mode 100644
index 14f36a6..0000000
--- a/sysdeps/hppa/nptl/pthread_spin_lock.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Copyright (C) 2005-2017 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library.  If not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#define SPIN_LOCK_READS_BETWEEN_CMPXCHG 1000
-
-/* We can't use the normal "#include <nptl/pthread_spin_lock.c>" because
-   it will resolve to this very file.  Using "sysdeps/.." as reference to the
-   top level directory does the job.  */
-#include <sysdeps/../nptl/pthread_spin_lock.c>
diff --git a/sysdeps/hppa/nptl/pthread_spin_parameters.h b/sysdeps/hppa/nptl/pthread_spin_parameters.h
new file mode 100644
index 0000000..ebeb162
--- /dev/null
+++ b/sysdeps/hppa/nptl/pthread_spin_parameters.h
@@ -0,0 +1,22 @@
+/* Parameters for generic pthread_spinlock_t implementation.  hppa version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define SPIN_LOCK_READS_BETWEEN_CMPXCHG 1000
+#define SPIN_TRYLOCK_LOAD_AND_TEST_BEFORE_XCHG 0
+
+#include_next <pthread_spin_parameters.h>
diff --git a/sysdeps/m68k/nptl/pthread_spin_lock.c b/sysdeps/m68k/nptl/pthread_spin_lock.c
deleted file mode 100644
index 62795f4..0000000
--- a/sysdeps/m68k/nptl/pthread_spin_lock.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Copyright (C) 2010-2017 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Maxim Kuvyrkov <maxim@codesourcery.com>, 2010.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library.  If not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#define SPIN_LOCK_READS_BETWEEN_CMPXCHG 1000
-
-/* We can't use the normal "#include <nptl/pthread_spin_lock.c>" because
-   it will resolve to this very file.  Using "sysdeps/.." as reference to the
-   top level directory does the job.  */
-#include <sysdeps/../nptl/pthread_spin_lock.c>
diff --git a/sysdeps/m68k/nptl/pthread_spin_parameters.h b/sysdeps/m68k/nptl/pthread_spin_parameters.h
new file mode 100644
index 0000000..b7b8581
--- /dev/null
+++ b/sysdeps/m68k/nptl/pthread_spin_parameters.h
@@ -0,0 +1,22 @@
+/* Parameters for generic pthread_spinlock_t implementation.  m68k version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define SPIN_LOCK_READS_BETWEEN_CMPXCHG 1000
+#define SPIN_TRYLOCK_LOAD_AND_TEST_BEFORE_XCHG 0
+
+#include_next <pthread_spin_parameters.h>
diff --git a/sysdeps/microblaze/nptl/pthread_spin_lock.c b/sysdeps/microblaze/nptl/pthread_spin_lock.c
deleted file mode 100644
index fcfcb40..0000000
--- a/sysdeps/microblaze/nptl/pthread_spin_lock.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Copyright (C) 2008-2017 Free Software Foundation, Inc.
-
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public License as
-   published by the Free Software Foundation; either version 2.1 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#define SPIN_LOCK_READS_BETWEEN_CMPXCHG 1000
-
-/* We can't use the normal "#include <nptl/pthread_spin_lock.c>" because
-   it will resolve to this very file.  Using "sysdeps/.." as reference to the
-   top level directory does the job.  */
-#include <sysdeps/../nptl/pthread_spin_lock.c>
diff --git a/sysdeps/microblaze/nptl/pthread_spin_parameters.h b/sysdeps/microblaze/nptl/pthread_spin_parameters.h
new file mode 100644
index 0000000..ef5827b
--- /dev/null
+++ b/sysdeps/microblaze/nptl/pthread_spin_parameters.h
@@ -0,0 +1,23 @@
+/* Parameters for generic pthread_spinlock_t implementation.
+   microblaze version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define SPIN_LOCK_READS_BETWEEN_CMPXCHG 1000
+#define SPIN_TRYLOCK_LOAD_AND_TEST_BEFORE_XCHG 0
+
+#include_next <pthread_spin_parameters.h>
diff --git a/sysdeps/mips/nptl/pthread_spin_lock.c b/sysdeps/mips/nptl/pthread_spin_lock.c
deleted file mode 100644
index 19d87a5..0000000
--- a/sysdeps/mips/nptl/pthread_spin_lock.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Copyright (C) 2012-2017 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library.  If not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#define SPIN_LOCK_READS_BETWEEN_CMPXCHG 1000
-
-/* We can't use the normal "#include <nptl/pthread_spin_lock.c>" because
-   it will resolve to this very file.  Using "sysdeps/.." as reference to the
-   top level directory does the job.  */
-#include <sysdeps/../nptl/pthread_spin_lock.c>
diff --git a/sysdeps/mips/nptl/pthread_spin_parameters.h b/sysdeps/mips/nptl/pthread_spin_parameters.h
new file mode 100644
index 0000000..4f03890
--- /dev/null
+++ b/sysdeps/mips/nptl/pthread_spin_parameters.h
@@ -0,0 +1,22 @@
+/* Parameters for generic pthread_spinlock_t implementation.  mips version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define SPIN_LOCK_READS_BETWEEN_CMPXCHG 1000
+#define SPIN_TRYLOCK_LOAD_AND_TEST_BEFORE_XCHG 0
+
+#include_next <pthread_spin_parameters.h>
diff --git a/sysdeps/nios2/nptl/pthread_spin_lock.c b/sysdeps/nios2/nptl/pthread_spin_lock.c
deleted file mode 100644
index b203469..0000000
--- a/sysdeps/nios2/nptl/pthread_spin_lock.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/* pthread spin-lock implementation for Nios II.
-   Copyright (C) 2005-2017 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library.  If not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#define SPIN_LOCK_READS_BETWEEN_CMPXCHG 1000
-
-/* We can't use the normal "#include <nptl/pthread_spin_lock.c>" because
-   it will resolve to this very file.  Using "sysdeps/.." as reference to the
-   top level directory does the job.  */
-#include <sysdeps/../nptl/pthread_spin_lock.c>
diff --git a/sysdeps/nios2/nptl/pthread_spin_parameters.h b/sysdeps/nios2/nptl/pthread_spin_parameters.h
new file mode 100644
index 0000000..237edb3
--- /dev/null
+++ b/sysdeps/nios2/nptl/pthread_spin_parameters.h
@@ -0,0 +1,22 @@
+/* Parameters for generic pthread_spinlock_t implementation.  nios2 version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define SPIN_LOCK_READS_BETWEEN_CMPXCHG 1000
+#define SPIN_TRYLOCK_LOAD_AND_TEST_BEFORE_XCHG 0
+
+#include_next <pthread_spin_parameters.h>
