2 * SPDX-License-Identifier: LGPL-2.1-or-later
4 * Copyright (c) 2009 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
6 * Userspace RCU library - sys_futex compatibility code
17 #include <urcu/arch.h>
18 #include <urcu/system.h>
22 * Using attribute "weak" for __lttng_ust_compat_futex_lock and
23 * __lttng_ust_compat_futex_cond. Those are globally visible by the entire
24 * program, even though many shared objects may have their own version.
25 * The first version that gets loaded will be used by the entire program
26 * (executable and all shared objects).
30 pthread_mutex_t __lttng_ust_compat_futex_lock
= PTHREAD_MUTEX_INITIALIZER
;
32 pthread_cond_t __lttng_ust_compat_futex_cond
= PTHREAD_COND_INITIALIZER
;
35 * _NOT SIGNAL-SAFE_. pthread_cond is not signal-safe anyway. Though.
36 * For now, timeout, uaddr2 and val3 are unused.
37 * Waiter will relinquish the CPU until woken up.
40 int lttng_ust_compat_futex_noasync(int32_t *uaddr
, int op
, int32_t val
,
41 const struct timespec
*timeout
, int32_t *uaddr2
, int32_t val3
)
46 * Check if NULL. Don't let users expect that they are taken into
54 * memory barriers to serialize with the previous uaddr modification.
58 lockret
= pthread_mutex_lock(&__lttng_ust_compat_futex_lock
);
67 * Wait until *uaddr is changed to something else than "val".
68 * Comparing *uaddr content against val figures out which
69 * thread has been awakened.
71 while (CMM_LOAD_SHARED(*uaddr
) == val
)
72 pthread_cond_wait(&__lttng_ust_compat_futex_cond
,
73 &__lttng_ust_compat_futex_lock
);
77 * Each wake is sending a broadcast, thus attempting wakeup of
78 * all awaiting threads, independently of their respective
81 pthread_cond_broadcast(&__lttng_ust_compat_futex_cond
);
87 lockret
= pthread_mutex_unlock(&__lttng_ust_compat_futex_lock
);
97 * _ASYNC SIGNAL-SAFE_.
98 * For now, timeout, uaddr2 and val3 are unused.
99 * Waiter will busy-loop trying to read the condition.
100 * It is OK to use compat_futex_async() on a futex address on which
101 * futex() WAKE operations are also performed.
104 int lttng_ust_compat_futex_async(int32_t *uaddr
, int op
, int32_t val
,
105 const struct timespec
*timeout
, int32_t *uaddr2
, int32_t val3
)
110 * Check if NULL. Don't let users expect that they are taken into
118 * Ensure previous memory operations on uaddr have completed.
124 while (CMM_LOAD_SHARED(*uaddr
) == val
) {
125 if (poll(NULL
, 0, 10) < 0) {
127 /* Keep poll errno. Caller handles EINTR. */