aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv/linux/sparc/lowlevellock.h')
-rw-r--r--sysdeps/unix/sysv/linux/sparc/lowlevellock.h39
1 files changed, 20 insertions, 19 deletions
diff --git a/sysdeps/unix/sysv/linux/sparc/lowlevellock.h b/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
index 47946c3eb5..5aed572d43 100644
--- a/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
+++ b/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
@@ -108,28 +108,29 @@ __lll_timedlock (int *futex, const struct timespec *abstime, int private)
#define LLL_LOCK_INITIALIZER (0)
#define LLL_LOCK_INITIALIZER_LOCKED (1)
-/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex
- wakeup when the clone terminates. The memory location contains the
- 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, LLL_SHARED); \
- } \
- while (0)
-
extern int __lll_timedwait_tid (int *, const struct timespec *)
attribute_hidden;
-#define lll_timedwait_tid(tid, abstime) \
- ({ \
- int __res = 0; \
- if ((tid) != 0) \
- __res = __lll_timedwait_tid (&(tid), (abstime)); \
- __res; \
+/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex
+ wake-up when the clone terminates. The memory location contains the
+ thread ID while the clone is running and is reset to zero by the kernel
+ afterwards. The kernel up to version 3.16.3 does not use the private futex
+ operations for futex wake-up when the clone terminates.
+ If ABSTIME is not NULL, is used a timeout for futex call. If the timeout
+ occurs then return ETIMEOUT, if ABSTIME is invalid, return EINVAL.
+ The futex operation are issues with cancellable versions. */
+#define lll_wait_tid(tid, abstime) \
+ ({ \
+ int __res = 0; \
+ __typeof (tid) __tid; \
+ if (abstime != NULL) \
+ __res = __lll_timedwait_tid (&(tid), (abstime)); \
+ else \
+ /* We need acquire MO here so that we synchronize with the \
+ kernel's store to 0 when the clone terminates. (see above) */ \
+ while ((__tid = atomic_load_acquire (&(tid))) != 0) \
+ lll_futex_wait_cancel (&(tid), __tid, LLL_SHARED); \
+ __res; \
})
#endif /* lowlevellock.h */