]>
Commit | Line | Data |
---|---|---|
0ecb606c | 1 | /* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc. |
a88c9263 UD |
2 | This file is part of the GNU C Library. |
3 | Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003. | |
4 | ||
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. | |
9 | ||
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. | |
14 | ||
15 | You should have received a copy of the GNU Lesser General Public | |
16 | License along with the GNU C Library; if not, write to the Free | |
17 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | |
18 | 02111-1307 USA. */ | |
19 | ||
20 | #include <endian.h> | |
21 | #include <errno.h> | |
22 | #include <sysdep.h> | |
23 | #include <lowlevellock.h> | |
24 | #include <pthread.h> | |
25 | #include <pthreadP.h> | |
26 | ||
27 | #include <shlib-compat.h> | |
69431c9a | 28 | #include <kernel-features.h> |
a88c9263 UD |
29 | |
30 | ||
31 | int | |
32 | __pthread_cond_broadcast (cond) | |
33 | pthread_cond_t *cond; | |
34 | { | |
35 | /* Make sure we are alone. */ | |
36 | lll_mutex_lock (cond->__data.__lock); | |
37 | ||
38 | /* Are there any waiters to be woken? */ | |
39 | if (cond->__data.__total_seq > cond->__data.__wakeup_seq) | |
40 | { | |
41 | /* Yes. Mark them all as woken. */ | |
42 | cond->__data.__wakeup_seq = cond->__data.__total_seq; | |
893a3511 | 43 | cond->__data.__woken_seq = cond->__data.__total_seq; |
75fccede UD |
44 | cond->__data.__futex = (unsigned int) cond->__data.__total_seq * 2; |
45 | int futex_val = cond->__data.__futex; | |
893a3511 UD |
46 | /* Signal that a broadcast happened. */ |
47 | ++cond->__data.__broadcast_seq; | |
a88c9263 | 48 | |
bbb9ba43 UD |
49 | /* We are done. */ |
50 | lll_mutex_unlock (cond->__data.__lock); | |
51 | ||
e42a990e UD |
52 | /* Do not use requeue for pshared condvars. */ |
53 | if (cond->__data.__mutex == (void *) ~0l) | |
54 | goto wake_all; | |
55 | ||
a88c9263 | 56 | /* Wake everybody. */ |
69431c9a | 57 | pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex; |
0ecb606c JJ |
58 | |
59 | /* XXX: Kernel so far doesn't support requeue to PI futex. */ | |
60 | if (__builtin_expect (mut->__data.__kind & PTHREAD_MUTEX_PRIO_INHERIT_NP, | |
61 | 0)) | |
62 | goto wake_all; | |
63 | ||
75fccede UD |
64 | /* lll_futex_requeue returns 0 for success and non-zero |
65 | for errors. */ | |
66 | if (__builtin_expect (lll_futex_requeue (&cond->__data.__futex, 1, | |
67 | INT_MAX, &mut->__data.__lock, | |
68 | futex_val), 0)) | |
69431c9a UD |
69 | { |
70 | /* The requeue functionality is not available. */ | |
e42a990e | 71 | wake_all: |
75fccede | 72 | lll_futex_wake (&cond->__data.__futex, INT_MAX); |
69431c9a | 73 | } |
bbb9ba43 UD |
74 | |
75 | /* That's all. */ | |
76 | return 0; | |
a88c9263 UD |
77 | } |
78 | ||
79 | /* We are done. */ | |
80 | lll_mutex_unlock (cond->__data.__lock); | |
81 | ||
82 | return 0; | |
83 | } | |
84 | ||
85 | versioned_symbol (libpthread, __pthread_cond_broadcast, pthread_cond_broadcast, | |
86 | GLIBC_2_3_2); |