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]

[RFC][PATCH 2/2] Port of lock elision on z/Architecture


Implementation of lock elision for pthread_mutexes.  More or less
identical to the corresponding Intel patch.

>From 757d335153edfaa2c349ab7dd7d6dc86d1351a5b Mon Sep 17 00:00:00 2001
From: Dominik Vogt <vogt@de.ibm.com>
Date: Wed, 10 Apr 2013 15:14:17 +0200
Subject: [PATCH 02/10] s390: Elided pthread_mutexes.

---
 .../unix/sysv/linux/s390/bits/pthreadtypes.h       | 12 ++++++++-
 nptl/sysdeps/unix/sysv/linux/s390/elision-lock.c   | 14 +++++-----
 .../sysdeps/unix/sysv/linux/s390/elision-trylock.c | 15 +++++------
 nptl/sysdeps/unix/sysv/linux/s390/elision-unlock.c |  4 +--
 nptl/sysdeps/unix/sysv/linux/s390/force-elision.h  | 31 ++++++++++++++++++++++
 .../unix/sysv/linux/s390/pthread_mutex_cond_lock.c | 22 +++++++++++++++
 .../unix/sysv/linux/s390/pthread_mutex_lock.c      | 22 +++++++++++++++
 .../unix/sysv/linux/s390/pthread_mutex_timedlock.c | 22 +++++++++++++++
 .../unix/sysv/linux/s390/pthread_mutex_trylock.c   | 22 +++++++++++++++
 .../unix/sysv/linux/s390/pthread_mutex_unlock.c    | 19 +++++++++++++
 10 files changed, 166 insertions(+), 17 deletions(-)
 create mode 100644 nptl/sysdeps/unix/sysv/linux/s390/force-elision.h
 create mode 100644 nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_cond_lock.c
 create mode 100644 nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_lock.c
 create mode 100644 nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_timedlock.c
 create mode 100644 nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_trylock.c
 create mode 100644 nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_unlock.c

diff --git a/nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h
index 75785d9..2a7c998 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h
+++ b/nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h
@@ -89,13 +89,23 @@ typedef union
        binary compatibility.  */
     int __kind;
 #if __WORDSIZE == 64
-    int __spins;
+    short __spins;
+    short __elision;
     __pthread_list_t __list;
 # define __PTHREAD_MUTEX_HAVE_PREV	1
+# define __PTHREAD_MUTEX_HAVE_ELISION   1
 #else
     unsigned int __nusers;
     __extension__ union
     {
+      struct
+      {
+	short __espins;
+	short __elision;
+# define __spins d.__espins
+# define __elision d.__elision
+# define __PTHREAD_MUTEX_HAVE_ELISION   2
+      } d;
       int __spins;
       __pthread_slist_t __list;
     };
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/elision-lock.c b/nptl/sysdeps/unix/sysv/linux/s390/elision-lock.c
index 962ced6..ec0db56 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/elision-lock.c
+++ b/nptl/sysdeps/unix/sysv/linux/s390/elision-lock.c
@@ -17,8 +17,8 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <pthread.h>
-#include "pthreadP.h"
-#include "lowlevellock.h"
+#include <pthreadP.h>
+#include <lowlevellock.h>
 #include "htm.h"
 #include <elision-conf.h>
 #include "elision-common.h"
@@ -55,7 +55,8 @@ __lll_lock_elision (int *futex, short *adapt_count, EXTRAARG int private)
 	   try_xbegin > 0;
 	   try_xbegin--)
 	{
-	  if (__builtin_expect((status = _tbegin()) == _TBEGIN_OK, 1))
+	  if (__builtin_expect
+	      ((status = __builtin_tbegin((void *)0)) == _TBEGIN_OK, 1))
 	    {
 	      if (*futex == 0)
 		return 0;
@@ -63,8 +64,9 @@ __lll_lock_elision (int *futex, short *adapt_count, EXTRAARG int private)
 	      /* Lock was busy.  Fall back to normal locking.  We cannot use
 		 _tend here because this might not be the outermost
 		 transaction.  */
-	      _ntstg (_ABORT_LOCK_BUSY, &__rtm_explicit_abort_rc);
-	      _tabort (_ABORT_LOCK_BUSY);
+	      __builtin_non_tx_store (&__rtm_explicit_abort_rc,
+				      _ABORT_LOCK_BUSY);
+	      __builtin_tabort (_ABORT_LOCK_BUSY);
 	    }
 
 	  asm volatile (
@@ -75,7 +77,7 @@ __lll_lock_elision (int *futex, short *adapt_count, EXTRAARG int private)
 
 	  if (status != _TABORT_RETRY)
 	    {
-	      if (__rtm_explicit_abort_rc == _ABORT_LOCK_BUSY)
+	      if (explicit_abort_rc == _ABORT_LOCK_BUSY)
 	        {
 		  /* Right now we skip here.  Better would be to wait a bit
 		     and retry.  This likely needs some spinning.  */
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/elision-trylock.c b/nptl/sysdeps/unix/sysv/linux/s390/elision-trylock.c
index 3501e17..9eed967 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/elision-trylock.c
+++ b/nptl/sysdeps/unix/sysv/linux/s390/elision-trylock.c
@@ -35,19 +35,19 @@ __lll_trylock_elision (int *futex, short *adapt_count)
      trylock.  Sorry.  After the abort the code is re-executed
      non transactional and if the lock was already locked
      return an error.  */
-  if (_etnd() > 0)
+  if (__builtin_tx_nesting_depth () > 0)
     {
-      _ntstg (_ABORT_NESTED_TRYLOCK, &__rtm_explicit_abort_rc);
-      _tabort (_ABORT_NESTED_TRYLOCK);
+      __builtin_non_tx_store (&__rtm_explicit_abort_rc, _ABORT_NESTED_TRYLOCK);
+      __builtin_tabort (_ABORT_NESTED_TRYLOCK);
     }
 
   /* Only try a transaction if it's worth it.  */
   if (*adapt_count <= 0)
     {
       unsigned status;
-      uint64_t explicit_abort_rc;
 
-      if (__builtin_expect((status = _tbegin()) == _TBEGIN_OK, 1))
+      if (__builtin_expect
+	  ((status = __builtin_tbegin ((void *)0)) == _TBEGIN_OK, 1))
 	{
 	  if (*futex == 0)
 	    return 0;
@@ -55,14 +55,13 @@ __lll_trylock_elision (int *futex, short *adapt_count)
 	  /* Lock was busy.  Fall back to normal locking.  We cannot use
 	     _tend here because this might not be the outermost
 	     transaction.  */
-	  _ntstg (_ABORT_LOCK_BUSY, &__rtm_explicit_abort_rc);
-	  _tabort (_ABORT_LOCK_BUSY);
+	  __builtin_non_tx_store (&__rtm_explicit_abort_rc, _ABORT_LOCK_BUSY);
+	  __builtin_tabort (_ABORT_LOCK_BUSY);
 	}
 
       asm volatile (
 	"" ::: "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9",
 	"f10", "f11", "f12", "f13", "f14", "f15", "cc", "memory");
-      explicit_abort_rc = __rtm_explicit_abort_rc;
       __rtm_explicit_abort_rc = 0;
       if (status != _TABORT_RETRY)
         {
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/elision-unlock.c b/nptl/sysdeps/unix/sysv/linux/s390/elision-unlock.c
index 7987311..ac42d24 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/elision-unlock.c
+++ b/nptl/sysdeps/unix/sysv/linux/s390/elision-unlock.c
@@ -29,10 +29,10 @@ __lll_unlock_elision(int *lock, int private)
     {
       /* The instruction ETND is slower than TEND, so the latter is used to
 	 check whether there was an active transaction.  */
-      if (__builtin_expect(_tend() != 0, 0))
+      if (__builtin_expect (__builtin_tend() != 0, 0))
 	{
 	  /* Lock released outside a transaction.  */
-	  abort();
+	  abort ();
 	}
     }
   else
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/force-elision.h b/nptl/sysdeps/unix/sysv/linux/s390/force-elision.h
new file mode 100644
index 0000000..9789905
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/s390/force-elision.h
@@ -0,0 +1,31 @@
+/* force-elision.h: Automatic enabling of elision for mutexes
+   Copyright (C) 2013 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/>.  */
+
+/* Check for elision on this lock without upgrading.  */
+#define DO_ELISION(m)							\
+  (__pthread_force_elision						\
+   && (m->__data.__kind & PTHREAD_MUTEX_NO_ELISION_NP) == 0)		\
+
+/* Automatically enable elision for existing user lock kinds.  */
+#define FORCE_ELISION(m, s)						\
+  if (__pthread_force_elision						\
+      && (m->__data.__kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0)	\
+    {									\
+      mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP;			\
+      s;								\
+    }
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_cond_lock.c b/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_cond_lock.c
new file mode 100644
index 0000000..fe64e02
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_cond_lock.c
@@ -0,0 +1,22 @@
+/* Copyright (C) 2013 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/>.  */
+
+/* The cond lock is not actually elided yet, but we still need to handle
+   already elided locks.  */
+#include <elision-conf.h>
+
+#include "sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c"
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_lock.c b/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_lock.c
new file mode 100644
index 0000000..37b122f
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_lock.c
@@ -0,0 +1,22 @@
+/* Elided version of pthread_mutex_lock.
+   Copyright (C) 2011, 2012, 2013 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/>.  */
+
+#include <elision-conf.h>
+#include "force-elision.h"
+
+#include "nptl/pthread_mutex_lock.c"
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_timedlock.c b/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_timedlock.c
new file mode 100644
index 0000000..ddc6d92
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_timedlock.c
@@ -0,0 +1,22 @@
+/* Elided version of pthread_mutex_timedlock.
+   Copyright (C) 2011, 2012, 2013 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/>.  */
+
+#include <elision-conf.h>
+#include "force-elision.h"
+
+#include "nptl/pthread_mutex_timedlock.c"
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_trylock.c b/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_trylock.c
new file mode 100644
index 0000000..0148aca
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_trylock.c
@@ -0,0 +1,22 @@
+/* Elided version of pthread_mutex_trylock.
+   Copyright (C) 2011, 2012, 2013 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/>.  */
+
+#include <elision-conf.h>
+#include "force-elision.h"
+
+#include "nptl/pthread_mutex_trylock.c"
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_unlock.c b/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_unlock.c
new file mode 100644
index 0000000..5af5c59
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/s390/pthread_mutex_unlock.c
@@ -0,0 +1,19 @@
+/* Elided version of pthread_mutex_trylock.
+   Copyright (C) 2011, 2012, 2013 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/>.  */
+
+#include "nptl/pthread_mutex_unlock.c"
-- 
1.7.11.4

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt
IBM Germany


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