[PATCH] Have x86 and x86_64 lll_futex_wake return the syscall error.
Carlos O'Donell
carlos@redhat.com
Fri May 24 21:53:00 GMT 2013
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.
More information about the Libc-alpha
mailing list