]>
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 <sysdep-cancel.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_supported_clockid (clockid_t clockid
)
167 return lll_futex_supported_clockid (clockid
);
170 /* See sysdeps/nptl/futex-internal.h for details. */
171 static __always_inline
int
172 futex_abstimed_wait (unsigned int *futex_word
, unsigned int expected
,
174 const struct timespec
*abstime
, int private)
176 /* Work around the fact that the kernel rejects negative timeout values
177 despite them being valid. */
178 if (__glibc_unlikely ((abstime
!= NULL
) && (abstime
->tv_sec
< 0)))
180 int err
= lll_futex_clock_wait_bitset (futex_word
, expected
,
191 case -EFAULT
: /* Must have been caused by a glibc or application bug. */
192 case -EINVAL
: /* Either due to wrong alignment, unsupported
193 clockid or due to the timeout not being
194 normalized. Must have been caused by a glibc or
196 case -ENOSYS
: /* Must have been caused by a glibc bug. */
197 /* No other errors are documented at this time. */
199 futex_fatal_error ();
203 /* See sysdeps/nptl/futex-internal.h for details. */
204 static __always_inline
int
205 futex_abstimed_wait_cancelable (unsigned int *futex_word
,
206 unsigned int expected
,
208 const struct timespec
*abstime
, int private)
210 /* Work around the fact that the kernel rejects negative timeout values
211 despite them being valid. */
212 if (__glibc_unlikely ((abstime
!= NULL
) && (abstime
->tv_sec
< 0)))
215 oldtype
= __pthread_enable_asynccancel ();
216 int err
= lll_futex_clock_wait_bitset (futex_word
, expected
,
219 __pthread_disable_asynccancel (oldtype
);
228 case -EFAULT
: /* Must have been caused by a glibc or application bug. */
229 case -EINVAL
: /* Either due to wrong alignment or due to the timeout not
230 being normalized. Must have been caused by a glibc or
232 case -ENOSYS
: /* Must have been caused by a glibc bug. */
233 /* No other errors are documented at this time. */
235 futex_fatal_error ();
239 /* See sysdeps/nptl/futex-internal.h for details. */
240 static __always_inline
void
241 futex_wake (unsigned int *futex_word
, int processes_to_wake
, int private)
243 int res
= lll_futex_wake (futex_word
, processes_to_wake
, private);
244 /* No error. Ignore the number of woken processes. */
249 case -EFAULT
: /* Could have happened due to memory reuse. */
250 case -EINVAL
: /* Could be either due to incorrect alignment (a bug in
251 glibc or in the application) or due to memory being
252 reused for a PI futex. We cannot distinguish between the
253 two causes, and one of them is correct use, so we do not
256 case -ENOSYS
: /* Must have been caused by a glibc bug. */
257 /* No other errors are documented at this time. */
259 futex_fatal_error ();
263 #endif /* futex-internal.h */