xref: /openbsd-src/regress/lib/libpthread/pthread_mutex/pthread_mutex.c (revision 3a3fbb3f2e2521ab7c4a56b7ff7462ebd9095ec5)
1 /*	$OpenBSD: pthread_mutex.c,v 1.3 2001/11/03 04:33:48 marc Exp $	*/
2 /*
3  * Copyright (c) 1993, 1994, 1995, 1996 by Chris Provenzano and contributors,
4  * proven@mit.edu All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. All advertising materials mentioning features or use of this software
15  *    must display the following acknowledgement:
16  *	This product includes software developed by Chris Provenzano,
17  *	the University of California, Berkeley, and contributors.
18  * 4. Neither the name of Chris Provenzano, the University, nor the names of
19  *   contributors may be used to endorse or promote products derived
20  *   from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL CHRIS PROVENZANO, THE REGENTS OR
26  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
29  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
31  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
32  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 /* ==== test_pthread_cond.c =========================================
36  * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
37  *
38  * Description : Test pthread_mutex(). Run this after test_create()
39  *
40  *  1.23 94/05/04 proven
41  *      -Started coding this file.
42  */
43 
44 #include <pthread.h>
45 #include <pthread_np.h>
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include "test.h"
49 
50 int contention_variable;
51 
52 void *
53 thread_contention(arg)
54 	void *arg;
55 {
56 	pthread_mutex_t *mutex = arg;
57 
58 	SET_NAME("cntntn");
59 
60 	CHECKr(pthread_mutex_lock(mutex));
61 	ASSERT(contention_variable == 1);
62 	contention_variable = 2;
63 	CHECKr(pthread_mutex_unlock(mutex));
64 	pthread_exit(NULL);
65 }
66 
67 void
68 test_contention_lock(mutex)
69 	pthread_mutex_t *mutex;
70 {
71 	pthread_t thread;
72 
73 	printf("  test_contention_lock()\n");
74 	CHECKr(pthread_mutex_lock(mutex));
75 	contention_variable = 0;
76 	CHECKr(pthread_create(&thread, NULL, thread_contention, mutex));
77 	pthread_yield();
78 	contention_variable = 1;
79 	CHECKr(pthread_mutex_unlock(mutex));
80 	CHECKr(pthread_mutex_lock(mutex));
81 	ASSERT(contention_variable == 2);
82 	CHECKr(pthread_mutex_unlock(mutex));
83 }
84 
85 void
86 test_nocontention_lock(mutex)
87 	pthread_mutex_t *mutex;
88 {
89 	printf("  test_nocontention_lock()\n");
90 	CHECKr(pthread_mutex_lock(mutex));
91 	CHECKr(pthread_mutex_unlock(mutex));
92 }
93 
94 void
95 test_debug_double_lock(mutex)
96 	pthread_mutex_t *mutex;
97 {
98 	printf("  test_debug_double_lock()\n");
99 	CHECKr(pthread_mutex_lock(mutex));
100 	ASSERTe(pthread_mutex_lock(mutex), == EDEADLK);
101 	CHECKr(pthread_mutex_unlock(mutex));
102 }
103 
104 void
105 test_debug_double_unlock(mutex)
106 	pthread_mutex_t *mutex;
107 {
108 	printf("  test_debug_double_unlock()\n");
109 	CHECKr(pthread_mutex_lock(mutex));
110 	CHECKr(pthread_mutex_unlock(mutex));
111 	/* Posix D10 says undefined behaviour? */
112 	ASSERTe(pthread_mutex_unlock(mutex), != 0);
113 }
114 
115 void
116 test_nocontention_trylock(mutex)
117 	pthread_mutex_t *mutex;
118 {
119 	printf("  test_nocontention_trylock()\n");
120 	CHECKr(pthread_mutex_trylock(mutex));
121 	CHECKr(pthread_mutex_unlock(mutex));
122 }
123 
124 void
125 test_mutex_static()
126 {
127 	pthread_mutex_t mutex_static = PTHREAD_MUTEX_INITIALIZER;
128 
129 	printf("test_mutex_static()\n");
130 	test_nocontention_lock(&mutex_static);
131 	test_contention_lock(&mutex_static);
132 }
133 
134 void
135 test_mutex_fast(void)
136 {
137 	pthread_mutex_t mutex_fast;
138 
139 	printf("test_mutex_fast()\n");
140 	CHECKr(pthread_mutex_init(&mutex_fast, NULL));
141 	test_nocontention_lock(&mutex_fast);
142 	test_contention_lock(&mutex_fast);
143 	CHECKr(pthread_mutex_destroy(&mutex_fast));
144 }
145 
146 void
147 test_mutex_debug()
148 {
149 	pthread_mutexattr_t mutex_debug_attr;
150 	pthread_mutex_t mutex_debug;
151 
152 	printf("test_mutex_debug()\n");
153 	CHECKr(pthread_mutexattr_init(&mutex_debug_attr));
154 	CHECKr(pthread_mutexattr_settype(&mutex_debug_attr,
155 	    PTHREAD_MUTEX_ERRORCHECK));
156 	CHECKr(pthread_mutex_init(&mutex_debug, &mutex_debug_attr));
157 	test_nocontention_lock(&mutex_debug);
158 	test_contention_lock(&mutex_debug);
159 	test_debug_double_lock(&mutex_debug);
160 	test_debug_double_unlock(&mutex_debug);
161 	CHECKr(pthread_mutex_destroy(&mutex_debug));
162 }
163 
164 void
165 test_mutex_recursive()
166 {
167 	pthread_mutexattr_t mutex_recursive_attr;
168 	pthread_mutex_t mutex_recursive;
169 	int i;
170 	int j = 9;
171 
172 	printf("test_mutex_recursive()\n");
173 	CHECKr(pthread_mutexattr_init(&mutex_recursive_attr));
174 	CHECKr(pthread_mutexattr_settype(&mutex_recursive_attr,
175 	    PTHREAD_MUTEX_RECURSIVE));
176 	CHECKr(pthread_mutex_init(&mutex_recursive, &mutex_recursive_attr));
177 
178 	CHECKr(pthread_mutex_lock(&mutex_recursive));
179 	for (i = 0; i < j; i++)
180 		CHECKr(pthread_mutex_lock(&mutex_recursive));
181 	for (i = 0; i < j; i++)
182 		CHECKr(pthread_mutex_unlock(&mutex_recursive));
183 	CHECKr(pthread_mutex_unlock(&mutex_recursive));
184 	/* Posix D10 says undefined behaviour? */
185 	ASSERTe(pthread_mutex_unlock(&mutex_recursive), != 0);
186 	CHECKr(pthread_mutex_destroy(&mutex_recursive));
187 }
188 
189 int
190 main()
191 {
192 	test_mutex_static();
193 	test_mutex_fast();
194 	test_mutex_debug();
195 	test_mutex_recursive();
196 	SUCCEED;
197 }
198