1/* futex operations for glibc-internal use. Stub version; do not include
2 this file directly.
3 Copyright (C) 2014-2019 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <http://www.gnu.org/licenses/>. */
19
20#ifndef STUB_FUTEX_INTERNAL_H
21#define STUB_FUTEX_INTERNAL_H
22
23#include <sys/time.h>
24#include <stdio.h>
25#include <stdbool.h>
26#include <libc-diag.h>
27
28/* This file defines futex operations used internally in glibc. A futex
29 consists of the so-called futex word in userspace, which is of type
30 unsigned int and represents an application-specific condition, and kernel
31 state associated with this particular futex word (e.g., wait queues). The
32 futex operations we provide are wrappers for the futex syscalls and add
33 glibc-specific error checking of the syscall return value. We abort on
34 error codes that are caused by bugs in glibc or in the calling application,
35 or when an error code is not known. We return error codes that can arise
36 in correct executions to the caller. Each operation calls out exactly the
37 return values that callers need to handle.
38
39 The private flag must be either FUTEX_PRIVATE or FUTEX_SHARED.
40 FUTEX_PRIVATE is always supported, and the implementation can internally
41 use FUTEX_SHARED when FUTEX_PRIVATE is requested. FUTEX_SHARED is not
42 necessarily supported (use futex_supports_pshared to detect this).
43
44 We expect callers to only use these operations if futexes and the
45 specific futex operations being used are supported (e.g., FUTEX_SHARED).
46
47 Given that waking other threads waiting on a futex involves concurrent
48 accesses to the futex word, you must use atomic operations to access the
49 futex word.
50
51 Both absolute and relative timeouts can be used. An absolute timeout
52 expires when the given specific point in time on the specified clock
53 passes, or when it already has passed. A relative timeout expires when
54 the given duration of time on the CLOCK_MONOTONIC clock passes.
55
56 Due to POSIX requirements on when synchronization data structures such
57 as mutexes or semaphores can be destroyed and due to the futex design
58 having separate fast/slow paths for wake-ups, we need to consider that
59 futex_wake calls might effectively target a data structure that has been
60 destroyed and reused for another object, or unmapped; thus, some
61 errors or spurious wake-ups can happen in correct executions that would
62 not be possible in a program using just a single futex whose lifetime
63 does not end before the program terminates. For background, see:
64 https://sourceware.org/ml/libc-alpha/2014-04/msg00075.html
65 https://lkml.org/lkml/2014/11/27/472 */
66
67/* Defined this way for interoperability with lowlevellock.
68 FUTEX_PRIVATE must be zero because the initializers for pthread_mutex_t,
69 pthread_rwlock_t, and pthread_cond_t initialize the respective field of
70 those structures to zero, and we want FUTEX_PRIVATE to be the default. */
71#define FUTEX_PRIVATE LLL_PRIVATE
72#define FUTEX_SHARED LLL_SHARED
73#if FUTEX_PRIVATE != 0
74# error FUTEX_PRIVATE must be equal to 0
75#endif
76
77/* Returns EINVAL if PSHARED is neither PTHREAD_PROCESS_PRIVATE nor
78 PTHREAD_PROCESS_SHARED; otherwise, returns 0 if PSHARED is supported, and
79 ENOTSUP if not. */
80static __always_inline int
81futex_supports_pshared (int pshared);
82
83/* Atomically wrt other futex operations on the same futex, this blocks iff
84 the value *FUTEX_WORD matches the expected value. This is
85 semantically equivalent to:
86 l = <get lock associated with futex> (FUTEX_WORD);
87 wait_flag = <get wait_flag associated with futex> (FUTEX_WORD);
88 lock (l);
89 val = atomic_load_relaxed (FUTEX_WORD);
90 if (val != expected) { unlock (l); return EAGAIN; }
91 atomic_store_relaxed (wait_flag, true);
92 unlock (l);
93 // Now block; can time out in futex_time_wait (see below)
94 while (atomic_load_relaxed(wait_flag) && !<spurious wake-up>);
95
96 Note that no guarantee of a happens-before relation between a woken
97 futex_wait and a futex_wake is documented; however, this does not matter
98 in practice because we have to consider spurious wake-ups (see below),
99 and thus would not be able to reliably reason about which futex_wake woke
100 us.
101
102 Returns 0 if woken by a futex operation or spuriously. (Note that due to
103 the POSIX requirements mentioned above, we need to conservatively assume
104 that unrelated futex_wake operations could wake this futex; it is easiest
105 to just be prepared for spurious wake-ups.)
106 Returns EAGAIN if the futex word did not match the expected value.
107 Returns EINTR if waiting was interrupted by a signal.
108
109 Note that some previous code in glibc assumed the underlying futex
110 operation (e.g., syscall) to start with or include the equivalent of a
111 seq_cst fence; this allows one to avoid an explicit seq_cst fence before
112 a futex_wait call when synchronizing similar to Dekker synchronization.
113 However, we make no such guarantee here. */
114static __always_inline int
115futex_wait (unsigned int *futex_word, unsigned int expected, int private);
116
117/* Like futex_wait but does not provide any indication why we stopped waiting.
118 Thus, when this function returns, you have to always check FUTEX_WORD to
119 determine whether you need to continue waiting, and you cannot detect
120 whether the waiting was interrupted by a signal. Example use:
121 while (atomic_load_relaxed (&futex_word) == 23)
122 futex_wait_simple (&futex_word, 23, FUTEX_PRIVATE);
123 This is common enough to make providing this wrapper worthwhile. */
124static __always_inline void
125futex_wait_simple (unsigned int *futex_word, unsigned int expected,
126 int private)
127{
128 ignore_value (futex_wait (futex_word, expected, private));
129}
130
131
132/* Like futex_wait but is a POSIX cancellation point. */
133static __always_inline int
134futex_wait_cancelable (unsigned int *futex_word, unsigned int expected,
135 int private);
136
137/* Like futex_wait, but will eventually time out (i.e., stop being
138 blocked) after the duration of time provided (i.e., RELTIME) has
139 passed. The caller must provide a normalized RELTIME. RELTIME can also
140 equal NULL, in which case this function behaves equivalent to futex_wait.
141
142 Returns the same values as futex_wait under those same conditions;
143 additionally, returns ETIMEDOUT if the timeout expired.
144 */
145static __always_inline int
146futex_reltimed_wait (unsigned int* futex_word, unsigned int expected,
147 const struct timespec* reltime, int private);
148
149/* Like futex_reltimed_wait but is a POSIX cancellation point. */
150static __always_inline int
151futex_reltimed_wait_cancelable (unsigned int* futex_word,
152 unsigned int expected,
153 const struct timespec* reltime, int private);
154
155/* Check whether the specified clockid is supported by
156 futex_abstimed_wait and futex_abstimed_wait_cancelable. */
157static __always_inline int
158futex_abstimed_supported_clockid (clockid_t clockid);
159
160/* Like futex_reltimed_wait, but the provided timeout (ABSTIME) is an
161 absolute point in time; a call will time out after this point in time. */
162static __always_inline int
163futex_abstimed_wait (unsigned int* futex_word, unsigned int expected,
164 clockid_t clockid,
165 const struct timespec* abstime, int private);
166
167/* Like futex_reltimed_wait but is a POSIX cancellation point. */
168static __always_inline int
169futex_abstimed_wait_cancelable (unsigned int* futex_word,
170 unsigned int expected,
171 clockid_t clockid,
172 const struct timespec* abstime, int private);
173
174/* Atomically wrt other futex operations on the same futex, this unblocks the
175 specified number of processes, or all processes blocked on this futex if
176 there are fewer than the specified number. Semantically, this is
177 equivalent to:
178 l = <get lock associated with futex> (FUTEX_WORD);
179 lock (l);
180 for (res = 0; PROCESSES_TO_WAKE > 0; PROCESSES_TO_WAKE--, res++) {
181 if (<no process blocked on futex>) break;
182 wf = <get wait_flag of a process blocked on futex> (FUTEX_WORD);
183 // No happens-before guarantee with woken futex_wait (see above)
184 atomic_store_relaxed (wf, 0);
185 }
186 return res;
187
188 Note that we need to support futex_wake calls to past futexes whose memory
189 has potentially been reused due to POSIX' requirements on synchronization
190 object destruction (see above); therefore, we must not report or abort
191 on most errors. */
192static __always_inline void
193futex_wake (unsigned int* futex_word, int processes_to_wake, int private);
194
195/* Calls __libc_fatal with an error message. Convenience function for
196 concrete implementations of the futex interface. */
197static __always_inline __attribute__ ((__noreturn__)) void
198futex_fatal_error (void)
199{
200 __libc_fatal ("The futex facility returned an unexpected error code.\n");
201}
202
203#endif /* futex-internal.h */
204