hppa: fix loading of global pointer in _start [BZ #20277]
[glibc.git] / sysdeps / nacl / futex-internal.h
blob0c5e02e8181a87b930f784ebb523183896e0ad40
1 /* futex operations for glibc-internal use. NaCl version.
2 Copyright (C) 2014-2016 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>
23 #include <errno.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
32 timeouts. */
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
38 value. */
39 #undef FUTEX_SHARED
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))
47 return 0;
48 else if (pshared == PTHREAD_PROCESS_SHARED)
49 return ENOTSUP;
50 else
51 return EINVAL;
54 /* Relative timeouts are only emulated via absolute timeouts using the
55 system clock. */
56 static __always_inline bool
57 futex_supports_exact_relative_timeouts (void)
59 return false;
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);
67 switch (err)
69 case 0:
70 case -EAGAIN:
71 case -EINTR:
72 return -err;
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
78 application bug. */
79 case -ENOSYS: /* Must have been caused by a glibc bug. */
80 /* No other errors are documented at this time. */
81 default:
82 futex_fatal_error ();
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,
89 int private)
91 int oldtype;
92 oldtype = __pthread_enable_asynccancel ();
93 int err = lll_futex_timed_wait (futex_word, expected, NULL, private);
94 __pthread_disable_asynccancel (oldtype);
95 switch (err)
97 case 0:
98 case -EAGAIN:
99 case -EINTR:
100 return -err;
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
106 application bug. */
107 case -ENOSYS: /* Must have been caused by a glibc bug. */
108 /* No other errors are documented at this time. */
109 default:
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);
120 switch (err)
122 case 0:
123 case -EAGAIN:
124 case -EINTR:
125 case -ETIMEDOUT:
126 return -err;
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
131 application bug. */
132 case -ENOSYS: /* Must have been caused by a glibc bug. */
133 /* No other errors are documented at this time. */
134 default:
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)
145 int oldtype;
146 oldtype = __pthread_enable_asynccancel ();
147 int err = lll_futex_timed_wait (futex_word, expected, reltime, private);
148 __pthread_disable_asynccancel (oldtype);
149 switch (err)
151 case 0:
152 case -EAGAIN:
153 case -EINTR:
154 case -ETIMEDOUT:
155 return -err;
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
160 application bug. */
161 case -ENOSYS: /* Must have been caused by a glibc bug. */
162 /* No other errors are documented at this time. */
163 default:
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,
174 expected, abstime);
175 switch (err)
177 case 0:
178 case EAGAIN:
179 case EINTR:
180 case ETIMEDOUT:
181 return err;
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
186 application bug. */
187 case ENOSYS: /* Must have been caused by a glibc bug. */
188 /* No other errors are documented at this time. */
189 default:
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)
200 int oldtype;
201 oldtype = __pthread_enable_asynccancel ();
202 int err = __nacl_irt_futex.futex_wait_abs ((volatile int *) futex_word,
203 expected, abstime);
204 __pthread_disable_asynccancel (oldtype);
205 switch (err)
207 case 0:
208 case EAGAIN:
209 case EINTR:
210 case ETIMEDOUT:
211 return err;
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
216 application bug. */
217 case ENOSYS: /* Must have been caused by a glibc bug. */
218 /* No other errors are documented at this time. */
219 default:
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. */
230 if (res >= 0)
231 return;
232 switch (res)
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
239 act in this case. */
240 return;
241 case -ENOSYS: /* Must have been caused by a glibc bug. */
242 /* No other errors are documented at this time. */
243 default:
244 futex_fatal_error ();
248 #endif /* futex-internal.h */