summaryrefslogtreecommitdiff
path: root/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
diff options
context:
space:
mode:
Diffstat (limited to 'nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h')
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h82
1 files changed, 46 insertions, 36 deletions
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
index 21de09fe91..56f63a4623 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -23,6 +23,8 @@
#include <time.h>
#include <sys/param.h>
#include <bits/pthreadtypes.h>
+#include <kernel-features.h>
+#include <tcb-offsets.h>
#ifndef LOCK_INSTR
# ifdef UP
@@ -38,6 +40,41 @@
#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)) \
+ : ({ unsigned int __fl = ((private) ^ FUTEX_PRIVATE_FLAG); \
+ asm ("andl %%fs:%P1, %0" : "+r" (__fl) \
+ : "i" (offsetof (struct pthread, header.private_futex))); \
+ __fl | (fl); }))
+# endif
+#endif
/* Initializer for compatibility lock. */
@@ -144,23 +181,11 @@ LLL_STUB_UNWIND_INFO_START \
LLL_STUB_UNWIND_INFO_END
-#define lll_futex_wait(futex, val) \
- ({ \
- int __status; \
- register __typeof (val) _val asm ("edx") = (val); \
- __asm __volatile (LLL_EBX_LOAD \
- LLL_ENTER_KERNEL \
- LLL_EBX_LOAD \
- : "=a" (__status) \
- : "0" (SYS_futex), LLL_EBX_REG (futex), "S" (0), \
- "c" (FUTEX_WAIT), "d" (_val), \
- "i" (offsetof (tcbhead_t, sysinfo)) \
- : "memory"); \
- __status; \
- })
+#define lll_futex_wait(futex, val, private) \
+ lll_futex_timed_wait (futex, val, NULL, private)
-#define lll_futex_timed_wait(futex, val, timeout) \
+#define lll_futex_timed_wait(futex, val, timeout, private) \
({ \
int __status; \
register __typeof (val) _val asm ("edx") = (val); \
@@ -169,14 +194,14 @@ LLL_STUB_UNWIND_INFO_END
LLL_EBX_LOAD \
: "=a" (__status) \
: "0" (SYS_futex), LLL_EBX_REG (futex), "S" (timeout), \
- "c" (FUTEX_WAIT), "d" (_val), \
- "i" (offsetof (tcbhead_t, sysinfo)) \
+ "c" (__lll_private_flag (FUTEX_WAIT, private)), \
+ "d" (_val), "i" (offsetof (tcbhead_t, sysinfo)) \
: "memory"); \
__status; \
})
-#define lll_futex_wake(futex, nr) \
+#define lll_futex_wake(futex, nr, private) \
do { \
int __ignore; \
register __typeof (nr) _nr asm ("edx") = (nr); \
@@ -185,7 +210,8 @@ LLL_STUB_UNWIND_INFO_END
LLL_EBX_LOAD \
: "=a" (__ignore) \
: "0" (SYS_futex), LLL_EBX_REG (futex), \
- "c" (FUTEX_WAKE), "d" (_nr), \
+ "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)
@@ -414,21 +440,6 @@ extern int __lll_mutex_unlock_wake (int *__futex)
"i" (offsetof (tcbhead_t, sysinfo))); })
-#define lll_futex_wake(futex, nr) \
- do { \
- int __ignore; \
- register __typeof (nr) _nr asm ("edx") = (nr); \
- __asm __volatile (LLL_EBX_LOAD \
- LLL_ENTER_KERNEL \
- LLL_EBX_LOAD \
- : "=a" (__ignore) \
- : "0" (SYS_futex), LLL_EBX_REG (futex), \
- "c" (FUTEX_WAKE), "d" (_nr), \
- "i" (0) /* phony, to align next arg's number */, \
- "i" (offsetof (tcbhead_t, sysinfo))); \
- } while (0)
-
-
#define lll_mutex_islocked(futex) \
(futex != 0)
@@ -448,7 +459,6 @@ extern int __lll_lock_wait (int val, int *__futex)
__attribute ((regparm (2))) attribute_hidden;
extern int __lll_unlock_wake (int *__futex)
__attribute ((regparm (1))) attribute_hidden;
-extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
/* The states of a lock are: