]>
git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/unix/sysv/linux/futex-internal.h
1 /* futex operations for glibc-internal use. Linux version.
2 Copyright (C) 2014-2019 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
19 #ifndef FUTEX_INTERNAL_H
20 #define FUTEX_INTERNAL_H
22 #include <sysdeps/nptl/futex-internal.h>
24 #include <lowlevellock-futex.h>
25 #include <nptl/pthreadP.h>
27 /* See sysdeps/nptl/futex-internal.h for documentation; this file only
28 contains Linux-specific comments.
30 The Linux kernel treats provides absolute timeouts based on the
31 CLOCK_REALTIME clock and relative timeouts measured against the
32 CLOCK_MONOTONIC clock.
34 We expect a Linux kernel version of 2.6.22 or more recent (since this
35 version, EINTR is not returned on spurious wake-ups anymore). */
37 /* FUTEX_SHARED is always supported by the Linux kernel. */
38 static __always_inline
int
39 futex_supports_pshared (int pshared
)
41 if (__glibc_likely (pshared
== PTHREAD_PROCESS_PRIVATE
))
43 else if (pshared
== PTHREAD_PROCESS_SHARED
)
49 /* The Linux kernel supports relative timeouts measured against the
50 CLOCK_MONOTONIC clock. */
51 static __always_inline
bool
52 futex_supports_exact_relative_timeouts (void)
57 /* See sysdeps/nptl/futex-internal.h for details. */
58 static __always_inline
int
59 futex_wait (unsigned int *futex_word
, unsigned int expected
, int private)
61 int err
= lll_futex_timed_wait (futex_word
, expected
, NULL
, private);
69 case -ETIMEDOUT
: /* Cannot have happened as we provided no timeout. */
70 case -EFAULT
: /* Must have been caused by a glibc or application bug. */
71 case -EINVAL
: /* Either due to wrong alignment or due to the timeout not
72 being normalized. Must have been caused by a glibc or
74 case -ENOSYS
: /* Must have been caused by a glibc bug. */
75 /* No other errors are documented at this time. */
81 /* See sysdeps/nptl/futex-internal.h for details. */
82 static __always_inline
int
83 futex_wait_cancelable (unsigned int *futex_word
, unsigned int expected
,
87 oldtype
= __pthread_enable_asynccancel ();
88 int err
= lll_futex_timed_wait (futex_word
, expected
, NULL
, private);
89 __pthread_disable_asynccancel (oldtype
);
97 case -ETIMEDOUT
: /* Cannot have happened as we provided no timeout. */
98 case -EFAULT
: /* Must have been caused by a glibc or application bug. */
99 case -EINVAL
: /* Either due to wrong alignment or due to the timeout not
100 being normalized. Must have been caused by a glibc or
102 case -ENOSYS
: /* Must have been caused by a glibc bug. */
103 /* No other errors are documented at this time. */
105 futex_fatal_error ();
109 /* See sysdeps/nptl/futex-internal.h for details. */
110 static __always_inline
int
111 futex_reltimed_wait (unsigned int *futex_word
, unsigned int expected
,
112 const struct timespec
*reltime
, int private)
114 int err
= lll_futex_timed_wait (futex_word
, expected
, reltime
, private);
123 case -EFAULT
: /* Must have been caused by a glibc or application bug. */
124 case -EINVAL
: /* Either due to wrong alignment or due to the timeout not
125 being normalized. Must have been caused by a glibc or
127 case -ENOSYS
: /* Must have been caused by a glibc bug. */
128 /* No other errors are documented at this time. */
130 futex_fatal_error ();
134 /* See sysdeps/nptl/futex-internal.h for details. */
135 static __always_inline
int
136 futex_reltimed_wait_cancelable (unsigned int *futex_word
,
137 unsigned int expected
,
138 const struct timespec
*reltime
, int private)
141 oldtype
= LIBC_CANCEL_ASYNC ();
142 int err
= lll_futex_timed_wait (futex_word
, expected
, reltime
, private);
143 LIBC_CANCEL_RESET (oldtype
);
152 case -EFAULT
: /* Must have been caused by a glibc or application bug. */
153 case -EINVAL
: /* Either due to wrong alignment or due to the timeout not
154 being normalized. Must have been caused by a glibc or
156 case -ENOSYS
: /* Must have been caused by a glibc bug. */
157 /* No other errors are documented at this time. */
159 futex_fatal_error ();
163 /* See sysdeps/nptl/futex-internal.h for details. */
164 static __always_inline
int
165 futex_abstimed_wait (unsigned int *futex_word
, unsigned int expected
,
166 const struct timespec
*abstime
, int private)
168 /* Work around the fact that the kernel rejects negative timeout values
169 despite them being valid. */
170 if (__glibc_unlikely ((abstime
!= NULL
) && (abstime
->tv_sec
< 0)))
172 int err
= lll_futex_timed_wait_bitset (futex_word
, expected
, abstime
,
173 FUTEX_CLOCK_REALTIME
, private);
182 case -EFAULT
: /* Must have been caused by a glibc or application bug. */
183 case -EINVAL
: /* Either due to wrong alignment or due to the timeout not
184 being normalized. Must have been caused by a glibc or
186 case -ENOSYS
: /* Must have been caused by a glibc bug. */
187 /* No other errors are documented at this time. */
189 futex_fatal_error ();
193 /* See sysdeps/nptl/futex-internal.h for details. */
194 static __always_inline
int
195 futex_abstimed_wait_cancelable (unsigned int *futex_word
,
196 unsigned int expected
,
197 const struct timespec
*abstime
, int private)
199 /* Work around the fact that the kernel rejects negative timeout values
200 despite them being valid. */
201 if (__glibc_unlikely ((abstime
!= NULL
) && (abstime
->tv_sec
< 0)))
204 oldtype
= __pthread_enable_asynccancel ();
205 int err
= lll_futex_timed_wait_bitset (futex_word
, expected
, abstime
,
206 FUTEX_CLOCK_REALTIME
, private);
207 __pthread_disable_asynccancel (oldtype
);
216 case -EFAULT
: /* Must have been caused by a glibc or application bug. */
217 case -EINVAL
: /* Either due to wrong alignment or due to the timeout not
218 being normalized. Must have been caused by a glibc or
220 case -ENOSYS
: /* Must have been caused by a glibc bug. */
221 /* No other errors are documented at this time. */
223 futex_fatal_error ();
227 /* See sysdeps/nptl/futex-internal.h for details. */
228 static __always_inline
void
229 futex_wake (unsigned int *futex_word
, int processes_to_wake
, int private)
231 int res
= lll_futex_wake (futex_word
, processes_to_wake
, private);
232 /* No error. Ignore the number of woken processes. */
237 case -EFAULT
: /* Could have happened due to memory reuse. */
238 case -EINVAL
: /* Could be either due to incorrect alignment (a bug in
239 glibc or in the application) or due to memory being
240 reused for a PI futex. We cannot distinguish between the
241 two causes, and one of them is correct use, so we do not
244 case -ENOSYS
: /* Must have been caused by a glibc bug. */
245 /* No other errors are documented at this time. */
247 futex_fatal_error ();
251 #endif /* futex-internal.h */