This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[trans-mem] fix futex syscall for x86_64
- From: Aldy Hernandez <aldyh at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org, rth at redhat dot com
- Date: Mon, 22 Mar 2010 12:01:26 -0400
- Subject: [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)
{