aboutsummaryrefslogtreecommitdiff
path: root/nptl
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2007-07-28 20:16:07 +0000
committerUlrich Drepper <drepper@redhat.com>2007-07-28 20:16:07 +0000
commit085a44122074e67d56dca0c4f88f01d450ae82ad (patch)
tree51042f8853e47a41e4bb5f220587e7a70b8ca406 /nptl
parentae1ad762f0687afb37761085cb6e83305afe4521 (diff)
downloadglibc-085a44122074e67d56dca0c4f88f01d450ae82ad.tar
glibc-085a44122074e67d56dca0c4f88f01d450ae82ad.tar.gz
glibc-085a44122074e67d56dca0c4f88f01d450ae82ad.tar.bz2
glibc-085a44122074e67d56dca0c4f88f01d450ae82ad.zip
* iconvdata/gbk.c (BODY): Make buf and cp char instead of unsigned
char array resp. pointer. * iconvdata/iso-2022-kr.c (BODY): Make buf unsigned char instead of char array. * iconvdata/cns11643.h (cns11643_to_ucs4): Change first argument to const unsigned char **. (ucs4_to_cns11643): Change second argument to unsigned char *. * iconvdata/euc-tw.c (BODY): Change endp type to const unsigned char *. * iconvdata/iso-ir-165.h (ucs4_to_isoir165): Change second argument to unsigned char *. * iconvdata/ibm1008_420.c (LOOP_NEED_FLAGS): Don't define. * iconvdata/iso-2022-cn.c (BODY): Change buf to unsigned char array. * iconvdata/iso-2022-cn-ext.c (BODY): Change buf, tmpbuf, tmp types to unsigned char pointers/arrays instead of char. * iconvdata/jis0201.h (ucs4_to_jisx0201): Change second argument to unsigned char *. * iconvdata/jis0208.h (ucs4_to_jisx0208): Likewise. * iconvdata/jis0212.h: Include assert.h. (ucs4_to_jisx0212): Change second argument to unsigned char *. assert that if cp[0] is not '\0', cp[1] is not '\0' either instead of trying to handle that. * iconvdata/euc-kr.c (euckr_from_ucs4): Initialize also cp[1] to shut up a warning. * iconvdata/euc-jp-ms.c (from_ucs4_lat1, from_ucs4_greek, from_ucs4_cjk, from_ucs4_cjkcpt, from_ucs4_extra): Change type to two dimensional const unsigned char arrays. (BODY): Cast "" to (const unsigned char *) for assignment to cp. Initialize endp to inptr to shut up a warning.
Diffstat (limited to 'nptl')
-rw-r--r--nptl/ChangeLog85
-rw-r--r--nptl/allocatestack.c6
-rw-r--r--nptl/init.c4
-rw-r--r--nptl/pthread_create.c2
-rw-r--r--nptl/sysdeps/alpha/tls.h2
-rw-r--r--nptl/sysdeps/i386/tls.h2
-rw-r--r--nptl/sysdeps/ia64/tls.h2
-rw-r--r--nptl/sysdeps/powerpc/tls.h2
-rw-r--r--nptl/sysdeps/pthread/aio_misc.h6
-rw-r--r--nptl/sysdeps/pthread/gai_misc.h6
-rw-r--r--nptl/sysdeps/s390/tls.h2
-rw-r--r--nptl/sysdeps/sh/tls.h2
-rw-r--r--nptl/sysdeps/sparc/tls.h2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h73
-rw-r--r--nptl/sysdeps/unix/sysv/linux/alpha/pthread_once.c8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/fork.c2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h67
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/pthread_once.c8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h9
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c6
-rw-r--r--nptl/sysdeps/unix/sysv/linux/rtld-lowlevel.h4
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h70
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/pthread_once.c8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h110
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h79
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c6
-rw-r--r--nptl/sysdeps/unix/sysv/linux/unregister-atfork.c2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h13
-rw-r--r--nptl/sysdeps/x86_64/tls.h2
29 files changed, 362 insertions, 228 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 68a7d3aadb..84681bb334 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,88 @@
+2007-07-24 Jakub Jelinek <jakub@redhat.com>
+
+ * allocatestack.c (__nptl_setxid, __wait_lookup_done): Replace
+ lll_private_futex_* (*) with lll_futex_* (*, LLL_PRIVATE).
+ * pthread_create.c (start_thread): Likewise.
+ * init.c (sighandler_setxid): Likewise.
+ * sysdeps/alpha/tls.h (THREAD_GSCOPE_RESET_FLAG): Likewise.
+ * sysdeps/ia64/tls.h (THREAD_GSCOPE_RESET_FLAG): Likewise.
+ * sysdeps/i386/tls.h (THREAD_GSCOPE_RESET_FLAG): Likewise.
+ * sysdeps/s390/tls.h (THREAD_GSCOPE_RESET_FLAG): Likewise.
+ * sysdeps/powerpc/tls.h (THREAD_GSCOPE_RESET_FLAG): Likewise.
+ * sysdeps/x86_64/tls.h (THREAD_GSCOPE_RESET_FLAG): Likewise.
+ * sysdeps/sparc/tls.h (THREAD_GSCOPE_RESET_FLAG): Likewise.
+ * sysdeps/sh/tls.h (THREAD_GSCOPE_RESET_FLAG): Likewise.
+ * sysdeps/pthread/aio_misc.h (AIO_MISC_NOTIFY, AIO_MISC_WAIT):
+ Likewise.
+ * sysdeps/pthread/gai_misc.h (GAI_MISC_NOTIFY, GAI_MISC_WAIT):
+ Likewise.
+ * sysdeps/unix/sysv/linux/unregister-atfork.c (__unregister_atfork):
+ Likewise.
+ * sysdeps/unix/sysv/linux/rtld-lowlevel.h (__rtld_waitzero,
+ __rtld_notify): Likewise.
+ * sysdeps/unix/sysv/linux/fork.c (__libc_fork): Likewise.
+ * sysdeps/unix/sysv/linux/powerpc/pthread_once.c (clear_once_control,
+ __pthread_once): Likewise.
+ * sysdeps/unix/sysv/linux/alpha/pthread_once.c (clear_once_control,
+ __pthread_once): Add LLL_PRIVATE as last argument to lll_futex_*.
+ * sysdeps/unix/sysv/linux/alpha/lowlevellock.h (FUTEX_PRIVATE_FLAG,
+ LLL_PRIVATE, LLL_SHARED, __lll_private_flag): Define.
+ (lll_futex_wait): Add private argument, define as wrapper around
+ lll_futex_timed_wait.
+ (lll_futex_timed_wait, lll_futex_wake): Add private argument,
+ use __lll_private_flag macro.
+ (lll_robust_mutex_dead, __lll_mutex_unlock, __lll_robust_mutex_unlock,
+ __lll_mutex_unlock_force): Pass LLL_SHARED as last arg to lll_futex_*.
+ * sysdeps/unix/sysv/linux/ia64/pthread_once.c (clear_once_control,
+ __pthread_once): Add LLL_PRIVATE as last argument to lll_futex_*.
+ * sysdeps/unix/sysv/linux/ia64/lowlevellock.h (FUTEX_PRIVATE_FLAG,
+ LLL_PRIVATE, LLL_SHARED, __lll_private_flag): Define.
+ (lll_futex_wait): Add private argument, define as wrapper around
+ lll_futex_timed_wait.
+ (lll_futex_timed_wait, lll_futex_wake): Add private argument,
+ use __lll_private_flag macro.
+ (__lll_mutex_unlock, __lll_robust_mutex_unlock, lll_wait_tid,
+ __lll_mutex_unlock_force): Pass LLL_SHARED as last arg to lll_futex_*.
+ * sysdeps/unix/sysv/linux/i386/lowlevellock.h (__lll_private_flag):
+ Define.
+ (lll_futex_timed_wait, lll_futex_wake): Use it.
+ (lll_private_futex_wait, lll_private_futex_timed_wait,
+ lll_private_futex_wake): Removed.
+ * sysdeps/unix/sysv/linux/s390/pthread_once.c (clear_once_control,
+ __pthread_once): Add LLL_PRIVATE as last argument to lll_futex_*.
+ * sysdeps/unix/sysv/linux/s390/lowlevellock.h (FUTEX_PRIVATE_FLAG,
+ LLL_PRIVATE, LLL_SHARED, __lll_private_flag): Define.
+ (lll_futex_wait): Add private argument, define as wrapper around
+ lll_futex_timed_wait.
+ (lll_futex_timed_wait, lll_futex_wake): Add private argument,
+ use __lll_private_flag macro.
+ (lll_robust_mutex_dead, __lll_mutex_unlock, __lll_robust_mutex_unlock,
+ lll_wait_tid, __lll_mutex_unlock_force): Pass LLL_SHARED as last arg
+ to lll_futex_*.
+ * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
+ (lll_private_futex_wait, lll_private_futex_timed_wait,
+ lll_private_futex_wake): Removed.
+ * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h (__lll_private_flag):
+ Fix !__ASSUME_PRIVATE_FUTEX non-constant private case.
+ (lll_private_futex_wait, lll_private_futex_timed_wait,
+ lll_private_futex_wake): Removed.
+ * sysdeps/unix/sysv/linux/sparc/pthread_once.c (clear_once_control,
+ __pthread_once): Add LLL_PRIVATE as last argument to lll_futex_*.
+ * sysdeps/unix/sysv/linux/sparc/lowlevellock.h (FUTEX_PRIVATE_FLAG,
+ LLL_PRIVATE, LLL_SHARED, __lll_private_flag): Define.
+ (lll_futex_wait): Add private argument, define as wrapper around
+ lll_futex_timed_wait.
+ (lll_futex_timed_wait, lll_futex_wake): Add private argument,
+ use __lll_private_flag macro.
+ (lll_robust_mutex_dead, __lll_mutex_unlock, __lll_robust_mutex_unlock,
+ lll_wait_tid, __lll_mutex_unlock_force): Pass LLL_SHARED as last arg
+ to lll_futex_*.
+ * sysdeps/unix/sysv/linux/sh/lowlevellock.h (__lll_private_flag):
+ Define.
+ (lll_futex_timed_wait, lll_futex_wake): Use it.
+ (lll_private_futex_wait, lll_private_futex_timed_wait,
+ lll_private_futex_wake): Removed.
+
2007-07-27 Jakub Jelinek <jakub@redhat.com>
* sysdeps/sparc/tls.h (tcbhead_t): Move gscope_flag to the end
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index 145fe0a35f..ddf91e5c10 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -951,7 +951,7 @@ __nptl_setxid (struct xid_command *cmdp)
int cur = cmdp->cntr;
while (cur != 0)
{
- lll_private_futex_wait (&cmdp->cntr, cur);
+ lll_futex_wait (&cmdp->cntr, cur, LLL_PRIVATE);
cur = cmdp->cntr;
}
@@ -1037,7 +1037,7 @@ __wait_lookup_done (void)
continue;
do
- lll_private_futex_wait (gscope_flagp, THREAD_GSCOPE_FLAG_WAIT);
+ lll_futex_wait (gscope_flagp, THREAD_GSCOPE_FLAG_WAIT, LLL_PRIVATE);
while (*gscope_flagp == THREAD_GSCOPE_FLAG_WAIT);
}
@@ -1059,7 +1059,7 @@ __wait_lookup_done (void)
continue;
do
- lll_private_futex_wait (gscope_flagp, THREAD_GSCOPE_FLAG_WAIT);
+ lll_futex_wait (gscope_flagp, THREAD_GSCOPE_FLAG_WAIT, LLL_PRIVATE);
while (*gscope_flagp == THREAD_GSCOPE_FLAG_WAIT);
}
diff --git a/nptl/init.c b/nptl/init.c
index a1aec6b8f7..95b9c7be5d 100644
--- a/nptl/init.c
+++ b/nptl/init.c
@@ -216,7 +216,7 @@ sighandler_setxid (int sig, siginfo_t *si, void *ctx)
__xidcmd->id[1], __xidcmd->id[2]);
if (atomic_decrement_val (&__xidcmd->cntr) == 0)
- lll_private_futex_wake (&__xidcmd->cntr, 1);
+ lll_futex_wake (&__xidcmd->cntr, 1, LLL_PRIVATE);
/* Reset the SETXID flag. */
struct pthread *self = THREAD_SELF;
@@ -225,7 +225,7 @@ sighandler_setxid (int sig, siginfo_t *si, void *ctx)
/* And release the futex. */
self->setxid_futex = 1;
- lll_private_futex_wake (&self->setxid_futex, 1);
+ lll_futex_wake (&self->setxid_futex, 1, LLL_PRIVATE);
}
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index b1f852dc95..ca55903c22 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -385,7 +385,7 @@ start_thread (void *arg)
/* Some other thread might call any of the setXid functions and expect
us to reply. In this case wait until we did that. */
do
- lll_private_futex_wait (&pd->setxid_futex, 0);
+ lll_futex_wait (&pd->setxid_futex, 0, LLL_PRIVATE);
while (pd->cancelhandling & SETXID_BITMASK);
/* Reset the value so that the stack can be reused. */
diff --git a/nptl/sysdeps/alpha/tls.h b/nptl/sysdeps/alpha/tls.h
index 388a399c73..e77b1ffca9 100644
--- a/nptl/sysdeps/alpha/tls.h
+++ b/nptl/sysdeps/alpha/tls.h
@@ -131,7 +131,7 @@ typedef struct
= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \
THREAD_GSCOPE_FLAG_UNUSED); \
if (__res == THREAD_GSCOPE_FLAG_WAIT) \
- lll_private_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \
+ lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE); \
} \
while (0)
#define THREAD_GSCOPE_SET_FLAG() \
diff --git a/nptl/sysdeps/i386/tls.h b/nptl/sysdeps/i386/tls.h
index 1ffd4cf494..b5127420cf 100644
--- a/nptl/sysdeps/i386/tls.h
+++ b/nptl/sysdeps/i386/tls.h
@@ -449,7 +449,7 @@ union user_desc_init
: "i" (offsetof (struct pthread, header.gscope_flag)), \
"0" (THREAD_GSCOPE_FLAG_UNUSED)); \
if (__res == THREAD_GSCOPE_FLAG_WAIT) \
- lll_private_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \
+ lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE); \
} \
while (0)
#define THREAD_GSCOPE_SET_FLAG() \
diff --git a/nptl/sysdeps/ia64/tls.h b/nptl/sysdeps/ia64/tls.h
index a5b7b76e2a..936ff01a72 100644
--- a/nptl/sysdeps/ia64/tls.h
+++ b/nptl/sysdeps/ia64/tls.h
@@ -173,7 +173,7 @@ register struct pthread *__thread_self __asm__("r13");
= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \
THREAD_GSCOPE_FLAG_UNUSED); \
if (__res == THREAD_GSCOPE_FLAG_WAIT) \
- lll_private_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \
+ lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE); \
} \
while (0)
#define THREAD_GSCOPE_SET_FLAG() \
diff --git a/nptl/sysdeps/powerpc/tls.h b/nptl/sysdeps/powerpc/tls.h
index 06c60e8ba2..0f4d5290dd 100644
--- a/nptl/sysdeps/powerpc/tls.h
+++ b/nptl/sysdeps/powerpc/tls.h
@@ -190,7 +190,7 @@ register void *__thread_register __asm__ ("r13");
= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \
THREAD_GSCOPE_FLAG_UNUSED); \
if (__res == THREAD_GSCOPE_FLAG_WAIT) \
- lll_private_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \
+ lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE); \
} \
while (0)
#define THREAD_GSCOPE_SET_FLAG() \
diff --git a/nptl/sysdeps/pthread/aio_misc.h b/nptl/sysdeps/pthread/aio_misc.h
index 25ab74e272..f36825e06f 100644
--- a/nptl/sysdeps/pthread/aio_misc.h
+++ b/nptl/sysdeps/pthread/aio_misc.h
@@ -30,7 +30,7 @@
#define AIO_MISC_NOTIFY(waitlist) \
do { \
if (*waitlist->counterp > 0 && --*waitlist->counterp == 0) \
- lll_private_futex_wake (waitlist->counterp, 1); \
+ lll_futex_wake (waitlist->counterp, 1, LLL_PRIVATE); \
} while (0)
#define AIO_MISC_WAIT(result, futex, timeout, cancel) \
@@ -49,8 +49,8 @@
int status; \
do \
{ \
- status = lll_private_futex_timed_wait (futexaddr, oldval, \
- timeout); \
+ status = lll_futex_timed_wait (futexaddr, oldval, timeout, \
+ LLL_PRIVATE); \
if (status != -EWOULDBLOCK) \
break; \
\
diff --git a/nptl/sysdeps/pthread/gai_misc.h b/nptl/sysdeps/pthread/gai_misc.h
index 5f6990040a..0a2686cb27 100644
--- a/nptl/sysdeps/pthread/gai_misc.h
+++ b/nptl/sysdeps/pthread/gai_misc.h
@@ -31,7 +31,7 @@
#define GAI_MISC_NOTIFY(waitlist) \
do { \
if (*waitlist->counterp > 0 && --*waitlist->counterp == 0) \
- lll_private_futex_wake (waitlist->counterp, 1); \
+ lll_futex_wake (waitlist->counterp, 1, LLL_PRIVATE); \
} while (0)
#define GAI_MISC_WAIT(result, futex, timeout, cancel) \
@@ -50,8 +50,8 @@
int status; \
do \
{ \
- status = lll_private_futex_timed_wait (futexaddr, oldval, \
- timeout); \
+ status = lll_futex_timed_wait (futexaddr, oldval, timeout, \
+ LLL_PRIVATE); \
if (status != -EWOULDBLOCK) \
break; \
\
diff --git a/nptl/sysdeps/s390/tls.h b/nptl/sysdeps/s390/tls.h
index f10db8f227..3be459e32c 100644
--- a/nptl/sysdeps/s390/tls.h
+++ b/nptl/sysdeps/s390/tls.h
@@ -183,7 +183,7 @@ typedef struct
= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \
THREAD_GSCOPE_FLAG_UNUSED); \
if (__res == THREAD_GSCOPE_FLAG_WAIT) \
- lll_private_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \
+ lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE); \
} \
while (0)
#define THREAD_GSCOPE_SET_FLAG() \
diff --git a/nptl/sysdeps/sh/tls.h b/nptl/sysdeps/sh/tls.h
index e07e29f786..a2d4d565ff 100644
--- a/nptl/sysdeps/sh/tls.h
+++ b/nptl/sysdeps/sh/tls.h
@@ -164,7 +164,7 @@ typedef struct
= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \
THREAD_GSCOPE_FLAG_UNUSED); \
if (__res == THREAD_GSCOPE_FLAG_WAIT) \
- lll_private_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \
+ lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE); \
} \
while (0)
#define THREAD_GSCOPE_SET_FLAG() \
diff --git a/nptl/sysdeps/sparc/tls.h b/nptl/sysdeps/sparc/tls.h
index c4741c8fc8..601b53732b 100644
--- a/nptl/sysdeps/sparc/tls.h
+++ b/nptl/sysdeps/sparc/tls.h
@@ -157,7 +157,7 @@ register struct pthread *__thread_self __asm__("%g7");
= atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \
THREAD_GSCOPE_FLAG_UNUSED); \
if (__res == THREAD_GSCOPE_FLAG_WAIT) \
- lll_private_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \
+ lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE); \
} \
while (0)
#define THREAD_GSCOPE_SET_FLAG() \
diff --git a/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h
index 04ac006400..5f08673c43 100644
--- a/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h
@@ -36,34 +36,63 @@
#define FUTEX_LOCK_PI 6
#define FUTEX_UNLOCK_PI 7
#define FUTEX_TRYLOCK_PI 8
+#define FUTEX_PRIVATE_FLAG 128
+
+/* Values for 'private' parameter of locking macros. Yes, the
+ definition seems to be backwards. But it is not. The bit will be
+ reversed before passing to the system call. */
+#define LLL_PRIVATE 0
+#define LLL_SHARED FUTEX_PRIVATE_FLAG
+
+
+#if !defined NOT_IN_libc || defined IS_IN_rtld
+/* In libc.so or ld.so all futexes are private. */
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ ((fl) | FUTEX_PRIVATE_FLAG)
+# else
+# define __lll_private_flag(fl, private) \
+ ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex))
+# endif
+#else
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ (((fl) | FUTEX_PRIVATE_FLAG) ^ (private))
+# else
+# define __lll_private_flag(fl, private) \
+ (__builtin_constant_p (private) \
+ ? ((private) == 0 \
+ ? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) \
+ : (fl)) \
+ : ((fl) | (((private) ^ FUTEX_PRIVATE_FLAG) \
+ & THREAD_GETMEM (THREAD_SELF, header.private_futex))))
+# endif
+#endif
+
/* Initializer for compatibility lock. */
#define LLL_MUTEX_LOCK_INITIALIZER (0)
-#define lll_futex_wait(futexp, val) \
- ({ \
- INTERNAL_SYSCALL_DECL (__err); \
- long int __ret; \
- __ret = INTERNAL_SYSCALL (futex, __err, 4, \
- (futexp), FUTEX_WAIT, (val), 0); \
- INTERNAL_SYSCALL_ERROR_P (__ret, __err)? -__ret : __ret; \
- })
+#define lll_futex_wait(futexp, val, private) \
+ lll_futex_timed_wait (futexp, val, NULL, private)
-#define lll_futex_timed_wait(futexp, val, timespec) \
+#define lll_futex_timed_wait(futexp, val, timespec, private) \
({ \
INTERNAL_SYSCALL_DECL (__err); \
long int __ret; \
- __ret = INTERNAL_SYSCALL (futex, __err, 4, \
- (futexp), FUTEX_WAIT, (val), (timespec)); \
+ __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \
+ __lll_private_flag (FUTEX_WAIT, private), \
+ (val), (timespec)); \
INTERNAL_SYSCALL_ERROR_P (__ret, __err)? -__ret : __ret; \
})
-#define lll_futex_wake(futexp, nr) \
+#define lll_futex_wake(futexp, nr, private) \
({ \
INTERNAL_SYSCALL_DECL (__err); \
long int __ret; \
- __ret = INTERNAL_SYSCALL (futex, __err, 4, \
- (futexp), FUTEX_WAKE, (nr), 0); \
+ __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \
+ __lll_private_flag (FUTEX_WAKE, private), \
+ (nr), 0); \
INTERNAL_SYSCALL_ERROR_P (__ret, __err)? -__ret : __ret; \
})
@@ -72,7 +101,7 @@
{ \
int *__futexp = &(futexv); \
atomic_or (__futexp, FUTEX_OWNER_DIED); \
- lll_futex_wake (__futexp, 1); \
+ lll_futex_wake (__futexp, 1, LLL_SHARED); \
} \
while (0)
@@ -198,7 +227,7 @@ __lll_mutex_unlock (int *futex)
{
int val = atomic_exchange_rel (futex, 0);
if (__builtin_expect (val > 1, 0))
- lll_futex_wake (futex, 1);
+ lll_futex_wake (futex, 1, LLL_SHARED);
}
#define lll_mutex_unlock(futex) __lll_mutex_unlock(&(futex))
@@ -208,7 +237,7 @@ __lll_robust_mutex_unlock (int *futex, int mask)
{
int val = atomic_exchange_rel (futex, 0);
if (__builtin_expect (val & mask, 0))
- lll_futex_wake (futex, 1);
+ lll_futex_wake (futex, 1, LLL_SHARED);
}
#define lll_robust_mutex_unlock(futex) \
__lll_robust_mutex_unlock(&(futex), FUTEX_WAITERS)
@@ -218,7 +247,7 @@ static inline void __attribute__ ((always_inline))
__lll_mutex_unlock_force (int *futex)
{
(void) atomic_exchange_rel (futex, 0);
- lll_futex_wake (futex, 1);
+ lll_futex_wake (futex, 1, LLL_SHARED);
}
#define lll_mutex_unlock_force(futex) __lll_mutex_unlock_force(&(futex))
@@ -252,10 +281,10 @@ typedef int lll_lock_t;
thread ID while the clone is running and is reset to zero
afterwards. */
#define lll_wait_tid(tid) \
- do { \
- __typeof (tid) __tid; \
- while ((__tid = (tid)) != 0) \
- lll_futex_wait (&(tid), __tid); \
+ do { \
+ __typeof (tid) __tid; \
+ while ((__tid = (tid)) != 0) \
+ lll_futex_wait (&(tid), __tid, LLL_SHARED); \
} while (0)
extern int __lll_timedwait_tid (int *, const struct timespec *)
diff --git a/nptl/sysdeps/unix/sysv/linux/alpha/pthread_once.c b/nptl/sysdeps/unix/sysv/linux/alpha/pthread_once.c
index 79a3c47aed..0e7e9790dd 100644
--- a/nptl/sysdeps/unix/sysv/linux/alpha/pthread_once.c
+++ b/nptl/sysdeps/unix/sysv/linux/alpha/pthread_once.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -28,7 +28,7 @@ clear_once_control (void *arg)
pthread_once_t *once_control = (pthread_once_t *) arg;
*once_control = 0;
- lll_futex_wake (once_control, INT_MAX);
+ lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
}
int
@@ -72,7 +72,7 @@ __pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
break;
/* Same generation, some other thread was faster. Wait. */
- lll_futex_wait (once_control, oldval);
+ lll_futex_wait (once_control, oldval, LLL_PRIVATE);
}
/* This thread is the first here. Do the initialization.
@@ -88,7 +88,7 @@ __pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
atomic_increment (once_control);
/* Wake up all other threads. */
- lll_futex_wake (once_control, INT_MAX);
+ lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
return 0;
}
diff --git a/nptl/sysdeps/unix/sysv/linux/fork.c b/nptl/sysdeps/unix/sysv/linux/fork.c
index c6dadb5683..f9913c343e 100644
--- a/nptl/sysdeps/unix/sysv/linux/fork.c
+++ b/nptl/sysdeps/unix/sysv/linux/fork.c
@@ -203,7 +203,7 @@ __libc_fork (void)
if (atomic_decrement_and_test (&allp->handler->refcntr)
&& allp->handler->need_signal)
- lll_private_futex_wake (allp->handler->refcntr, 1);
+ lll_futex_wake (allp->handler->refcntr, 1, LLL_PRIVATE);
allp = allp->next;
}
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h
index 17093471d3..095f0e8aca 100644
--- a/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h
@@ -36,6 +36,39 @@
#define FUTEX_LOCK_PI 6
#define FUTEX_UNLOCK_PI 7
#define FUTEX_TRYLOCK_PI 8
+#define FUTEX_PRIVATE_FLAG 128
+
+/* Values for 'private' parameter of locking macros. Yes, the
+ definition seems to be backwards. But it is not. The bit will be
+ reversed before passing to the system call. */
+#define LLL_PRIVATE 0
+#define LLL_SHARED FUTEX_PRIVATE_FLAG
+
+
+#if !defined NOT_IN_libc || defined IS_IN_rtld
+/* In libc.so or ld.so all futexes are private. */
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ ((fl) | FUTEX_PRIVATE_FLAG)
+# else
+# define __lll_private_flag(fl, private) \
+ ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex))
+# endif
+#else
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ (((fl) | FUTEX_PRIVATE_FLAG) ^ (private))
+# else
+# define __lll_private_flag(fl, private) \
+ (__builtin_constant_p (private) \
+ ? ((private) == 0 \
+ ? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) \
+ : (fl)) \
+ : ((fl) | (((private) ^ FUTEX_PRIVATE_FLAG) \
+ & THREAD_GETMEM (THREAD_SELF, header.private_futex))))
+# endif
+#endif
+
/* Delay in spinlock loop. */
#define BUSY_WAIT_NOP asm ("hint @pause")
@@ -43,18 +76,22 @@
/* Initializer for compatibility lock. */
#define LLL_MUTEX_LOCK_INITIALIZER (0)
-#define lll_futex_wait(futex, val) lll_futex_timed_wait (futex, val, 0)
+#define lll_futex_wait(futex, val, private) \
+ lll_futex_timed_wait (futex, val, NULL, private)
-#define lll_futex_timed_wait(ftx, val, timespec) \
+#define lll_futex_timed_wait(ftx, val, timespec, private) \
({ \
- DO_INLINE_SYSCALL(futex, 4, (long) (ftx), FUTEX_WAIT, (int) (val), \
- (long) (timespec)); \
+ DO_INLINE_SYSCALL(futex, 4, (long) (ftx), \
+ __lll_private_flag (FUTEX_WAIT, private), \
+ (int) (val), (long) (timespec)); \
_r10 == -1 ? -_retval : _retval; \
})
-#define lll_futex_wake(ftx, nr) \
+#define lll_futex_wake(ftx, nr, private) \
({ \
- DO_INLINE_SYSCALL(futex, 3, (long) (ftx), FUTEX_WAKE, (int) (nr)); \
+ DO_INLINE_SYSCALL(futex, 3, (long) (ftx), \
+ __lll_private_flag (FUTEX_WAKE, private), \
+ (int) (nr)); \
_r10 == -1 ? -_retval : _retval; \
})
@@ -188,7 +225,7 @@ extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *)
int __val = atomic_exchange_rel (__futex, 0); \
\
if (__builtin_expect (__val > 1, 0)) \
- lll_futex_wake (__futex, 1); \
+ lll_futex_wake (__futex, 1, LLL_SHARED); \
}))
#define lll_mutex_unlock(futex) \
__lll_mutex_unlock(&(futex))
@@ -200,7 +237,7 @@ extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *)
int __val = atomic_exchange_rel (__futex, 0); \
\
if (__builtin_expect (__val & FUTEX_WAITERS, 0)) \
- lll_futex_wake (__futex, 1); \
+ lll_futex_wake (__futex, 1, LLL_SHARED); \
}))
#define lll_robust_mutex_unlock(futex) \
__lll_robust_mutex_unlock(&(futex))
@@ -210,7 +247,7 @@ extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *)
((void) ({ \
int *__futex = (futex); \
(void) atomic_exchange_rel (__futex, 0); \
- lll_futex_wake (__futex, 1); \
+ lll_futex_wake (__futex, 1, LLL_SHARED); \
}))
#define lll_mutex_unlock_force(futex) \
__lll_mutex_unlock_force(&(futex))
@@ -241,12 +278,12 @@ typedef int lll_lock_t;
thread ID while the clone is running and is reset to zero
afterwards. */
#define lll_wait_tid(tid) \
- do \
- { \
- __typeof (tid) __tid; \
- while ((__tid = (tid)) != 0) \
- lll_futex_wait (&(tid), __tid); \
- } \
+ do \
+ { \
+ __typeof (tid) __tid; \
+ while ((__tid = (tid)) != 0) \
+ lll_futex_wait (&(tid), __tid, LLL_SHARED); \
+ } \
while (0)
extern int __lll_timedwait_tid (int *, const struct timespec *)
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/pthread_once.c b/nptl/sysdeps/unix/sysv/linux/ia64/pthread_once.c
index 3b07cc127d..22e2dd3c0c 100644
--- a/nptl/sysdeps/unix/sysv/linux/ia64/pthread_once.c
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/pthread_once.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
@@ -30,7 +30,7 @@ clear_once_control (void *arg)
pthread_once_t *once_control = (pthread_once_t *) arg;
*once_control = 0;
- lll_futex_wake (once_control, INT_MAX);
+ lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
}
@@ -65,7 +65,7 @@ __pthread_once (once_control, init_routine)
if (((oldval ^ newval) & -4) == 0)
{
/* Same generation, some other thread was faster. Wait. */
- lll_futex_wait (once_control, newval);
+ lll_futex_wait (once_control, newval, LLL_PRIVATE);
continue;
}
}
@@ -84,7 +84,7 @@ __pthread_once (once_control, init_routine)
atomic_increment (once_control);
/* Wake up all other threads. */
- lll_futex_wake (once_control, INT_MAX);
+ lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
break;
}
diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
index ab795348ee..cf91f21483 100644
--- a/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
@@ -134,15 +134,6 @@
})
-#define lll_private_futex_wait(futexp, val) \
- lll_futex_timed_wait (futexp, val, NULL, LLL_PRIVATE)
-
-#define lll_private_futex_timed_wait(futexp, val, timeout) \
- lll_futex_timed_wait (futexp, val, timeout, LLL_PRIVATE)
-
-#define lll_private_futex_wake(futexp, val) \
- lll_futex_wake (futexp, val, LLL_PRIVATE)
-
#ifdef UP
# define __lll_acq_instr ""
# define __lll_rel_instr ""
diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c b/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c
index 3224568fb7..969078094d 100644
--- a/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c
+++ b/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c
@@ -30,7 +30,7 @@ clear_once_control (void *arg)
pthread_once_t *once_control = (pthread_once_t *) arg;
*once_control = 0;
- lll_private_futex_wake (once_control, INT_MAX);
+ lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
}
@@ -74,7 +74,7 @@ __pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
break;
/* Same generation, some other thread was faster. Wait. */
- lll_private_futex_wait (once_control, oldval);
+ lll_futex_wait (once_control, oldval, LLL_PRIVATE);
}
@@ -92,7 +92,7 @@ __pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
atomic_increment (once_control);
/* Wake up all other threads. */
- lll_private_futex_wake (once_control, INT_MAX);
+ lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
return 0;
}
diff --git a/nptl/sysdeps/unix/sysv/linux/rtld-lowlevel.h b/nptl/sysdeps/unix/sysv/linux/rtld-lowlevel.h
index 1aeff8fb39..4a49925588 100644
--- a/nptl/sysdeps/unix/sysv/linux/rtld-lowlevel.h
+++ b/nptl/sysdeps/unix/sysv/linux/rtld-lowlevel.h
@@ -33,12 +33,12 @@
int val = word; \
if (val == 0) \
break; \
- lll_private_futex_wait (&(word), val); \
+ lll_futex_wait (&(word), val, LLL_PRIVATE); \
} \
} while (0)
#define __rtld_notify(word) \
- lll_private_futex_wake (&(word), 1)
+ lll_futex_wake (&(word), 1, LLL_PRIVATE)
#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
index d915facba1..4758b63bd0 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
@@ -35,31 +35,50 @@
#define FUTEX_LOCK_PI 6
#define FUTEX_UNLOCK_PI 7
#define FUTEX_TRYLOCK_PI 8
+#define FUTEX_PRIVATE_FLAG 128
+
+/* Values for 'private' parameter of locking macros. Yes, the
+ definition seems to be backwards. But it is not. The bit will be
+ reversed before passing to the system call. */
+#define LLL_PRIVATE 0
+#define LLL_SHARED FUTEX_PRIVATE_FLAG
+
+
+#if !defined NOT_IN_libc || defined IS_IN_rtld
+/* In libc.so or ld.so all futexes are private. */
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ ((fl) | FUTEX_PRIVATE_FLAG)
+# else
+# define __lll_private_flag(fl, private) \
+ ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex))
+# endif
+#else
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ (((fl) | FUTEX_PRIVATE_FLAG) ^ (private))
+# else
+# define __lll_private_flag(fl, private) \
+ (__builtin_constant_p (private) \
+ ? ((private) == 0 \
+ ? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) \
+ : (fl)) \
+ : ((fl) | (((private) ^ FUTEX_PRIVATE_FLAG) \
+ & THREAD_GETMEM (THREAD_SELF, header.private_futex))))
+# endif
+#endif
/* Initializer for compatibility lock. */
#define LLL_MUTEX_LOCK_INITIALIZER (0)
-#define lll_futex_wait(futex, val) \
- ({ \
- register unsigned long int __r2 asm ("2") = (unsigned long int) (futex); \
- register unsigned long int __r3 asm ("3") = FUTEX_WAIT; \
- register unsigned long int __r4 asm ("4") = (unsigned long int) (val); \
- register unsigned long int __r5 asm ("5") = 0ul; \
- register unsigned long __result asm ("2"); \
- \
- __asm __volatile ("svc %b1" \
- : "=d" (__result) \
- : "i" (SYS_futex), "0" (__r2), "d" (__r3), \
- "d" (__r4), "d" (__r5) \
- : "cc", "memory" ); \
- __result; \
- })
-
+#define lll_futex_wait(futex, val, private) \
+ lll_futex_timed_wait (futex, val, NULL, private)
-#define lll_futex_timed_wait(futex, val, timespec) \
+#define lll_futex_timed_wait(futex, val, timespec, private) \
({ \
register unsigned long int __r2 asm ("2") = (unsigned long int) (futex); \
- register unsigned long int __r3 asm ("3") = FUTEX_WAIT; \
+ register unsigned long int __r3 asm ("3") \
+ = __lll_private_flag (FUTEX_WAIT, private); \
register unsigned long int __r4 asm ("4") = (unsigned long int) (val); \
register unsigned long int __r5 asm ("5") = (unsigned long int)(timespec);\
register unsigned long int __result asm ("2"); \
@@ -73,10 +92,11 @@
})
-#define lll_futex_wake(futex, nr) \
+#define lll_futex_wake(futex, nr, private) \
({ \
register unsigned long int __r2 asm ("2") = (unsigned long int) (futex); \
- register unsigned long int __r3 asm ("3") = FUTEX_WAKE; \
+ register unsigned long int __r3 asm ("3") \
+ __lll_private_flag (FUTEX_WAKE, private); \
register unsigned long int __r4 asm ("4") = (unsigned long int) (nr); \
register unsigned long int __result asm ("2"); \
\
@@ -94,7 +114,7 @@
int *__futexp = &(futexv); \
\
atomic_or (__futexp, FUTEX_OWNER_DIED); \
- lll_futex_wake (__futexp, 1); \
+ lll_futex_wake (__futexp, 1, LLL_SHARED); \
} \
while (0)
@@ -271,7 +291,7 @@ __lll_mutex_unlock (int *futex)
lll_compare_and_swap (futex, oldval, newval, "slr %2,%2");
if (oldval > 1)
- lll_futex_wake (futex, 1);
+ lll_futex_wake (futex, 1, LLL_SHARED);
}
#define lll_mutex_unlock(futex) \
__lll_mutex_unlock(&(futex))
@@ -286,7 +306,7 @@ __lll_robust_mutex_unlock (int *futex, int mask)
lll_compare_and_swap (futex, oldval, newval, "slr %2,%2");
if (oldval & mask)
- lll_futex_wake (futex, 1);
+ lll_futex_wake (futex, 1, LLL_SHARED);
}
#define lll_robust_mutex_unlock(futex) \
__lll_robust_mutex_unlock(&(futex), FUTEX_WAITERS)
@@ -297,7 +317,7 @@ __attribute__ ((always_inline))
__lll_mutex_unlock_force (int *futex)
{
*futex = 0;
- lll_futex_wake (futex, 1);
+ lll_futex_wake (futex, 1, LLL_SHARED);
}
#define lll_mutex_unlock_force(futex) \
__lll_mutex_unlock_force(&(futex))
@@ -338,7 +358,7 @@ __lll_wait_tid (int *ptid)
int tid;
while ((tid = *ptid) != 0)
- lll_futex_wait (ptid, tid);
+ lll_futex_wait (ptid, tid, LLL_SHARED);
}
#define lll_wait_tid(tid) __lll_wait_tid(&(tid))
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/pthread_once.c b/nptl/sysdeps/unix/sysv/linux/s390/pthread_once.c
index f29e23fd4b..0012e9ae27 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/pthread_once.c
+++ b/nptl/sysdeps/unix/sysv/linux/s390/pthread_once.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
@@ -30,7 +30,7 @@ clear_once_control (void *arg)
pthread_once_t *once_control = (pthread_once_t *) arg;
*once_control = 0;
- lll_futex_wake (once_control, INT_MAX);
+ lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
}
@@ -76,7 +76,7 @@ __pthread_once (once_control, init_routine)
if (((oldval ^ newval) & -4) == 0)
{
/* Same generation, some other thread was faster. Wait. */
- lll_futex_wait (once_control, newval);
+ lll_futex_wait (once_control, newval, LLL_PRIVATE);
continue;
}
}
@@ -101,7 +101,7 @@ __pthread_once (once_control, init_routine)
: "m" (*once_control) : "cc" );
/* Wake up all other threads. */
- lll_futex_wake (once_control, INT_MAX);
+ lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
break;
}
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
index 3092b27642..be47bd752e 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
@@ -40,6 +40,31 @@
#define LLL_SHARED FUTEX_PRIVATE_FLAG
+#if !defined NOT_IN_libc || defined IS_IN_rtld
+/* In libc.so or ld.so all futexes are private. */
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ ((fl) | FUTEX_PRIVATE_FLAG)
+# else
+# define __lll_private_flag(fl, private) \
+ ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex))
+# endif
+#else
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ (((fl) | FUTEX_PRIVATE_FLAG) ^ (private))
+# else
+# define __lll_private_flag(fl, private) \
+ (__builtin_constant_p (private) \
+ ? ((private) == 0 \
+ ? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) \
+ : (fl)) \
+ : ((fl) | (((private) ^ FUTEX_PRIVATE_FLAG) \
+ & THREAD_GETMEM (THREAD_SELF, header.private_futex))))
+# endif
+#endif
+
+
/* Initializer for compatibility lock. */
#define LLL_MUTEX_LOCK_INITIALIZER (0)
#define LLL_MUTEX_LOCK_INITIALIZER_LOCKED (1)
@@ -278,7 +303,7 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
1: mov r1,r15"\
: "=&r" (__ignore) : "r" (__futex), "r" (FUTEX_OWNER_DIED) \
: "r0", "r1", "memory"); \
- lll_futex_wake (__futex, 1, 0); })
+ lll_futex_wake (__futex, 1, LLL_SHARED); })
#define lll_mutex_islocked(futex) \
(futex != 0)
@@ -312,7 +337,8 @@ typedef int lll_lock_t;
int __status; \
register unsigned long __r3 asm ("r3") = SYS_futex; \
register unsigned long __r4 asm ("r4") = (unsigned long) (futex); \
- register unsigned long __r5 asm ("r5") = FUTEX_WAIT; \
+ register unsigned long __r5 asm ("r5") \
+ = __lll_private_flag (FUTEX_WAIT, private); \
register unsigned long __r6 asm ("r6") = (unsigned long) (val); \
register unsigned long __r7 asm ("r7") = (timeout); \
__asm __volatile (SYSCALL_WITH_INST_PAD \
@@ -329,7 +355,8 @@ typedef int lll_lock_t;
int __ignore; \
register unsigned long __r3 asm ("r3") = SYS_futex; \
register unsigned long __r4 asm ("r4") = (unsigned long) (futex); \
- register unsigned long __r5 asm ("r5") = FUTEX_WAKE; \
+ register unsigned long __r5 asm ("r5") \
+ = __lll_private_flag (FUTEX_WAKE, private); \
register unsigned long __r6 asm ("r6") = (unsigned long) (nr); \
register unsigned long __r7 asm ("r7") = 0; \
__asm __volatile (SYSCALL_WITH_INST_PAD \
@@ -340,81 +367,6 @@ typedef int lll_lock_t;
} while (0)
-#define lll_private_futex_wait(futex, val) \
- lll_private_futex_timed_wait (futex, val, NULL)
-
-
-#ifdef __ASSUME_PRIVATE_FUTEX
-# define lll_private_futex_timed_wait(futex, val, timeout) \
- ({ \
- int __status; \
- register unsigned long __r3 asm ("r3") = SYS_futex; \
- register unsigned long __r4 asm ("r4") = (unsigned long) (futex); \
- register unsigned long __r5 asm ("r5") = FUTEX_WAIT | FUTEX_PRIVATE_FLAG; \
- register unsigned long __r6 asm ("r6") = (unsigned long) (val); \
- register unsigned long __r7 asm ("r7") = (timeout); \
- __asm __volatile (SYSCALL_WITH_INST_PAD \
- : "=z" (__status) \
- : "r" (__r3), "r" (__r4), "r" (__r5), \
- "r" (__r6), "r" (__r7) \
- : "memory", "t"); \
- __status; \
- })
-
-
-# define lll_private_futex_wake(futex, nr) \
- do { \
- int __ignore; \
- register unsigned long __r3 asm ("r3") = SYS_futex; \
- register unsigned long __r4 asm ("r4") = (unsigned long) (futex); \
- register unsigned long __r5 asm ("r5") = FUTEX_WAKE | FUTEX_PRIVATE_FLAG; \
- register unsigned long __r6 asm ("r6") = (unsigned long) (nr); \
- register unsigned long __r7 asm ("r7") = 0; \
- __asm __volatile (SYSCALL_WITH_INST_PAD \
- : "=z" (__ignore) \
- : "r" (__r3), "r" (__r4), "r" (__r5), \
- "r" (__r6), "r" (__r7) \
- : "memory", "t"); \
- } while (0)
-
-
-#else
-# define lll_private_futex_timed_wait(futex, val, timeout) \
- ({ \
- int __status; \
- register unsigned long __r3 asm ("r3") = SYS_futex; \
- register unsigned long __r4 asm ("r4") = (unsigned long) (futex); \
- register unsigned long __r5 asm ("r5"); \
- register unsigned long __r6 asm ("r6") = (unsigned long) (val); \
- register unsigned long __r7 asm ("r7") = (timeout); \
- __r5 = THREAD_GETMEM (THREAD_SELF, header.private_futex); \
- __asm __volatile (SYSCALL_WITH_INST_PAD \
- : "=z" (__status) \
- : "r" (__r3), "r" (__r4), "r" (__r5), \
- "r" (__r6), "r" (__r7) \
- : "memory", "t"); \
- __status; \
- })
-
-
-# define lll_private_futex_wake(futex, nr) \
- do { \
- int __ignore; \
- register unsigned long __r3 asm ("r3") = SYS_futex; \
- register unsigned long __r4 asm ("r4") = (unsigned long) (futex); \
- register unsigned long __r5 asm ("r5") = FUTEX_WAKE; \
- register unsigned long __r6 asm ("r6") = (unsigned long) (nr); \
- register unsigned long __r7 asm ("r7") = 0; \
- __r5 |= THREAD_GETMEM (THREAD_SELF, header.private_futex); \
- __asm __volatile (SYSCALL_WITH_INST_PAD \
- : "=z" (__ignore) \
- : "r" (__r3), "r" (__r4), "r" (__r5), \
- "r" (__r6), "r" (__r7) \
- : "memory", "t"); \
- } while (0)
-#endif
-
-
/* The states of a lock are:
0 - untaken
1 - taken by one user
@@ -438,7 +390,7 @@ extern int __lll_wait_tid (int *tid) attribute_hidden;
do { \
__typeof (tid) *__tid = &(tid); \
while (*__tid != 0) \
- lll_futex_wait (__tid, *__tid, 0); \
+ lll_futex_wait (__tid, *__tid, LLL_SHARED); \
} while (0)
extern int __lll_timedwait_tid (int *tid, const struct timespec *abstime)
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
index 6548970663..922e3c21d3 100644
--- a/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
@@ -35,37 +35,66 @@
#define FUTEX_LOCK_PI 6
#define FUTEX_UNLOCK_PI 7
#define FUTEX_TRYLOCK_PI 8
+#define FUTEX_PRIVATE_FLAG 128
+
+
+/* Values for 'private' parameter of locking macros. Yes, the
+ definition seems to be backwards. But it is not. The bit will be
+ reversed before passing to the system call. */
+#define LLL_PRIVATE 0
+#define LLL_SHARED FUTEX_PRIVATE_FLAG
+
+
+#if !defined NOT_IN_libc || defined IS_IN_rtld
+/* In libc.so or ld.so all futexes are private. */
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ ((fl) | FUTEX_PRIVATE_FLAG)
+# else
+# define __lll_private_flag(fl, private) \
+ ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex))
+# endif
+#else
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ (((fl) | FUTEX_PRIVATE_FLAG) ^ (private))
+# else
+# define __lll_private_flag(fl, private) \
+ (__builtin_constant_p (private) \
+ ? ((private) == 0 \
+ ? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) \
+ : (fl)) \
+ : ((fl) | (((private) ^ FUTEX_PRIVATE_FLAG) \
+ & THREAD_GETMEM (THREAD_SELF, header.private_futex))))
+# endif
+#endif
+
/* Initializer for compatibility lock. */
#define LLL_MUTEX_LOCK_INITIALIZER (0)
-#define lll_futex_wait(futexp, val) \
- ({ \
- INTERNAL_SYSCALL_DECL (__err); \
- long int __ret; \
- \
- __ret = INTERNAL_SYSCALL (futex, __err, 4, \
- (futexp), FUTEX_WAIT, (val), 0); \
- __ret; \
- })
+#define lll_futex_wait(futexp, val, private) \
+ lll_futex_timed_wait (futexp, val, NULL, private)
-#define lll_futex_timed_wait(futexp, val, timespec) \
+#define lll_futex_timed_wait(futexp, val, timespec, private) \
({ \
INTERNAL_SYSCALL_DECL (__err); \
long int __ret; \
\
- __ret = INTERNAL_SYSCALL (futex, __err, 4, \
- (futexp), FUTEX_WAIT, (val), (timespec)); \
+ __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \
+ __lll_private_flag (FUTEX_WAIT, private), \
+ (val), (timespec)); \
__ret; \
})
-#define lll_futex_wake(futexp, nr) \
+#define lll_futex_wake(futexp, nr, private) \
({ \
INTERNAL_SYSCALL_DECL (__err); \
long int __ret; \
\
- __ret = INTERNAL_SYSCALL (futex, __err, 4, \
- (futexp), FUTEX_WAKE, (nr), 0); \
+ __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \
+ __lll_private_flag (FUTEX_WAKE, private), \
+ (nr), 0); \
__ret; \
})
@@ -86,7 +115,7 @@
{ \
int *__futexp = &(futexv); \
atomic_or (__futexp, FUTEX_OWNER_DIED); \
- lll_futex_wake (__futexp, 1); \
+ lll_futex_wake (__futexp, 1, LLL_SHARED); \
} \
while (0)
@@ -212,7 +241,7 @@ __lll_robust_mutex_timedlock (int *futex, const struct timespec *abstime,
int *__futex = &(lock); \
int __val = atomic_exchange_24_rel (__futex, 0); \
if (__builtin_expect (__val > 1, 0)) \
- lll_futex_wake (__futex, 1); \
+ lll_futex_wake (__futex, 1, LLL_SHARED); \
}))
#define lll_robust_mutex_unlock(lock) \
@@ -220,14 +249,14 @@ __lll_robust_mutex_timedlock (int *futex, const struct timespec *abstime,
int *__futex = &(lock); \
int __val = atomic_exchange_rel (__futex, 0); \
if (__builtin_expect (__val & FUTEX_WAITERS, 0)) \
- lll_futex_wake (__futex, 1); \
+ lll_futex_wake (__futex, 1, LLL_SHARED); \
}))
#define lll_mutex_unlock_force(lock) \
((void) ({ \
int *__futex = &(lock); \
(void) atomic_exchange_24_rel (__futex, 0); \
- lll_futex_wake (__futex, 1); \
+ lll_futex_wake (__futex, 1, LLL_SHARED); \
}))
#define lll_mutex_islocked(futex) \
@@ -255,12 +284,12 @@ typedef int lll_lock_t;
thread ID while the clone is running and is reset to zero
afterwards. */
#define lll_wait_tid(tid) \
- do \
- { \
- __typeof (tid) __tid; \
- while ((__tid = (tid)) != 0) \
- lll_futex_wait (&(tid), __tid); \
- } \
+ do \
+ { \
+ __typeof (tid) __tid; \
+ while ((__tid = (tid)) != 0) \
+ lll_futex_wait (&(tid), __tid, LLL_SHARED); \
+ } \
while (0)
extern int __lll_timedwait_tid (int *, const struct timespec *)
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c b/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c
index 83fedef8e8..22e2dd3c0c 100644
--- a/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c
@@ -30,7 +30,7 @@ clear_once_control (void *arg)
pthread_once_t *once_control = (pthread_once_t *) arg;
*once_control = 0;
- lll_private_futex_wake (once_control, INT_MAX);
+ lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
}
@@ -65,7 +65,7 @@ __pthread_once (once_control, init_routine)
if (((oldval ^ newval) & -4) == 0)
{
/* Same generation, some other thread was faster. Wait. */
- lll_futex_wait (once_control, newval);
+ lll_futex_wait (once_control, newval, LLL_PRIVATE);
continue;
}
}
@@ -84,7 +84,7 @@ __pthread_once (once_control, init_routine)
atomic_increment (once_control);
/* Wake up all other threads. */
- lll_private_futex_wake (once_control, INT_MAX);
+ lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
break;
}
diff --git a/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c b/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c
index 240ce597f9..bc5b7537a3 100644
--- a/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c
+++ b/nptl/sysdeps/unix/sysv/linux/unregister-atfork.c
@@ -104,7 +104,7 @@ __unregister_atfork (dso_handle)
atomic_decrement (&deleted->handler->refcntr);
unsigned int val;
while ((val = deleted->handler->refcntr) != 0)
- lll_private_futex_wait (&deleted->handler->refcntr, val);
+ lll_futex_wait (&deleted->handler->refcntr, val, LLL_PRIVATE);
deleted = deleted->next;
}
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
index 6323d4850d..7ec7deff17 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
@@ -71,8 +71,8 @@
: (fl)) \
: ({ unsigned int __fl = ((private) ^ FUTEX_PRIVATE_FLAG); \
asm ("andl %%fs:%P1, %0" : "+r" (__fl) \
- : "i" offsetof (struct pthread, header.private_futex)); \
- __fl | (fl); })
+ : "i" (offsetof (struct pthread, header.private_futex))); \
+ __fl | (fl); }))
# endif
#endif
@@ -215,15 +215,6 @@ LLL_STUB_UNWIND_INFO_END
} while (0)
-#define lll_private_futex_wait(futex, val) \
- lll_futex_timed_wait (futex, val, NULL, LLL_PRIVATE)
-
-#define lll_private_futex_timed_wait(futex, val, timeout) \
- lll_futex_timed_wait (futex, val, timeout, LLL_PRIVATE)
-
-#define lll_private_futex_wake(futex, nr) \
- lll_futex_wake (futex, nr, LLL_PRIVATE)
-
/* Does not preserve %eax and %ecx. */
extern int __lll_mutex_lock_wait (int *__futex, int __val) attribute_hidden;
diff --git a/nptl/sysdeps/x86_64/tls.h b/nptl/sysdeps/x86_64/tls.h
index 029848a8fa..79db61c709 100644
--- a/nptl/sysdeps/x86_64/tls.h
+++ b/nptl/sysdeps/x86_64/tls.h
@@ -355,7 +355,7 @@ typedef struct
: "i" (offsetof (struct pthread, header.gscope_flag)), \
"0" (THREAD_GSCOPE_FLAG_UNUSED)); \
if (__res == THREAD_GSCOPE_FLAG_WAIT) \
- lll_private_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \
+ lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE); \
} \
while (0)
#define THREAD_GSCOPE_SET_FLAG() \