1 /* futex operations for glibc-internal use. NaCl version.
2 Copyright (C) 2014-2015 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 <nacl-interfaces.h>
26 #include <nptl/pthreadP.h>
28 /* See sysdeps/nptl/futex-internal.h for documentation; this file only
29 contains NaCl-specific comments.
31 There is no support yet for shared futexes nor for exact relative
34 /* See sysdeps/nptl/futex-internal.h for constraints on the value of the
35 FUTEX_PRIVATE and FUTEX_SHARED constants.
36 Shared futexes are not yet supported, and we never allow clients to
37 actually request shared futexes. Therefore, we do not need a different
40 #define FUTEX_SHARED FUTEX_PRIVATE
42 /* FUTEX_SHARED is not yet supported. */
43 static __always_inline
int
44 futex_supports_pshared (int pshared
)
46 if (__glibc_likely (pshared
== PTHREAD_PROCESS_PRIVATE
))
48 else if (pshared
== PTHREAD_PROCESS_SHARED
)
54 /* Relative timeouts are only emulated via absolute timeouts using the
56 static __always_inline
bool
57 futex_supports_exact_relative_timeouts (void)
62 /* See sysdeps/nptl/futex-internal.h for details. */
63 static __always_inline
int
64 futex_wait (unsigned int *futex_word
, unsigned int expected
, int private)
66 int err
= lll_futex_timed_wait (futex_word
, expected
, NULL
, private);
74 case -ETIMEDOUT
: /* Cannot have happened as we provided no timeout. */
75 case -EFAULT
: /* Must have been caused by a glibc or application bug. */
76 case -EINVAL
: /* Either due to wrong alignment or due to the timeout not
77 being normalized. Must have been caused by a glibc or
79 case -ENOSYS
: /* Must have been caused by a glibc bug. */
80 /* No other errors are documented at this time. */
86 /* See sysdeps/nptl/futex-internal.h for details. */
87 static __always_inline
int
88 futex_wait_cancelable (unsigned int *futex_word
, unsigned int expected
,
92 oldtype
= __pthread_enable_asynccancel ();
93 int err
= lll_futex_timed_wait (futex_word
, expected
, NULL
, private);
94 __pthread_disable_asynccancel (oldtype
);
102 case -ETIMEDOUT
: /* Cannot have happened as we provided no timeout. */
103 case -EFAULT
: /* Must have been caused by a glibc or application bug. */
104 case -EINVAL
: /* Either due to wrong alignment or due to the timeout not
105 being normalized. Must have been caused by a glibc or
107 case -ENOSYS
: /* Must have been caused by a glibc bug. */
108 /* No other errors are documented at this time. */
110 futex_fatal_error ();
114 /* See sysdeps/nptl/futex-internal.h for details. */
115 static __always_inline
int
116 futex_reltimed_wait (unsigned int *futex_word
, unsigned int expected
,
117 const struct timespec
*reltime
, int private)
119 int err
= lll_futex_timed_wait (futex_word
, expected
, reltime
, private);
128 case -EFAULT
: /* Must have been caused by a glibc or application bug. */
129 case -EINVAL
: /* Either due to wrong alignment or due to the timeout not
130 being normalized. Must have been caused by a glibc or
132 case -ENOSYS
: /* Must have been caused by a glibc bug. */
133 /* No other errors are documented at this time. */
135 futex_fatal_error ();
139 /* See sysdeps/nptl/futex-internal.h for details. */
140 static __always_inline
int
141 futex_reltimed_wait_cancelable (unsigned int *futex_word
,
142 unsigned int expected
,
143 const struct timespec
*reltime
, int private)
146 oldtype
= __pthread_enable_asynccancel ();
147 int err
= lll_futex_timed_wait (futex_word
, expected
, reltime
, private);
148 __pthread_disable_asynccancel (oldtype
);
157 case -EFAULT
: /* Must have been caused by a glibc or application bug. */
158 case -EINVAL
: /* Either due to wrong alignment or due to the timeout not
159 being normalized. Must have been caused by a glibc or
161 case -ENOSYS
: /* Must have been caused by a glibc bug. */
162 /* No other errors are documented at this time. */
164 futex_fatal_error ();
168 /* See sysdeps/nptl/futex-internal.h for details. */
169 static __always_inline
int
170 futex_abstimed_wait (unsigned int *futex_word
, unsigned int expected
,
171 const struct timespec
*abstime
, int private)
173 int err
= __nacl_irt_futex
.futex_wait_abs ((volatile int *) futex_word
,
183 case EFAULT
: /* Must have been caused by a glibc or application bug. */
184 case EINVAL
: /* Either due to wrong alignment or due to the timeout not
185 being normalized. Must have been caused by a glibc or
187 case ENOSYS
: /* Must have been caused by a glibc bug. */
188 /* No other errors are documented at this time. */
190 futex_fatal_error ();
194 /* See sysdeps/nptl/futex-internal.h for details. */
195 static __always_inline
int
196 futex_abstimed_wait_cancelable (unsigned int *futex_word
,
197 unsigned int expected
,
198 const struct timespec
*abstime
, int private)
201 oldtype
= __pthread_enable_asynccancel ();
202 int err
= __nacl_irt_futex
.futex_wait_abs ((volatile int *) futex_word
,
204 __pthread_disable_asynccancel (oldtype
);
213 case EFAULT
: /* Must have been caused by a glibc or application bug. */
214 case EINVAL
: /* Either due to wrong alignment or due to the timeout not
215 being normalized. Must have been caused by a glibc or
217 case ENOSYS
: /* Must have been caused by a glibc bug. */
218 /* No other errors are documented at this time. */
220 futex_fatal_error ();
224 /* See sysdeps/nptl/futex-internal.h for details. */
225 static __always_inline
void
226 futex_wake (unsigned int *futex_word
, int processes_to_wake
, int private)
228 int res
= lll_futex_wake (futex_word
, processes_to_wake
, private);
229 /* No error. Ignore the number of woken processes. */
234 case -EFAULT
: /* Could have happened due to memory reuse. */
235 case -EINVAL
: /* Could be either due to incorrect alignment (a bug in
236 glibc or in the application) or due to memory being
237 reused for a PI futex. We cannot distinguish between the
238 two causes, and one of them is correct use, so we do not
241 case -ENOSYS
: /* Must have been caused by a glibc bug. */
242 /* No other errors are documented at this time. */
244 futex_fatal_error ();
248 #endif /* futex-internal.h */