* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
[platform/upstream/glibc.git] / nptl / sysdeps / unix / sysv / linux / powerpc / lowlevellock.h
index 20547f9..ab79534 100644 (file)
 #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;                \
   })
 
   })
 
 /* Returns non-zero if error happened, zero if success.  */
-#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2) \
+#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \
   ({                                                                         \
     INTERNAL_SYSCALL_DECL (__err);                                           \
     long int __ret;                                                          \
                                                                              \
-    __ret = INTERNAL_SYSCALL (futex, __err, 6,                               \
-                             (futexp), FUTEX_WAKE_OP, (nr_wake),             \
-                             (nr_wake2), (futexp2),                          \
+    __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp),                     \
+                             __lll_private_flag (FUTEX_WAKE_OP, private),    \
+                             (nr_wake), (nr_wake2), (futexp2),               \
                              FUTEX_OP_CLEAR_WAKE_IF_GT_ONE);                 \
     INTERNAL_SYSCALL_ERROR_P (__ret, __err);                                 \
   })
+  
+  
+#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       ""
@@ -230,7 +264,7 @@ extern int __lll_robust_timedlock_wait
     int *__futex = &(lock);                                                  \
     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_robust_mutex_unlock(lock) \
@@ -238,7 +272,7 @@ extern int __lll_robust_timedlock_wait
     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) \
@@ -246,7 +280,7 @@ extern int __lll_robust_timedlock_wait
     int *__futex = &(lock);                                                  \
     *__futex = 0;                                                            \
     __asm __volatile (__lll_rel_instr ::: "memory");                         \
-    lll_futex_wake (__futex, 1);                                             \
+    lll_futex_wake (__futex, 1, LLL_SHARED);                                 \
   }))
 
 #define lll_mutex_islocked(futex) \
@@ -281,7 +315,7 @@ typedef int lll_lock_t;
   do {                                                                       \
     __typeof (tid) __tid;                                                    \
     while ((__tid = (tid)) != 0)                                             \
-      lll_futex_wait (&(tid), __tid);                                        \
+      lll_futex_wait (&(tid), __tid, LLL_SHARED);                            \
   } while (0)
 
 extern int __lll_timedwait_tid (int *, const struct timespec *)