about summary refs log tree commit diff
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 *)