• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (c) 2005, Bull S.A..  All rights reserved.
3 * Created by: Sebastien Decugis
4 
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 
17 * This stress test aims to test the following assertion:
18 *  sem_getvalue always returns the value of the semaphore at a given time
19 * during the call into the sval argument.
20 
21 * The steps are:
22 * -> Create a named semaphore and an unnamed semaphore, initialized to 0.
23 * -> create two threads which continuously post and wait these semaphores.
24 * -> main loops on sem_getvalue on these two semaphores.
25 
26 * The test fails if sem_getvalue gets a value different from 0 or 1.
27 
28 */
29 
30 #include <pthread.h>
31 #include <stdarg.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <unistd.h>
36 
37 #include <semaphore.h>
38 #include <fcntl.h>
39 #include <errno.h>
40 #include <signal.h>
41 
42 #include "testfrmw.h"
43 #include "testfrmw.c"
44 /* This header is responsible for defining the following macros:
45  * UNRESOLVED(ret, descr);
46  *    where descr is a description of the error and ret is an int (error code for example)
47  * FAILED(descr);
48  *    where descr is a short text saying why the test has failed.
49  * PASSED();
50  *    No parameter.
51  *
52  * Both three macros shall terminate the calling process.
53  * The testcase shall not terminate in any other maneer.
54  *
55  * The other file defines the functions
56  * void output_init()
57  * void output(char * string, ...)
58  *
59  * Those may be used to output information.
60  */
61 
62 #ifndef VERBOSE
63 #define VERBOSE 1
64 #endif
65 
66 #define SEM_NAME "/set_getval_stress"
67 
68 #define INIT_VAL 0
69 
70 char do_it = 1;
71 long long iterations = 0;
72 
73 /* Handler for user request to terminate */
sighdl(int sig)74 void sighdl(int sig)
75 {
76 	/* do_it = 0 */
77 
78 	do {
79 		do_it = 0;
80 	} while (do_it);
81 }
82 
83 /* Thread function */
threaded(void * arg)84 void *threaded(void *arg)
85 {
86 	int ret = 0;
87 
88 	do {
89 		/* sem_post */
90 		ret = sem_post(arg);
91 
92 		if (ret != 0) {
93 			UNRESOLVED(errno, "Failed to post the semaphore");
94 		}
95 
96 		/* sem wait */
97 		do {
98 			ret = sem_wait(arg);
99 		} while ((ret != 0) && (errno == EINTR));
100 
101 		if (ret != 0) {
102 			UNRESOLVED(errno, "Failed to wait for the semaphore");
103 		}
104 
105 	} while (do_it);
106 
107 	return NULL;
108 }
109 
110 /* Main function */
main(int argc,char * argv[])111 int main(int argc, char *argv[])
112 {
113 	int ret = 0, value;
114 
115 	struct sigaction sa;
116 
117 	pthread_t child1, child2;
118 
119 	sem_t unnamed, *named;
120 
121 	/* Initialize output routine */
122 	output_init();
123 
124 	/* Register the signal handler for SIGUSR1 */
125 	sigemptyset(&sa.sa_mask);
126 
127 	sa.sa_flags = 0;
128 
129 	sa.sa_handler = sighdl;
130 
131 	if ((ret = sigaction(SIGUSR1, &sa, NULL))) {
132 		UNRESOLVED(ret, "Unable to register signal handler");
133 	}
134 
135 	if ((ret = sigaction(SIGALRM, &sa, NULL))) {
136 		UNRESOLVED(ret, "Unable to register signal handler");
137 	}
138 #if VERBOSE > 1
139 	output("[parent] Signal handler registered\n");
140 
141 #endif
142 
143 	/* Initialize the semaphores */
144 	named = sem_open(SEM_NAME, O_CREAT, 0777, INIT_VAL);
145 
146 	if (named == SEM_FAILED) {
147 		UNRESOLVED(errno, "Failed to sem_open");
148 	}
149 
150 	ret = sem_unlink(SEM_NAME);
151 
152 	if (ret != 0) {
153 		UNRESOLVED(errno, "Failed to sem_unlink");
154 	}
155 
156 	ret = sem_init(&unnamed, 0, INIT_VAL);
157 
158 	if (ret != 0) {
159 		UNRESOLVED(errno, "Failed to sem_init");
160 	}
161 
162 	/* Create the threads */
163 	ret = pthread_create(&child1, NULL, threaded, named);
164 
165 	if (ret != 0) {
166 		UNRESOLVED(ret, "Failed to create a thread");
167 	}
168 
169 	ret = pthread_create(&child2, NULL, threaded, &unnamed);
170 
171 	if (ret != 0) {
172 		UNRESOLVED(ret, "Failed to create a thread");
173 	}
174 
175 	/* loop */
176 	while (do_it) {
177 		ret = sem_getvalue(named, &value);
178 
179 		if (ret != 0) {
180 			UNRESOLVED(errno, "Failed to get sem value");
181 		}
182 
183 		if ((value != INIT_VAL) && (value != INIT_VAL + 1)) {
184 			output("Got value %d, expected %d or %d only\n",
185 			       value, INIT_VAL, INIT_VAL + 1);
186 			FAILED
187 			    ("sem_getvalue returned an invalid value for the named semaphore");
188 		}
189 
190 		ret = sem_getvalue(&unnamed, &value);
191 
192 		if (ret != 0) {
193 			UNRESOLVED(errno, "Failed to get sem value");
194 		}
195 
196 		if ((value != INIT_VAL) && (value != INIT_VAL + 1)) {
197 			output("Got value %d, expected %d or %d only\n",
198 			       value, INIT_VAL, INIT_VAL + 1);
199 			FAILED
200 			    ("sem_getvalue returned an invalid value for the unnamed semaphore");
201 		}
202 
203 		iterations++;
204 	}
205 
206 	/* Join the threads */
207 	ret = pthread_join(child1, NULL);
208 
209 	if (ret != 0) {
210 		UNRESOLVED(ret, "Failed to join a thread");
211 	}
212 
213 	ret = pthread_join(child2, NULL);
214 
215 	if (ret != 0) {
216 		UNRESOLVED(ret, "Failed to join a thread");
217 	}
218 
219 	/* Destroy the semaphores */
220 	ret = sem_close(named);
221 
222 	if (ret != 0) {
223 		UNRESOLVED(errno, "Failed to close the semaphore");
224 	}
225 
226 	ret = sem_destroy(&unnamed);
227 
228 	if (ret != 0) {
229 		UNRESOLVED(errno, "Failed to destroy the semaphore");
230 	}
231 
232 	/* Passed */
233 	output("pthread_exit stress test PASSED -- %llu iterations\n",
234 	       iterations);
235 
236 	PASSED;
237 }
238