chiark / gitweb /
eglibc (2.11.3-4+deb6u3) squeeze-lts; urgency=medium
[eglibc.git] / debian / patches / hppa / local-linuxthreads.diff
1 ---
2  ports/sysdeps/unix/sysv/linux/hppa/linuxthreads/lowlevellock.h  |  298 ++++++++++
3  ports/sysdeps/unix/sysv/linux/hppa/linuxthreads/sysdep-cancel.h |    7 
4  2 files changed, 305 insertions(+)
5
6 --- /dev/null
7 +++ b/ports/sysdeps/unix/sysv/linux/hppa/linuxthreads/lowlevellock.h
8 @@ -0,0 +1,298 @@
9 +/* Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
10 +   This file is part of the GNU C Library.
11 +
12 +   The GNU C Library is free software; you can redistribute it and/or
13 +   modify it under the terms of the GNU Lesser General Public
14 +   License as published by the Free Software Foundation; either
15 +   version 2.1 of the License, or (at your option) any later version.
16 +
17 +   The GNU C Library is distributed in the hope that it will be useful,
18 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
19 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
20 +   Lesser General Public License for more details.
21 +
22 +   You should have received a copy of the GNU Lesser General Public
23 +   License along with the GNU C Library; if not, write to the Free
24 +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25 +   02111-1307 USA.  */
26 +
27 +#ifndef _LOWLEVELLOCK_H
28 +#define _LOWLEVELLOCK_H        1
29 +
30 +#include <time.h>
31 +#include <sys/param.h>
32 +#include <bits/pthreadtypes.h>
33 +#include <sysdep.h>
34 +#include <atomic.h>
35 +
36 +/* The hppa only has one atomic read and modify memory operation,
37 +   load and clear, so hppa uses a kernel helper routine to implement
38 +   compare_and_exchange. See atomic.h for the userspace calling
39 +   sequence.  */
40 +
41 +#define FUTEX_WAIT             0
42 +#define FUTEX_WAKE             1
43 +#define FUTEX_REQUEUE          3
44 +#define FUTEX_CMP_REQUEUE      4
45 +#define FUTEX_WAKE_OP          5
46 +#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE  ((4 << 24) | 1)
47 +#define FUTEX_LOCK_PI          6
48 +#define FUTEX_UNLOCK_PI                7
49 +#define FUTEX_TRYLOCK_PI       8
50 +
51 +/* Initialize locks to zero.  */
52 +#define LLL_MUTEX_LOCK_INITIALIZER (0)
53 +
54 +
55 +/* Type for lock object.  */
56 +typedef int lll_lock_t;
57 +
58 +
59 +#define lll_futex_wait(futexp, val) \
60 +  ({                                                                         \
61 +    INTERNAL_SYSCALL_DECL (__err);                                           \
62 +    long int __ret;                                                          \
63 +    __ret = INTERNAL_SYSCALL (futex, __err, 4,                               \
64 +                             (futexp), FUTEX_WAIT, (val), 0);                \
65 +    __ret;                                                                   \
66 +  })
67 +
68 +#define lll_futex_timed_wait(futexp, val, timespec) \
69 +  ({                                                                         \
70 +    INTERNAL_SYSCALL_DECL (__err);                                           \
71 +    long int __ret;                                                          \
72 +    __ret = INTERNAL_SYSCALL (futex, __err, 4,                               \
73 +                             (futexp), FUTEX_WAIT, (val), (timespec));       \
74 +    __ret;                                                                   \
75 +  })
76 +
77 +#define lll_futex_wake(futexp, nr) \
78 +  ({                                                                         \
79 +    INTERNAL_SYSCALL_DECL (__err);                                           \
80 +    long int __ret;                                                          \
81 +    __ret = INTERNAL_SYSCALL (futex, __err, 4,                               \
82 +                             (futexp), FUTEX_WAKE, (nr), 0);                 \
83 +    __ret;                                                                   \
84 +  })
85 +
86 +#define lll_robust_mutex_dead(futexv) \
87 +  do                                                                         \
88 +    {                                                                        \
89 +      int *__futexp = &(futexv);                                             \
90 +      atomic_or (__futexp, FUTEX_OWNER_DIED);                                \
91 +      lll_futex_wake (__futexp, 1);                                          \
92 +    }                                                                        \
93 +  while (0)
94 +
95 +/* Returns non-zero if error happened, zero if success.  */
96 +#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val) \
97 +  ({                                                                         \
98 +    INTERNAL_SYSCALL_DECL (__err);                                           \
99 +    long int __ret;                                                          \
100 +    __ret = INTERNAL_SYSCALL (futex, __err, 6,                               \
101 +                             (futexp), FUTEX_CMP_REQUEUE, (nr_wake),         \
102 +                             (nr_move), (mutex), (val));                     \
103 +    __ret;                                                                   \
104 +  })
105 +
106 +/* Returns non-zero if error happened, zero if success.  */
107 +#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2) \
108 +  ({                                                                         \
109 +    INTERNAL_SYSCALL_DECL (__err);                                           \
110 +    long int __ret;                                                          \
111 +    __ret = INTERNAL_SYSCALL (futex, __err, 6,                               \
112 +                             (futexp), FUTEX_WAKE_OP, (nr_wake),             \
113 +                             (nr_wake2), (futexp2),                          \
114 +                             FUTEX_OP_CLEAR_WAKE_IF_GT_ONE);                 \
115 +    __ret;                                                                   \
116 +  })
117 +
118 +static inline int __attribute__((always_inline))
119 +__lll_mutex_trylock(lll_lock_t *futex)
120 +{
121 +  return atomic_compare_and_exchange_val_acq (futex, 1, 0) != 0;
122 +}
123 +#define lll_mutex_trylock(lock)        __lll_mutex_trylock (&(lock))
124 +
125 +static inline int __attribute__((always_inline))
126 +__lll_robust_mutex_trylock(int *futex, int id)
127 +{
128 +  return atomic_compare_and_exchange_val_acq (futex, id, 0) != 0;
129 +}
130 +#define lll_robust_mutex_trylock(lock, id) \
131 +  __lll_robust_mutex_trylock (&(lock), id)
132 +
133 +
134 +static inline int __attribute__((always_inline))
135 +__lll_mutex_cond_trylock(lll_lock_t *futex)
136 +{
137 +  return atomic_compare_and_exchange_val_acq (futex, 2, 0) != 0;
138 +}
139 +#define lll_mutex_cond_trylock(lock)   __lll_mutex_cond_trylock (&(lock))
140 +
141 +
142 +extern void __lll_lock_wait (lll_lock_t *futex) attribute_hidden;
143 +
144 +static inline void __attribute__((always_inline))
145 +__lll_mutex_lock(lll_lock_t *futex)
146 +{
147 +  if (atomic_compare_and_exchange_bool_acq (futex, 1, 0) != 0)
148 +    __lll_lock_wait (futex);
149 +}
150 +#define lll_mutex_lock(futex) __lll_mutex_lock (&(futex))
151 +
152 +extern int __lll_robust_lock_wait (int *futex) attribute_hidden;
153 +
154 +static inline int __attribute__ ((always_inline))
155 +__lll_robust_mutex_lock (int *futex, int id)
156 +{
157 +  int result = 0;
158 +  if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0)
159 +    result = __lll_robust_lock_wait (futex);
160 +  return result;
161 +}
162 +#define lll_robust_mutex_lock(futex, id) \
163 +  __lll_robust_mutex_lock (&(futex), id)
164 +
165 +static inline void __attribute__ ((always_inline))
166 +__lll_mutex_cond_lock (lll_lock_t *futex)
167 +{
168 +  if (atomic_compare_and_exchange_bool_acq (futex, 2, 0) != 0)
169 +    __lll_lock_wait (futex);
170 +}
171 +#define lll_mutex_cond_lock(futex) __lll_mutex_cond_lock (&(futex))
172 +
173 +
174 +#define lll_robust_mutex_cond_lock(futex, id) \
175 +  __lll_robust_mutex_lock (&(futex), (id) | FUTEX_WAITERS)
176 +
177 +
178 +extern int __lll_timedlock_wait (lll_lock_t *futex, const struct timespec *)
179 +       attribute_hidden;
180 +extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *)
181 +       attribute_hidden;
182 +
183 +static inline int __attribute__ ((always_inline))
184 +__lll_mutex_timedlock (lll_lock_t *futex, const struct timespec *abstime)
185 +{
186 +  int result = 0;
187 +  if (atomic_compare_and_exchange_bool_acq (futex, 1, 0) != 0)
188 +    result = __lll_timedlock_wait (futex, abstime);
189 +  return result;
190 +}
191 +#define lll_mutex_timedlock(futex, abstime) \
192 +  __lll_mutex_timedlock (&(futex), abstime)
193 +
194 +static inline int __attribute__ ((always_inline))
195 +__lll_robust_mutex_timedlock (int *futex, const struct timespec *abstime,
196 +                             int id)
197 +{
198 +  int result = 0;
199 +  if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0)
200 +    result = __lll_robust_timedlock_wait (futex, abstime);
201 +  return result;
202 +}
203 +#define lll_robust_mutex_timedlock(futex, abstime, id) \
204 +  __lll_robust_mutex_timedlock (&(futex), abstime, id)
205 +
206 +
207 +static inline void __attribute__ ((always_inline))
208 +__lll_mutex_unlock (lll_lock_t *futex)
209 +{
210 +  int val = atomic_exchange_rel (futex, 0);
211 +  if (__builtin_expect (val > 1, 0))
212 +    lll_futex_wake (futex, 1);
213 +}
214 +#define lll_mutex_unlock(futex) __lll_mutex_unlock(&(futex))
215 +
216 +
217 +static inline void __attribute__ ((always_inline))
218 +__lll_robust_mutex_unlock (int *futex, int mask)
219 +{
220 +  int val = atomic_exchange_rel (futex, 0);
221 +  if (__builtin_expect (val & mask, 0))
222 +    lll_futex_wake (futex, 1);
223 +}
224 +#define lll_robust_mutex_unlock(futex) \
225 +  __lll_robust_mutex_unlock(&(futex), FUTEX_WAITERS)
226 +
227 +
228 +static inline void __attribute__ ((always_inline))
229 +__lll_mutex_unlock_force (lll_lock_t *futex)
230 +{
231 +  (void) atomic_exchange_rel (futex, 0);
232 +  lll_futex_wake (futex, 1);
233 +}
234 +#define lll_mutex_unlock_force(futex) __lll_mutex_unlock_force(&(futex))
235 +
236 +#define lll_mutex_islocked(futex) \
237 +  (futex != 0)
238 +
239 +/* Our internal lock implementation is identical to the binary-compatible
240 +   mutex implementation. */
241 +
242 +#define LLL_LOCK_INITIALIZER (0)
243 +#define LLL_LOCK_INITIALIZER_CONST (0)
244 +#define LLL_LOCK_INITIALIZER_LOCKED (1)
245 +
246 +
247 +#define THREAD_INIT_LOCK(PD, LOCK) \
248 +  (PD)->LOCK = LLL_LOCK_INITIALIZER
249 +
250 +extern int lll_unlock_wake_cb (lll_lock_t *__futex) attribute_hidden;
251 +
252 +/* The states of a lock are:
253 +    0  -  untaken
254 +    1  -  taken by one user
255 +   >1  -  taken by more users */
256 +
257 +#define lll_trylock(lock)      lll_mutex_trylock (lock)
258 +#define lll_lock(lock)         lll_mutex_lock (lock)
259 +#define lll_unlock(lock)       lll_mutex_unlock (lock)
260 +#define lll_islocked(lock)     lll_mutex_islocked (lock)
261 +
262 +/* The kernel notifies a process which uses CLONE_CLEARTID via futex
263 +   wakeup when the clone terminates.  The memory location contains the
264 +   thread ID while the clone is running and is reset to zero
265 +   afterwards. */
266 +#define lll_wait_tid(tid) \
267 +  do {                                 \
268 +    __typeof (tid) __tid;              \
269 +    while ((__tid = (tid)) != 0)       \
270 +      lll_futex_wait (&(tid), __tid);  \
271 +  } while (0)
272 +
273 +extern int __lll_timedwait_tid (int *, const struct timespec *)
274 +     attribute_hidden;
275 +
276 +#define lll_timedwait_tid(tid, abstime) \
277 +  ({                                                   \
278 +    int __res = 0;                                     \
279 +    if ((tid) != 0)                                    \
280 +      __res = __lll_timedwait_tid (&(tid), (abstime)); \
281 +    __res;                                             \
282 +  })
283 +
284 +
285 +/* Conditional variable handling.  */
286 +
287 +extern void __lll_cond_wait (pthread_cond_t *cond)
288 +     attribute_hidden;
289 +extern int __lll_cond_timedwait (pthread_cond_t *cond,
290 +                                const struct timespec *abstime)
291 +     attribute_hidden;
292 +extern void __lll_cond_wake (pthread_cond_t *cond)
293 +     attribute_hidden;
294 +extern void __lll_cond_broadcast (pthread_cond_t *cond)
295 +     attribute_hidden;
296 +
297 +#define lll_cond_wait(cond) \
298 +  __lll_cond_wait (cond)
299 +#define lll_cond_timedwait(cond, abstime) \
300 +  __lll_cond_timedwait (cond, abstime)
301 +#define lll_cond_wake(cond) \
302 +  __lll_cond_wake (cond)
303 +#define lll_cond_broadcast(cond) \
304 +  __lll_cond_broadcast (cond)
305 +
306 +#endif /* lowlevellock.h */
307 --- a/ports/sysdeps/unix/sysv/linux/hppa/linuxthreads/sysdep-cancel.h
308 +++ b/ports/sysdeps/unix/sysv/linux/hppa/linuxthreads/sysdep-cancel.h
309 @@ -240,3 +240,10 @@
310  
311  #endif
312  /* !defined NOT_IN_libc || defined IS_IN_libpthread */
313 +
314 +#ifndef __ASSEMBLER__
315 +# define RTLD_SINGLE_THREAD_P \
316 +  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
317 +                                  p_multiple_threads) == 0, 1)
318 +#endif
319 +