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>
20 #include "common/compat/futex.h"
23 * Using attribute "weak" for __lttng_ust_compat_futex_lock and
24 * __lttng_ust_compat_futex_cond. Those are globally visible by the entire
25 * program, even though many shared objects may have their own version.
26 * The first version that gets loaded will be used by the entire program
27 * (executable and all shared objects).
31 pthread_mutex_t __lttng_ust_compat_futex_lock
= PTHREAD_MUTEX_INITIALIZER
;
33 pthread_cond_t __lttng_ust_compat_futex_cond
= PTHREAD_COND_INITIALIZER
;
36 * _NOT SIGNAL-SAFE_. pthread_cond is not signal-safe anyway. Though.
37 * For now, timeout, uaddr2 and val3 are unused.
38 * Waiter will relinquish the CPU until woken up.
41 int lttng_ust_compat_futex_noasync(int32_t *uaddr
, int op
, int32_t val
,
42 const struct timespec
*timeout
, int32_t *uaddr2
, int32_t val3
)
47 * Check if NULL. Don't let users expect that they are taken into
55 * memory barriers to serialize with the previous uaddr modification.
59 lockret
= pthread_mutex_lock(&__lttng_ust_compat_futex_lock
);
68 * Wait until *uaddr is changed to something else than "val".
69 * Comparing *uaddr content against val figures out which
70 * thread has been awakened.
72 while (CMM_LOAD_SHARED(*uaddr
) == val
)
73 pthread_cond_wait(&__lttng_ust_compat_futex_cond
,
74 &__lttng_ust_compat_futex_lock
);
78 * Each wake is sending a broadcast, thus attempting wakeup of
79 * all awaiting threads, independently of their respective
82 pthread_cond_broadcast(&__lttng_ust_compat_futex_cond
);
88 lockret
= pthread_mutex_unlock(&__lttng_ust_compat_futex_lock
);
98 * _ASYNC SIGNAL-SAFE_.
99 * For now, timeout, uaddr2 and val3 are unused.
100 * Waiter will busy-loop trying to read the condition.
101 * It is OK to use compat_futex_async() on a futex address on which
102 * futex() WAKE operations are also performed.
105 int lttng_ust_compat_futex_async(int32_t *uaddr
, int op
, int32_t val
,
106 const struct timespec
*timeout
, int32_t *uaddr2
, int32_t val3
)
111 * Check if NULL. Don't let users expect that they are taken into
119 * Ensure previous memory operations on uaddr have completed.
125 while (CMM_LOAD_SHARED(*uaddr
) == val
) {
126 if (poll(NULL
, 0, 10) < 0) {
128 /* Keep poll errno. Caller handles EINTR. */