Copy-edit NEWS and fixup ChangeLog entries.
[glibc.git] / nptl / tst-cond24.c
blobd58ab52f5a0f41658159db90676f88c6bfc465cf
1 /* Verify that condition variables synchronized by PI mutexes don't hang.
2 Copyright (C) 2012-2013 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 #include <pthread.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <errno.h>
24 #include <sys/types.h>
25 #include <sys/syscall.h>
26 #include <unistd.h>
27 #include <sys/time.h>
28 #include <time.h>
30 #define THREADS_NUM 5
31 #define MAXITER 50000
33 static pthread_mutex_t mutex;
34 static pthread_mutexattr_t mutex_attr;
35 static pthread_cond_t cond;
36 static pthread_t threads[THREADS_NUM];
37 static int pending = 0;
39 typedef void * (*threadfunc) (void *);
41 void *
42 thread_fun_timed (void *arg)
44 int *ret = arg;
45 int rv, i;
47 printf ("Started thread_fun_timed[%d]\n", *ret);
49 for (i = 0; i < MAXITER / THREADS_NUM; i++)
51 rv = pthread_mutex_lock (&mutex);
52 if (rv)
54 printf ("pthread_mutex_lock: %s(%d)\n", strerror (rv), rv);
55 *ret = 1;
56 goto out;
59 while (!pending)
61 struct timespec ts;
62 clock_gettime(CLOCK_REALTIME, &ts);
63 ts.tv_sec += 20;
64 rv = pthread_cond_timedwait (&cond, &mutex, &ts);
66 /* There should be no timeout either. */
67 if (rv)
69 printf ("pthread_cond_wait: %s(%d)\n", strerror (rv), rv);
70 *ret = 1;
71 goto out;
75 pending--;
77 rv = pthread_mutex_unlock (&mutex);
78 if (rv)
80 printf ("pthread_mutex_unlock: %s(%d)\n", strerror (rv), rv);
81 *ret = 1;
82 goto out;
86 *ret = 0;
88 out:
89 return ret;
92 void *
93 thread_fun (void *arg)
95 int *ret = arg;
96 int rv, i;
98 printf ("Started thread_fun[%d]\n", *ret);
100 for (i = 0; i < MAXITER / THREADS_NUM; i++)
102 rv = pthread_mutex_lock (&mutex);
103 if (rv)
105 printf ("pthread_mutex_lock: %s(%d)\n", strerror (rv), rv);
106 *ret = 1;
107 goto out;
110 while (!pending)
112 rv = pthread_cond_wait (&cond, &mutex);
114 if (rv)
116 printf ("pthread_cond_wait: %s(%d)\n", strerror (rv), rv);
117 *ret = 1;
118 goto out;
122 pending--;
124 rv = pthread_mutex_unlock (&mutex);
125 if (rv)
127 printf ("pthread_mutex_unlock: %s(%d)\n", strerror (rv), rv);
128 *ret = 1;
129 goto out;
133 *ret = 0;
135 out:
136 return ret;
139 static int
140 do_test_wait (threadfunc f)
142 int i;
143 int rv;
144 int counter = 0;
145 int retval[THREADS_NUM];
147 puts ("Starting test");
149 rv = pthread_mutexattr_init (&mutex_attr);
150 if (rv)
152 printf ("pthread_mutexattr_init: %s(%d)\n", strerror (rv), rv);
153 return 1;
156 rv = pthread_mutexattr_setprotocol (&mutex_attr, PTHREAD_PRIO_INHERIT);
157 if (rv)
159 printf ("pthread_mutexattr_setprotocol: %s(%d)\n", strerror (rv), rv);
160 return 1;
163 rv = pthread_mutex_init (&mutex, &mutex_attr);
164 if (rv)
166 printf ("pthread_mutex_init: %s(%d)\n", strerror (rv), rv);
167 return 1;
170 rv = pthread_cond_init (&cond, NULL);
171 if (rv)
173 printf ("pthread_cond_init: %s(%d)\n", strerror (rv), rv);
174 return 1;
177 for (i = 0; i < THREADS_NUM; i++)
179 retval[i] = i;
180 rv = pthread_create (&threads[i], NULL, f, &retval[i]);
181 if (rv)
183 printf ("pthread_create: %s(%d)\n", strerror (rv), rv);
184 return 1;
188 for (; counter < MAXITER; counter++)
190 rv = pthread_mutex_lock (&mutex);
191 if (rv)
193 printf ("pthread_mutex_lock: %s(%d)\n", strerror (rv), rv);
194 return 1;
197 if (!(counter % 100))
198 printf ("counter: %d\n", counter);
199 pending += 1;
201 rv = pthread_cond_signal (&cond);
202 if (rv)
204 printf ("pthread_cond_signal: %s(%d)\n", strerror (rv), rv);
205 return 1;
208 rv = pthread_mutex_unlock (&mutex);
209 if (rv)
211 printf ("pthread_mutex_unlock: %s(%d)\n", strerror (rv), rv);
212 return 1;
216 for (i = 0; i < THREADS_NUM; i++)
218 void *ret;
219 rv = pthread_join (threads[i], &ret);
220 if (rv)
222 printf ("pthread_join: %s(%d)\n", strerror (rv), rv);
223 return 1;
225 if (ret && *(int *)ret)
227 printf ("Thread %d returned with an error\n", i);
228 return 1;
232 return 0;
235 static int
236 do_test (void)
238 puts ("Testing pthread_cond_wait");
239 int ret = do_test_wait (thread_fun);
240 if (ret)
241 return ret;
243 puts ("Testing pthread_cond_timedwait");
244 return do_test_wait (thread_fun_timed);
247 #define TIMEOUT 20
248 #define TEST_FUNCTION do_test ()
249 #include "../test-skeleton.c"