This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

[trans-mem] fix futex syscall for x86_64


The futex (wait) syscall on x86_64 has the timeout (struct timespec *)
passed in r10.  Not setting it was causing many sporadic failures in
libitm/testsuite/libitm.c/simple-2.c.

The following patch sets r10 appropriately.  Unfortunately, we still
have (less) sporadic deadlocks on the x86_64 futex implementation.  The
POSIX variants (--disable-linux-futex) does not exhibit this problem.

I will look into the remaining deadlock issue(s) next.

BTW, I added a macro below, as I didn't want to redesign everything to
look like the libgomp futex implementation.  Not because I dislike it,
but because it's easier this way.

OK for branch?

	* futex.cc (sys_futex0_wait): Define.
	(futex_wait): Use it.
	* futex_bits.h (sys_futex0_wait): Define.
	(x86_64_sys_futex0_wait): New.

Index: config/linux/futex.cc
===================================================================
--- config/linux/futex.cc	(revision 157626)
+++ config/linux/futex.cc	(working copy)
@@ -38,6 +38,11 @@ namespace GTM HIDDEN {
 static long int gtm_futex_wait = FUTEX_WAIT | FUTEX_PRIVATE_FLAG;
 static long int gtm_futex_wake = FUTEX_WAKE | FUTEX_PRIVATE_FLAG;
 
+/* Define sys_futex0_wait if backend's wait syscall is different than
+   the wake.  See x86_64 for an example.  */
+#ifndef sys_futex0_wait
+#define sys_futex0_wait sys_futex0
+#endif
 
 void
 futex_wait (int *addr, int val)
@@ -51,12 +56,12 @@ futex_wait (int *addr, int val)
     else
       cpu_relax ();
 
-  res = sys_futex0 (addr, gtm_futex_wait, val);
+  res = sys_futex0_wait (addr, gtm_futex_wait, val);
   if (__builtin_expect (res == -ENOSYS, 0))
     {
       gtm_futex_wait = FUTEX_WAIT;
       gtm_futex_wake = FUTEX_WAKE;
-      res = sys_futex0 (addr, FUTEX_WAIT, val);
+      res = sys_futex0_wait (addr, FUTEX_WAIT, val);
     }
   if (__builtin_expect (res < 0, 0))
     {
Index: config/linux/x86/futex_bits.h
===================================================================
--- config/linux/x86/futex_bits.h	(revision 157626)
+++ config/linux/x86/futex_bits.h	(working copy)
@@ -27,6 +27,24 @@
 #  define SYS_futex	202
 # endif
 
+#define sys_futex0_wait x86_64_sys_futex0_wait
+
+static inline long
+x86_64_sys_futex0_wait (int *addr, long op, long val)
+{
+  register long r10 __asm__("%r10");
+  long res;
+
+  r10 = 0;			/* Wait indefinitely.  */
+  __asm volatile ("syscall"
+		  : "=a" (res)
+		  : "0" (SYS_futex), "D" (addr), "S" (op),
+		    "d" (val), "r" (r10)
+		  : "r11", "rcx", "memory");
+
+  return res;
+}
+
 static inline long
 sys_futex0 (int *addr, long op, long val)
 {


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