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 3/6] Use XEND when a lock is busy in an elision attempt.


The patch replaces XABORT with XEND in case a transaction needs to be manually
aborted because the futex is locked when we have opened a transaction.  This
approach is less invasive than aborting because it keeps outer transactions
intact.  The transaction may still abort later, when the futex is acquired.
Another advantage is that we do not throw our private abort code at the creator
of the outermost transaction.

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt
IBM Germany
>From 21c16c036c0528450648f7958e760b4bc8d80a5b Mon Sep 17 00:00:00 2001
From: Dominik Vogt <vogt@de.ibm.com>
Date: Mon, 2 Sep 2013 07:10:31 +0000
Subject: [PATCH 3/7] x86: Use XEND when a lock is busy in an elision attempt.

This approach is less invasive than aborting because it keeps outer
transactions intact.  The transaction may still abort later, when the futex is
acquired.  Another advantage is that we do not throw our private abort code at
the creator of the outermost transaction.
---
 nptl/sysdeps/unix/sysv/linux/x86/elision-lock.c    | 26 ++++++++---------
 nptl/sysdeps/unix/sysv/linux/x86/elision-trylock.c | 33 +++++++++++++---------
 2 files changed, 32 insertions(+), 27 deletions(-)

diff --git a/nptl/sysdeps/unix/sysv/linux/x86/elision-lock.c b/nptl/sysdeps/unix/sysv/linux/x86/elision-lock.c
index 04f7c28..68427f9 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86/elision-lock.c
+++ b/nptl/sysdeps/unix/sysv/linux/x86/elision-lock.c
@@ -57,27 +57,25 @@ __lll_lock_elision (int *futex, short *adapt_count, EXTRAARG int private)
 	    {
 	      if (*futex == 0)
 		return 0;
-
-	      /* Lock was busy.  Fall back to normal locking.
-		 Could also _xend here but xabort with 0xff code
-		 is more visible in the profiler.  */
-	      _xabort (_ABORT_LOCK_BUSY);
+	      /* Lock was busy.  Fall back to normal locking.  Aborting could
+		 unnecessarily terminate outer transactions, not just this one,
+		 so it is less invasive to simple end the transaction here.  */
+	      __xend ();
+	      /* Note: Changing the adapt_count here might abort a transaction
+		 on a different cpu, but that could happen anyway when the futex
+		 is acquired, so there's no need to check the nesting depth
+		 here.  */
+	      if (aconf.skip_lock_busy > 0)
+		*adapt_count = aconf.skip_lock_busy;
+	      break;
 	    }
 
 	  if (!(status & _XABORT_RETRY))
 	    {
-	      if ((status & _XABORT_EXPLICIT)
-			&& _XABORT_CODE (status) == _ABORT_LOCK_BUSY)
-	        {
-		  /* Right now we skip here.  Better would be to wait a bit
-		     and retry.  This likely needs some spinning.  */
-		  if (aconf.skip_lock_busy > 0)
-		    *adapt_count = aconf.skip_lock_busy;
-		}
 	      /* Internal abort.  There is no chance for retry.
 		 Use the normal locking and next time use lock.
 		 Be careful to avoid writing to the lock.  */
-	      else if (aconf.skip_lock_internal_abort > 0)
+	      if (aconf.skip_lock_internal_abort > 0)
 		*adapt_count = aconf.skip_lock_internal_abort;
 	      break;
 	    }
diff --git a/nptl/sysdeps/unix/sysv/linux/x86/elision-trylock.c b/nptl/sysdeps/unix/sysv/linux/x86/elision-trylock.c
index be22270..0b9c686 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86/elision-trylock.c
+++ b/nptl/sysdeps/unix/sysv/linux/x86/elision-trylock.c
@@ -45,20 +45,27 @@ __lll_trylock_elision (int *futex, short *adapt_count)
 	{
 	  if (*futex == 0)
 	    return 0;
-
-	  /* Lock was busy.  Fall back to normal locking.
-	     Could also _xend here but xabort with 0xff code
-	     is more visible in the profiler.  */
-	  _xabort (_ABORT_LOCK_BUSY);
+	  /* Lock was busy.  Fall back to normal locking.  Aborting could
+	     unnecessarily terminate outer transactions, not just this one,
+	     so it is less invasive to simple end the transaction here.  */
+	  __builtin_xend ();
+	  /* Note: Changing the adapt_count here might abort a transaction
+	     on a different cpu, but that could happen anyway when the futex
+	     is acquired, so there's no need to check the nesting depth
+	     here.  */
+	  if (aconf.skip_lock_busy > 0)
+	    *adapt_count = aconf.skip_lock_busy;
+	}
+      else
+	{
+	  if (!(status & _XABORT_RETRY))
+	    {
+	      /* Internal abort.  No chance for retry.  For future
+		 locks don't try speculation for some time.  */
+	      if (aconf.skip_trylock_internal_abort > 0)
+		*adapt_count = aconf.skip_trylock_internal_abort;
+	    }
 	}
-
-      if (!(status & _XABORT_RETRY))
-        {
-          /* Internal abort.  No chance for retry.  For future
-             locks don't try speculation for some time.  */
-          if (aconf.skip_trylock_internal_abort > 0)
-            *adapt_count = aconf.skip_trylock_internal_abort;
-        }
       /* Could do some retries here.  */
     }
   else
-- 
1.7.11.4


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