summaryrefslogtreecommitdiff
path: root/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
diff options
context:
space:
mode:
Diffstat (limited to 'nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h')
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h83
1 files changed, 55 insertions, 28 deletions
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
index 5013922a2f..922e3c21d3 100644
--- a/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
@@ -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) \
@@ -240,8 +269,6 @@ __lll_robust_mutex_timedlock (int *futex, const struct timespec *abstime,
/* Type for lock object. */
typedef int lll_lock_t;
-extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
-
/* Initializers for lock. */
#define LLL_LOCK_INITIALIZER (0)
#define LLL_LOCK_INITIALIZER_LOCKED (1)
@@ -257,12 +284,12 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
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 *)