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] Have x86 and x86_64 lll_futex_wake return the syscall error.


It is very very possible that the futex syscall returns an
error and that the caller of lll_futex_wake may want to
look at that error and propagate the failure.

In the current i386 and x86-64 implementations of pthread_once
we don't currently check for a failure in lll_futex_wake
but we *should* for the sake of correctness and robustness.
It's this kind of problem which eventually results in
hard to track down bugs in the nptl code.

I first noticed this when I was testing removing the pthread_once
assembly implementation for x86 and x86_64 and looking at the
performance difference. Regardless of the results of that analysis,
which isn't done, and which Torvald is now initially tackling as the
pthread_once unification work[1], this is a good step forward.

This patch is a first step and ensures that a status is returned
for the lll_futex_wake call so we can detect failures.

No regressions in either x86 or x86-64.

OK to commit?

[1] http://sourceware.org/bugzilla/show_bug.cgi?id=15215

nptl/

2013-05-24  Carlos O'Donell  <carlos@redhat.com>

	* sysdeps/unix/sysv/linux/i386/lowlevellock.h
	(lll_futex_wake): Return syscall error.
	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
	(lll_futex_wake): Return syscall error.

diff --git a/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
index f51f650..f665ac9 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
@@ -224,20 +224,21 @@ LLL_STUB_UNWIND_INFO_END
 
 
 #define lll_futex_wake(futex, nr, private) \
-  do {                                                                       \
-    int __ignore;                                                            \
+  ({                                                                         \
+    int __status;                                                            \
     register __typeof (nr) _nr asm ("edx") = (nr);                           \
     LIBC_PROBE (lll_futex_wake, 3, futex, nr, private);                       \
     __asm __volatile (LLL_EBX_LOAD                                           \
                      LLL_ENTER_KERNEL                                        \
                      LLL_EBX_LOAD                                            \
-                     : "=a" (__ignore)                                       \
+                     : "=a" (__status)                                       \
                      : "0" (SYS_futex), LLL_EBX_REG (futex),                 \
                        "c" (__lll_private_flag (FUTEX_WAKE, private)),       \
                        "d" (_nr),                                            \
                        "i" (0) /* phony, to align next arg's number */,      \
                        "i" (offsetof (tcbhead_t, sysinfo)));                 \
-  } while (0)
+    __status;                                                                \
+  })
 
 
 /* NB: in the lll_trylock macro we simply return the value in %eax
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
index 6722294..7a176ae 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
@@ -225,17 +225,18 @@ LLL_STUB_UNWIND_INFO_END
 
 
 #define lll_futex_wake(futex, nr, private) \
-  do {                                                                       \
-    int __ignore;                                                            \
+  ({                                                                         \
+    int __status;                                                            \
     register __typeof (nr) _nr __asm ("edx") = (nr);                         \
     LIBC_PROBE (lll_futex_wake, 3, futex, nr, private);                       \
     __asm __volatile ("syscall"                                                      \
-                     : "=a" (__ignore)                                       \
+                     : "=a" (__status)                                       \
                      : "0" (SYS_futex), "D" (futex),                         \
                        "S" (__lll_private_flag (FUTEX_WAKE, private)),       \
                        "d" (_nr)                                             \
                      : "memory", "cc", "r10", "r11", "cx");                  \
-  } while (0)
+    __status;                                                                \
+  })
 
 
 /* NB: in the lll_trylock macro we simply return the value in %eax
~
---

Cheers,
Carlos.


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