]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/netbsd-tests/lib/libpthread/t_mutex.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / netbsd-tests / lib / libpthread / t_mutex.c
1 /* $NetBSD: t_mutex.c,v 1.7 2014/11/04 00:20:19 justin Exp $ */
2
3 /*
4  * Copyright (c) 2008 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include <sys/cdefs.h>
30 __COPYRIGHT("@(#) Copyright (c) 2008\
31  The NetBSD Foundation, inc. All rights reserved.");
32 __RCSID("$NetBSD: t_mutex.c,v 1.7 2014/11/04 00:20:19 justin Exp $");
33
34 #include <pthread.h>
35 #include <stdio.h>
36 #include <string.h>
37 #include <unistd.h>
38
39 #include <atf-c.h>
40
41 #include "h_common.h"
42
43 static pthread_mutex_t mutex;
44 static pthread_mutex_t static_mutex = PTHREAD_MUTEX_INITIALIZER;
45 static int global_x;
46
47 static void *
48 mutex1_threadfunc(void *arg)
49 {
50         int *param;
51
52         printf("2: Second thread.\n");
53
54         param = arg;
55         printf("2: Locking mutex\n");
56         pthread_mutex_lock(&mutex);
57         printf("2: Got mutex. *param = %d\n", *param);
58         ATF_REQUIRE_EQ(*param, 20);
59         (*param)++;
60
61         pthread_mutex_unlock(&mutex);
62
63         return param;
64 }
65
66 ATF_TC(mutex1);
67 ATF_TC_HEAD(mutex1, tc)
68 {
69         atf_tc_set_md_var(tc, "descr", "Checks mutexes");
70 }
71 ATF_TC_BODY(mutex1, tc)
72 {
73         int x;
74         pthread_t new;
75         void *joinval;
76
77         printf("1: Mutex-test 1\n");
78
79         PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL));
80         x = 1;
81         PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
82         PTHREAD_REQUIRE(pthread_create(&new, NULL, mutex1_threadfunc, &x));
83         printf("1: Before changing the value.\n");
84         sleep(2);
85         x = 20;
86         printf("1: Before releasing the mutex.\n");
87         sleep(2);
88         PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
89         printf("1: After releasing the mutex.\n");
90         PTHREAD_REQUIRE(pthread_join(new, &joinval));
91
92         PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
93         printf("1: Thread joined. X was %d. Return value (int) was %d\n",
94                 x, *(int *)joinval);
95         ATF_REQUIRE_EQ(x, 21);
96         ATF_REQUIRE_EQ(*(int *)joinval, 21);
97         PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
98 }
99
100 static void *
101 mutex2_threadfunc(void *arg)
102 {
103         long count = *(int *)arg;
104
105         printf("2: Second thread (%p). Count is %ld\n", pthread_self(), count);
106
107         while (count--) {
108                 PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
109                 global_x++;
110                 PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
111         }
112
113         return (void *)count;
114 }
115
116 ATF_TC(mutex2);
117 ATF_TC_HEAD(mutex2, tc)
118 {
119         atf_tc_set_md_var(tc, "descr", "Checks mutexes");
120 #ifdef __NetBSD__
121 #if defined(__powerpc__)
122         atf_tc_set_md_var(tc, "timeout", "40");
123 #endif
124 #endif
125 }
126 ATF_TC_BODY(mutex2, tc)
127 {
128         int count, count2;
129         pthread_t new;
130         void *joinval;
131
132         printf("1: Mutex-test 2\n");
133
134 #ifdef __NetBSD__
135 #if defined(__powerpc__)
136         atf_tc_expect_timeout("PR port-powerpc/44387");
137 #endif
138 #endif
139
140         PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL));
141         
142         global_x = 0;
143         count = count2 = 10000000;
144
145         PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
146         PTHREAD_REQUIRE(pthread_create(&new, NULL, mutex2_threadfunc, &count2));
147
148         printf("1: Thread %p\n", pthread_self());
149
150         PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
151
152         while (count--) {
153                 PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
154                 global_x++;
155                 PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
156         }
157
158         PTHREAD_REQUIRE(pthread_join(new, &joinval));
159
160         PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
161         printf("1: Thread joined. X was %d. Return value (long) was %ld\n",
162                 global_x, (long)joinval);
163         ATF_REQUIRE_EQ(global_x, 20000000);
164
165 #ifdef __NetBSD__
166 #if defined(__powerpc__)
167         /* XXX force a timeout in ppc case since an un-triggered race
168            otherwise looks like a "failure" */
169         /* We sleep for longer than the timeout to make ATF not
170            complain about unexpected success */
171         sleep(41);
172 #endif
173 #endif
174 }
175
176 static void *
177 mutex3_threadfunc(void *arg)
178 {
179         long count = *(int *)arg;
180
181         printf("2: Second thread (%p). Count is %ld\n", pthread_self(), count);
182
183         while (count--) {
184                 PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex));
185                 global_x++;
186                 PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex));
187         }
188
189         return (void *)count;
190 }
191
192 ATF_TC(mutex3);
193 ATF_TC_HEAD(mutex3, tc)
194 {
195         atf_tc_set_md_var(tc, "descr", "Checks mutexes using a static "
196             "initializer");
197 #ifdef __NetBSD__
198 #if defined(__powerpc__)
199         atf_tc_set_md_var(tc, "timeout", "40");
200 #endif
201 #endif
202 }
203 ATF_TC_BODY(mutex3, tc)
204 {
205         int count, count2;
206         pthread_t new;
207         void *joinval;
208
209         printf("1: Mutex-test 3\n");
210
211 #ifdef __NetBSD__
212 #if defined(__powerpc__)
213         atf_tc_expect_timeout("PR port-powerpc/44387");
214 #endif
215 #endif
216
217         global_x = 0;
218         count = count2 = 10000000;
219
220         PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex));
221         PTHREAD_REQUIRE(pthread_create(&new, NULL, mutex3_threadfunc, &count2));
222
223         printf("1: Thread %p\n", pthread_self());
224
225         PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex));
226
227         while (count--) {
228                 PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex));
229                 global_x++;
230                 PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex));
231         }
232
233         PTHREAD_REQUIRE(pthread_join(new, &joinval));
234
235         PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex));
236         printf("1: Thread joined. X was %d. Return value (long) was %ld\n",
237                 global_x, (long)joinval);
238         ATF_REQUIRE_EQ(global_x, 20000000);
239
240 #ifdef __NetBSD__
241 #if defined(__powerpc__)
242         /* XXX force a timeout in ppc case since an un-triggered race
243            otherwise looks like a "failure" */
244         /* We sleep for longer than the timeout to make ATF not
245            complain about unexpected success */
246         sleep(41);
247 #endif
248 #endif
249 }
250
251 static void *
252 mutex4_threadfunc(void *arg)
253 {
254         int *param;
255
256         printf("2: Second thread.\n");
257
258         param = arg;
259         printf("2: Locking mutex\n");
260         PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
261         printf("2: Got mutex. *param = %d\n", *param);
262         (*param)++;
263
264         PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
265
266         return param;
267 }
268
269 ATF_TC(mutex4);
270 ATF_TC_HEAD(mutex4, tc)
271 {
272         atf_tc_set_md_var(tc, "descr", "Checks mutexes");
273 }
274 ATF_TC_BODY(mutex4, tc)
275 {
276         int x;
277         pthread_t new;
278         pthread_mutexattr_t mattr;
279         void *joinval;
280
281         printf("1: Mutex-test 4\n");
282
283         PTHREAD_REQUIRE(pthread_mutexattr_init(&mattr));
284         PTHREAD_REQUIRE(pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE));
285
286         PTHREAD_REQUIRE(pthread_mutex_init(&mutex, &mattr));
287
288         PTHREAD_REQUIRE(pthread_mutexattr_destroy(&mattr));
289
290         x = 1;
291         PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
292         PTHREAD_REQUIRE(pthread_create(&new, NULL, mutex4_threadfunc, &x));
293
294         printf("1: Before recursively acquiring the mutex.\n");
295         PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
296
297         printf("1: Before releasing the mutex once.\n");
298         sleep(2);
299         PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
300         printf("1: After releasing the mutex once.\n");
301
302         x = 20;
303
304         printf("1: Before releasing the mutex twice.\n");
305         sleep(2);
306         PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
307         printf("1: After releasing the mutex twice.\n");
308
309         PTHREAD_REQUIRE(pthread_join(new, &joinval));
310
311         PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
312         printf("1: Thread joined. X was %d. Return value (int) was %d\n",
313                 x, *(int *)joinval);
314         ATF_REQUIRE_EQ(x, 21);
315         ATF_REQUIRE_EQ(*(int *)joinval, 21);
316         PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
317 }
318
319 ATF_TP_ADD_TCS(tp)
320 {
321         ATF_TP_ADD_TC(tp, mutex1);
322         ATF_TP_ADD_TC(tp, mutex2);
323         ATF_TP_ADD_TC(tp, mutex3);
324         ATF_TP_ADD_TC(tp, mutex4);
325
326         return atf_no_error();
327 }