xref: /aosp_15_r20/external/ltp/testcases/misc/math/float/main.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker /*
2*49cdfc7eSAndroid Build Coastguard Worker 	* Copyright (C) Bull S.A. 2001
3*49cdfc7eSAndroid Build Coastguard Worker 	* Copyright (c) International Business Machines  Corp., 2001
4*49cdfc7eSAndroid Build Coastguard Worker 	*
5*49cdfc7eSAndroid Build Coastguard Worker 	*   This program is free software;  you can redistribute it and/or modify
6*49cdfc7eSAndroid Build Coastguard Worker 	*   it under the terms of the GNU General Public License as published by
7*49cdfc7eSAndroid Build Coastguard Worker 	*   the Free Software Foundation; either version 2 of the License, or
8*49cdfc7eSAndroid Build Coastguard Worker 	*   (at your option) any later version.
9*49cdfc7eSAndroid Build Coastguard Worker 	*
10*49cdfc7eSAndroid Build Coastguard Worker 	*   This program is distributed in the hope that it will be useful,
11*49cdfc7eSAndroid Build Coastguard Worker 	*   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12*49cdfc7eSAndroid Build Coastguard Worker 	*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13*49cdfc7eSAndroid Build Coastguard Worker 	*   the GNU General Public License for more details.
14*49cdfc7eSAndroid Build Coastguard Worker 	*
15*49cdfc7eSAndroid Build Coastguard Worker 	*   You should have received a copy of the GNU General Public License
16*49cdfc7eSAndroid Build Coastguard Worker 	*   along with this program;  if not, write to the Free Software
17*49cdfc7eSAndroid Build Coastguard Worker 	*   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18*49cdfc7eSAndroid Build Coastguard Worker 	*/
19*49cdfc7eSAndroid Build Coastguard Worker 
20*49cdfc7eSAndroid Build Coastguard Worker /******************************************************************************/
21*49cdfc7eSAndroid Build Coastguard Worker /*									    */
22*49cdfc7eSAndroid Build Coastguard Worker /* Dec-03-2001  Created: Jacky Malcles & Jean Noel Cordenner		  */
23*49cdfc7eSAndroid Build Coastguard Worker /*	      These tests are adapted from AIX float PVT tests.	     */
24*49cdfc7eSAndroid Build Coastguard Worker /*									    */
25*49cdfc7eSAndroid Build Coastguard Worker /******************************************************************************/
26*49cdfc7eSAndroid Build Coastguard Worker #include "tfloat.h"
27*49cdfc7eSAndroid Build Coastguard Worker 
28*49cdfc7eSAndroid Build Coastguard Worker #include "test.h"
29*49cdfc7eSAndroid Build Coastguard Worker 
30*49cdfc7eSAndroid Build Coastguard Worker #define SAFE_FREE(p) { if (p) { free(p); (p)=NULL; } }
31*49cdfc7eSAndroid Build Coastguard Worker /* LTP status reporting */
32*49cdfc7eSAndroid Build Coastguard Worker char *TCID;			/* Test program identifier.    */
33*49cdfc7eSAndroid Build Coastguard Worker int TST_TOTAL = 1;		/* Total number of test cases. */
34*49cdfc7eSAndroid Build Coastguard Worker 
35*49cdfc7eSAndroid Build Coastguard Worker /* To avoid extensive modifications to the code, use this bodge */
36*49cdfc7eSAndroid Build Coastguard Worker #define exit(x) myexit(x)
37*49cdfc7eSAndroid Build Coastguard Worker 
myexit(int x)38*49cdfc7eSAndroid Build Coastguard Worker void myexit(int x)
39*49cdfc7eSAndroid Build Coastguard Worker {
40*49cdfc7eSAndroid Build Coastguard Worker 	if (x)
41*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TFAIL, "Test failed");
42*49cdfc7eSAndroid Build Coastguard Worker 	else
43*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TPASS, "Test passed");
44*49cdfc7eSAndroid Build Coastguard Worker 	tst_exit();
45*49cdfc7eSAndroid Build Coastguard Worker }
46*49cdfc7eSAndroid Build Coastguard Worker 
47*49cdfc7eSAndroid Build Coastguard Worker TH_DATA *pcom;
48*49cdfc7eSAndroid Build Coastguard Worker TH_DATA **tabcom;
49*49cdfc7eSAndroid Build Coastguard Worker TH_DATA **tabcour;
50*49cdfc7eSAndroid Build Coastguard Worker #ifndef	PATH_MAX
51*49cdfc7eSAndroid Build Coastguard Worker #define PATH_MAX		1024
52*49cdfc7eSAndroid Build Coastguard Worker #endif
53*49cdfc7eSAndroid Build Coastguard Worker char datadir[PATH_MAX];		/* DATA directory */
54*49cdfc7eSAndroid Build Coastguard Worker 
55*49cdfc7eSAndroid Build Coastguard Worker #ifndef PTHREAD_THREADS_MAX
56*49cdfc7eSAndroid Build Coastguard Worker #define PTHREAD_THREADS_MAX	1024
57*49cdfc7eSAndroid Build Coastguard Worker #endif
58*49cdfc7eSAndroid Build Coastguard Worker #define DEFAULT_NUM_THREADS	20
59*49cdfc7eSAndroid Build Coastguard Worker int num_threads = DEFAULT_NUM_THREADS;
60*49cdfc7eSAndroid Build Coastguard Worker int num_loops = 500;
61*49cdfc7eSAndroid Build Coastguard Worker 
62*49cdfc7eSAndroid Build Coastguard Worker int sig_cancel = 0;		/* flag set by handle_signals to tell initial thread
63*49cdfc7eSAndroid Build Coastguard Worker 				   to stop creating new threads (signal caught) */
64*49cdfc7eSAndroid Build Coastguard Worker 
65*49cdfc7eSAndroid Build Coastguard Worker int indice = 0;			/* # of threads created, to be canceled by handle_signals
66*49cdfc7eSAndroid Build Coastguard Worker 				   or waited for by initial thread */
67*49cdfc7eSAndroid Build Coastguard Worker 
68*49cdfc7eSAndroid Build Coastguard Worker pthread_mutex_t sig_mutex;
69*49cdfc7eSAndroid Build Coastguard Worker pthread_t *threads;
70*49cdfc7eSAndroid Build Coastguard Worker 
71*49cdfc7eSAndroid Build Coastguard Worker int debug = 0;
72*49cdfc7eSAndroid Build Coastguard Worker int true = 1;
73*49cdfc7eSAndroid Build Coastguard Worker 
74*49cdfc7eSAndroid Build Coastguard Worker static void *handle_signals(void *);
75*49cdfc7eSAndroid Build Coastguard Worker 
76*49cdfc7eSAndroid Build Coastguard Worker static void sys_error(const char *, int);
77*49cdfc7eSAndroid Build Coastguard Worker 
78*49cdfc7eSAndroid Build Coastguard Worker const double EPS = 0.1e-300;
79*49cdfc7eSAndroid Build Coastguard Worker 
80*49cdfc7eSAndroid Build Coastguard Worker const int nb_func = NB_FUNC;
81*49cdfc7eSAndroid Build Coastguard Worker 
generate(char * datadir,char * bin_path)82*49cdfc7eSAndroid Build Coastguard Worker int generate(char *datadir, char *bin_path)
83*49cdfc7eSAndroid Build Coastguard Worker {
84*49cdfc7eSAndroid Build Coastguard Worker 	char *cmdline;
85*49cdfc7eSAndroid Build Coastguard Worker 	char *fmt = "cd %s; %s/%s %s";
86*49cdfc7eSAndroid Build Coastguard Worker 
87*49cdfc7eSAndroid Build Coastguard Worker 	cmdline = malloc(2 * strlen(bin_path) + strlen(datadir) + strlen(GENERATOR) + strlen(fmt));
88*49cdfc7eSAndroid Build Coastguard Worker 	if (cmdline == NULL)
89*49cdfc7eSAndroid Build Coastguard Worker 		return (1);
90*49cdfc7eSAndroid Build Coastguard Worker 	sprintf(cmdline, fmt, datadir, bin_path, GENERATOR, bin_path);
91*49cdfc7eSAndroid Build Coastguard Worker 	system(cmdline);
92*49cdfc7eSAndroid Build Coastguard Worker 	free(cmdline);
93*49cdfc7eSAndroid Build Coastguard Worker 	return (0);
94*49cdfc7eSAndroid Build Coastguard Worker }
95*49cdfc7eSAndroid Build Coastguard Worker 
cleanup(void)96*49cdfc7eSAndroid Build Coastguard Worker static void cleanup(void)
97*49cdfc7eSAndroid Build Coastguard Worker {
98*49cdfc7eSAndroid Build Coastguard Worker 	tst_rmdir();
99*49cdfc7eSAndroid Build Coastguard Worker }
100*49cdfc7eSAndroid Build Coastguard Worker 
main(int argc,char * argv[])101*49cdfc7eSAndroid Build Coastguard Worker int main(int argc, char *argv[])
102*49cdfc7eSAndroid Build Coastguard Worker {
103*49cdfc7eSAndroid Build Coastguard Worker 	int opt = 0;
104*49cdfc7eSAndroid Build Coastguard Worker 	pid_t pid;
105*49cdfc7eSAndroid Build Coastguard Worker 
106*49cdfc7eSAndroid Build Coastguard Worker 	char *bin_path, *ltproot;
107*49cdfc7eSAndroid Build Coastguard Worker 	void *exit_value;
108*49cdfc7eSAndroid Build Coastguard Worker 	pthread_attr_t newattr;
109*49cdfc7eSAndroid Build Coastguard Worker 	pthread_t sig_hand;
110*49cdfc7eSAndroid Build Coastguard Worker 	size_t stacksize = 2093056;
111*49cdfc7eSAndroid Build Coastguard Worker 	int th_num;
112*49cdfc7eSAndroid Build Coastguard Worker 	int retvalend = 0;
113*49cdfc7eSAndroid Build Coastguard Worker 	int retval = 0;
114*49cdfc7eSAndroid Build Coastguard Worker 	int error = 0;
115*49cdfc7eSAndroid Build Coastguard Worker 	/*int time=1; */
116*49cdfc7eSAndroid Build Coastguard Worker 	int i;
117*49cdfc7eSAndroid Build Coastguard Worker 
118*49cdfc7eSAndroid Build Coastguard Worker 	/* Generate test ID from invocation name */
119*49cdfc7eSAndroid Build Coastguard Worker 	if ((TCID = strrchr(argv[0], '/')) != NULL)
120*49cdfc7eSAndroid Build Coastguard Worker 		TCID++;
121*49cdfc7eSAndroid Build Coastguard Worker 	else
122*49cdfc7eSAndroid Build Coastguard Worker 		TCID = argv[0];
123*49cdfc7eSAndroid Build Coastguard Worker 	ltproot = getenv("LTPROOT");
124*49cdfc7eSAndroid Build Coastguard Worker 	if (ltproot == NULL || strlen(ltproot) == 0) {
125*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, NULL,
126*49cdfc7eSAndroid Build Coastguard Worker 			 "You must set $LTPROOT before executing this test");
127*49cdfc7eSAndroid Build Coastguard Worker 	}
128*49cdfc7eSAndroid Build Coastguard Worker 	bin_path = malloc(strlen(ltproot) + 16);
129*49cdfc7eSAndroid Build Coastguard Worker 	if (bin_path == NULL) {
130*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK | TERRNO, NULL, "malloc failed");
131*49cdfc7eSAndroid Build Coastguard Worker 	}
132*49cdfc7eSAndroid Build Coastguard Worker 	sprintf(bin_path, "%s/testcases/bin", ltproot);
133*49cdfc7eSAndroid Build Coastguard Worker 
134*49cdfc7eSAndroid Build Coastguard Worker 	tst_tmpdir();
135*49cdfc7eSAndroid Build Coastguard Worker 
136*49cdfc7eSAndroid Build Coastguard Worker 	setbuf(stdout, NULL);
137*49cdfc7eSAndroid Build Coastguard Worker 	setbuf(stderr, NULL);
138*49cdfc7eSAndroid Build Coastguard Worker 	datadir[0] = '.';
139*49cdfc7eSAndroid Build Coastguard Worker 	datadir[1] = '\0';
140*49cdfc7eSAndroid Build Coastguard Worker 
141*49cdfc7eSAndroid Build Coastguard Worker 	if (argc != 1) {
142*49cdfc7eSAndroid Build Coastguard Worker 		while ((opt = getopt(argc, argv, "vn:l:D:?")) != EOF) {
143*49cdfc7eSAndroid Build Coastguard Worker 			switch (opt) {
144*49cdfc7eSAndroid Build Coastguard Worker 			case 'D':
145*49cdfc7eSAndroid Build Coastguard Worker 				strncpy(datadir, optarg, PATH_MAX);
146*49cdfc7eSAndroid Build Coastguard Worker 				break;
147*49cdfc7eSAndroid Build Coastguard Worker 			case 'l':
148*49cdfc7eSAndroid Build Coastguard Worker 				num_loops = atoi(optarg);
149*49cdfc7eSAndroid Build Coastguard Worker 				break;
150*49cdfc7eSAndroid Build Coastguard Worker 			case 'n':
151*49cdfc7eSAndroid Build Coastguard Worker 				num_threads = atoi(optarg);
152*49cdfc7eSAndroid Build Coastguard Worker 				break;
153*49cdfc7eSAndroid Build Coastguard Worker 			case 'v':
154*49cdfc7eSAndroid Build Coastguard Worker 				++debug;	/* verbose mode */
155*49cdfc7eSAndroid Build Coastguard Worker 				break;
156*49cdfc7eSAndroid Build Coastguard Worker 			default:
157*49cdfc7eSAndroid Build Coastguard Worker 				fprintf(stderr,
158*49cdfc7eSAndroid Build Coastguard Worker 					"usage: %s [-n number_of_threads] [-v]\n",
159*49cdfc7eSAndroid Build Coastguard Worker 					argv[0]);
160*49cdfc7eSAndroid Build Coastguard Worker 				fprintf(stderr, "[-l number_of_loops] ");
161*49cdfc7eSAndroid Build Coastguard Worker 				fprintf(stderr, "[-D DATAs absolute path]\n");
162*49cdfc7eSAndroid Build Coastguard Worker 				exit(1);
163*49cdfc7eSAndroid Build Coastguard Worker 			}
164*49cdfc7eSAndroid Build Coastguard Worker 		}
165*49cdfc7eSAndroid Build Coastguard Worker 	}
166*49cdfc7eSAndroid Build Coastguard Worker 	switch (pid = fork()) {
167*49cdfc7eSAndroid Build Coastguard Worker 	case -1:
168*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK | TERRNO, cleanup, "fork failed");
169*49cdfc7eSAndroid Build Coastguard Worker 	case 0:
170*49cdfc7eSAndroid Build Coastguard Worker 		generate(datadir, bin_path);
171*49cdfc7eSAndroid Build Coastguard Worker 		exit(0);
172*49cdfc7eSAndroid Build Coastguard Worker 	default:
173*49cdfc7eSAndroid Build Coastguard Worker 		waitpid(pid, NULL, 0);
174*49cdfc7eSAndroid Build Coastguard Worker 	}
175*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_FREE(bin_path);
176*49cdfc7eSAndroid Build Coastguard Worker 
177*49cdfc7eSAndroid Build Coastguard Worker 	if (debug) {
178*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TINFO,
179*49cdfc7eSAndroid Build Coastguard Worker 			 "%s: will run for %d loops; using %s as a data directory",
180*49cdfc7eSAndroid Build Coastguard Worker 			 argv[0], num_loops, datadir);
181*49cdfc7eSAndroid Build Coastguard Worker 	}
182*49cdfc7eSAndroid Build Coastguard Worker 	if (num_threads <= 0) {
183*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TWARN,
184*49cdfc7eSAndroid Build Coastguard Worker 			 "num_threads undefined or incorrect, using \"1\"");
185*49cdfc7eSAndroid Build Coastguard Worker 		num_threads = 1;
186*49cdfc7eSAndroid Build Coastguard Worker 	}
187*49cdfc7eSAndroid Build Coastguard Worker 
188*49cdfc7eSAndroid Build Coastguard Worker 	if (nb_func * num_threads > PTHREAD_THREADS_MAX - 2)
189*49cdfc7eSAndroid Build Coastguard Worker 		while (nb_func * num_threads > PTHREAD_THREADS_MAX - 2)
190*49cdfc7eSAndroid Build Coastguard Worker 			num_threads--;
191*49cdfc7eSAndroid Build Coastguard Worker 	if (debug)
192*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TINFO,
193*49cdfc7eSAndroid Build Coastguard Worker 			 "%s: will run %d functions, %d threads per function",
194*49cdfc7eSAndroid Build Coastguard Worker 			 argv[0], nb_func, num_threads);
195*49cdfc7eSAndroid Build Coastguard Worker 
196*49cdfc7eSAndroid Build Coastguard Worker 	retval = pthread_mutex_init(&sig_mutex, NULL);
197*49cdfc7eSAndroid Build Coastguard Worker 	if (retval != 0)
198*49cdfc7eSAndroid Build Coastguard Worker 		sys_error("main : mutex_init(&sig_mutex) FAILED", __LINE__);
199*49cdfc7eSAndroid Build Coastguard Worker 
200*49cdfc7eSAndroid Build Coastguard Worker 	retval = pthread_create(&sig_hand, NULL, handle_signals, NULL);
201*49cdfc7eSAndroid Build Coastguard Worker 	if (retval != 0)
202*49cdfc7eSAndroid Build Coastguard Worker 		sys_error("main : create(&sig_hand) FAILED", __LINE__);
203*49cdfc7eSAndroid Build Coastguard Worker 
204*49cdfc7eSAndroid Build Coastguard Worker 	/*
205*49cdfc7eSAndroid Build Coastguard Worker 	 * Start all calculation threads...
206*49cdfc7eSAndroid Build Coastguard Worker 	 */
207*49cdfc7eSAndroid Build Coastguard Worker 	threads = malloc(nb_func * num_threads * sizeof(pthread_t));
208*49cdfc7eSAndroid Build Coastguard Worker 	if (threads == NULL)
209*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TFAIL | TERRNO, cleanup, "malloc failed");
210*49cdfc7eSAndroid Build Coastguard Worker 
211*49cdfc7eSAndroid Build Coastguard Worker 	tabcom = malloc((sizeof(TH_DATA *) * nb_func * num_threads));
212*49cdfc7eSAndroid Build Coastguard Worker 	if (!tabcom)
213*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TFAIL | TERRNO, cleanup, "malloc failed");
214*49cdfc7eSAndroid Build Coastguard Worker 	tabcour = tabcom;
215*49cdfc7eSAndroid Build Coastguard Worker 
216*49cdfc7eSAndroid Build Coastguard Worker 	retval = pthread_attr_init(&newattr);
217*49cdfc7eSAndroid Build Coastguard Worker 	if (retval != 0)
218*49cdfc7eSAndroid Build Coastguard Worker 		sys_error("main : attr_init(&newattr) FAILED", __LINE__);
219*49cdfc7eSAndroid Build Coastguard Worker 
220*49cdfc7eSAndroid Build Coastguard Worker 	if (pthread_attr_setstacksize(&newattr, stacksize))
221*49cdfc7eSAndroid Build Coastguard Worker 		sys_error("main: pthread_attr_setstacksize failed", __LINE__);
222*49cdfc7eSAndroid Build Coastguard Worker 
223*49cdfc7eSAndroid Build Coastguard Worker 	retval = pthread_attr_setdetachstate(&newattr, PTHREAD_CREATE_JOINABLE);
224*49cdfc7eSAndroid Build Coastguard Worker 	if (retval != 0)
225*49cdfc7eSAndroid Build Coastguard Worker 		sys_error("main : attr_setdetachstate(&newattr) FAILED",
226*49cdfc7eSAndroid Build Coastguard Worker 			  __LINE__);
227*49cdfc7eSAndroid Build Coastguard Worker 
228*49cdfc7eSAndroid Build Coastguard Worker 	/* run the nb_func functions on num_threads */
229*49cdfc7eSAndroid Build Coastguard Worker 
230*49cdfc7eSAndroid Build Coastguard Worker 	indice = 0;
231*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < nb_func; i++) {
232*49cdfc7eSAndroid Build Coastguard Worker 
233*49cdfc7eSAndroid Build Coastguard Worker 		for (th_num = 0; th_num < num_threads; th_num++) {
234*49cdfc7eSAndroid Build Coastguard Worker 
235*49cdfc7eSAndroid Build Coastguard Worker 			/* allocate struct of commucation  with the thread */
236*49cdfc7eSAndroid Build Coastguard Worker 			pcom = calloc(1, sizeof(TH_DATA));
237*49cdfc7eSAndroid Build Coastguard Worker 			if (pcom == NULL)
238*49cdfc7eSAndroid Build Coastguard Worker 				tst_brkm(TFAIL | TERRNO, cleanup,
239*49cdfc7eSAndroid Build Coastguard Worker 					 "calloc failed");
240*49cdfc7eSAndroid Build Coastguard Worker 			*tabcour = (TH_DATA *) pcom;
241*49cdfc7eSAndroid Build Coastguard Worker 			tabcour++;
242*49cdfc7eSAndroid Build Coastguard Worker 			/*
243*49cdfc7eSAndroid Build Coastguard Worker 			 * update structure of communication
244*49cdfc7eSAndroid Build Coastguard Worker 			 */
245*49cdfc7eSAndroid Build Coastguard Worker 			pcom->th_num = th_num;
246*49cdfc7eSAndroid Build Coastguard Worker 			pcom->th_func = th_func[i];
247*49cdfc7eSAndroid Build Coastguard Worker 
248*49cdfc7eSAndroid Build Coastguard Worker 			pthread_mutex_lock(&sig_mutex);
249*49cdfc7eSAndroid Build Coastguard Worker 
250*49cdfc7eSAndroid Build Coastguard Worker 			if (sig_cancel) {	/* stop processing right now! */
251*49cdfc7eSAndroid Build Coastguard Worker 				pthread_mutex_unlock(&sig_mutex);
252*49cdfc7eSAndroid Build Coastguard Worker 				goto finished;
253*49cdfc7eSAndroid Build Coastguard Worker 			}
254*49cdfc7eSAndroid Build Coastguard Worker 			retval = pthread_create(&threads[indice], &newattr,
255*49cdfc7eSAndroid Build Coastguard Worker 						thread_code, (void *)pcom);
256*49cdfc7eSAndroid Build Coastguard Worker 			if (retval != 0)
257*49cdfc7eSAndroid Build Coastguard Worker 				sys_error("main : create FAILED", __LINE__);
258*49cdfc7eSAndroid Build Coastguard Worker 			indice++;
259*49cdfc7eSAndroid Build Coastguard Worker 			pthread_mutex_unlock(&sig_mutex);
260*49cdfc7eSAndroid Build Coastguard Worker 
261*49cdfc7eSAndroid Build Coastguard Worker 		}		/* num_threads */
262*49cdfc7eSAndroid Build Coastguard Worker 	}			/* for i */
263*49cdfc7eSAndroid Build Coastguard Worker 
264*49cdfc7eSAndroid Build Coastguard Worker 	/*alarm(60*time); *//* start all threads for TEST_time */
265*49cdfc7eSAndroid Build Coastguard Worker 
266*49cdfc7eSAndroid Build Coastguard Worker 	/*
267*49cdfc7eSAndroid Build Coastguard Worker 	 * Wait for the threads finish their task
268*49cdfc7eSAndroid Build Coastguard Worker 	 * pthread_join () will block
269*49cdfc7eSAndroid Build Coastguard Worker 	 */
270*49cdfc7eSAndroid Build Coastguard Worker 
271*49cdfc7eSAndroid Build Coastguard Worker finished:
272*49cdfc7eSAndroid Build Coastguard Worker 	if (debug) {
273*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TINFO,
274*49cdfc7eSAndroid Build Coastguard Worker 			 "initial thread: Waiting for %d threads to finish",
275*49cdfc7eSAndroid Build Coastguard Worker 			 indice);
276*49cdfc7eSAndroid Build Coastguard Worker 	}
277*49cdfc7eSAndroid Build Coastguard Worker 	tabcour = tabcom;
278*49cdfc7eSAndroid Build Coastguard Worker 
279*49cdfc7eSAndroid Build Coastguard Worker 	for (th_num = 0; th_num < indice; th_num++) {
280*49cdfc7eSAndroid Build Coastguard Worker 		retvalend = pthread_join(threads[th_num], &exit_value);
281*49cdfc7eSAndroid Build Coastguard Worker 		if (retvalend != 0)
282*49cdfc7eSAndroid Build Coastguard Worker 			sys_error("finish : join FAILED", __LINE__);
283*49cdfc7eSAndroid Build Coastguard Worker 
284*49cdfc7eSAndroid Build Coastguard Worker 		/* test the result in TH_DATA : communication buffer */
285*49cdfc7eSAndroid Build Coastguard Worker 		pcom = *tabcour++;
286*49cdfc7eSAndroid Build Coastguard Worker 		if (pcom->th_result != 0) {
287*49cdfc7eSAndroid Build Coastguard Worker 			error++;
288*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TFAIL,
289*49cdfc7eSAndroid Build Coastguard Worker 				 "thread %d (%s) terminated unsuccessfully %d "
290*49cdfc7eSAndroid Build Coastguard Worker 				 "errors/%d loops\n%s",
291*49cdfc7eSAndroid Build Coastguard Worker 				 th_num, pcom->th_func.fident, pcom->th_nerror,
292*49cdfc7eSAndroid Build Coastguard Worker 				 pcom->th_nloop, pcom->detail_data);
293*49cdfc7eSAndroid Build Coastguard Worker 		} else if (debug) {
294*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TINFO,
295*49cdfc7eSAndroid Build Coastguard Worker 				 "thread %d (%s) terminated successfully %d loops",
296*49cdfc7eSAndroid Build Coastguard Worker 				 th_num, pcom->th_func.fident,
297*49cdfc7eSAndroid Build Coastguard Worker 				 pcom->th_nloop - 1);
298*49cdfc7eSAndroid Build Coastguard Worker 		}
299*49cdfc7eSAndroid Build Coastguard Worker 		SAFE_FREE(pcom);
300*49cdfc7eSAndroid Build Coastguard Worker 
301*49cdfc7eSAndroid Build Coastguard Worker 	}
302*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_FREE(tabcom);
303*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_FREE(threads);
304*49cdfc7eSAndroid Build Coastguard Worker 	tst_rmdir();
305*49cdfc7eSAndroid Build Coastguard Worker 	if (error)
306*49cdfc7eSAndroid Build Coastguard Worker 		exit(1);
307*49cdfc7eSAndroid Build Coastguard Worker 	else
308*49cdfc7eSAndroid Build Coastguard Worker 		exit(0);
309*49cdfc7eSAndroid Build Coastguard Worker 	return 0;
310*49cdfc7eSAndroid Build Coastguard Worker }
311*49cdfc7eSAndroid Build Coastguard Worker 
312*49cdfc7eSAndroid Build Coastguard Worker /*----------------------------------------------------------------------+
313*49cdfc7eSAndroid Build Coastguard Worker |			    handle_signals ()				|
314*49cdfc7eSAndroid Build Coastguard Worker | ======================================================================|
315*49cdfc7eSAndroid Build Coastguard Worker |									|
316*49cdfc7eSAndroid Build Coastguard Worker | Function:  ....							|
317*49cdfc7eSAndroid Build Coastguard Worker |	    If SIGALRM or SIGUSR1 or SIGINT : cancel threads		|
318*49cdfc7eSAndroid Build Coastguard Worker |									|
319*49cdfc7eSAndroid Build Coastguard Worker | Updates:   ....							|
320*49cdfc7eSAndroid Build Coastguard Worker |									|
321*49cdfc7eSAndroid Build Coastguard Worker +-----------------------------------------------------------------------*/
handle_signals(void * arg)322*49cdfc7eSAndroid Build Coastguard Worker static void *handle_signals(void *arg)
323*49cdfc7eSAndroid Build Coastguard Worker {
324*49cdfc7eSAndroid Build Coastguard Worker 	sigset_t signals_set;
325*49cdfc7eSAndroid Build Coastguard Worker 	int thd;
326*49cdfc7eSAndroid Build Coastguard Worker 	int sig;
327*49cdfc7eSAndroid Build Coastguard Worker 	int retvalsig = 0;
328*49cdfc7eSAndroid Build Coastguard Worker 
329*49cdfc7eSAndroid Build Coastguard Worker 	if (debug)
330*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TINFO, "signal handler %lu started", pthread_self());
331*49cdfc7eSAndroid Build Coastguard Worker 	/*
332*49cdfc7eSAndroid Build Coastguard Worker 	 * Set up the signals that we want to handle...
333*49cdfc7eSAndroid Build Coastguard Worker 	 */
334*49cdfc7eSAndroid Build Coastguard Worker 	sigemptyset(&signals_set);
335*49cdfc7eSAndroid Build Coastguard Worker 	sigaddset(&signals_set, SIGINT);
336*49cdfc7eSAndroid Build Coastguard Worker 	sigaddset(&signals_set, SIGQUIT);
337*49cdfc7eSAndroid Build Coastguard Worker 	sigaddset(&signals_set, SIGTERM);
338*49cdfc7eSAndroid Build Coastguard Worker 	sigaddset(&signals_set, SIGUSR1);
339*49cdfc7eSAndroid Build Coastguard Worker 	sigaddset(&signals_set, SIGALRM);
340*49cdfc7eSAndroid Build Coastguard Worker 	while (1) {
341*49cdfc7eSAndroid Build Coastguard Worker 		if (debug)
342*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TINFO, "Signal handler starts waiting...");
343*49cdfc7eSAndroid Build Coastguard Worker 
344*49cdfc7eSAndroid Build Coastguard Worker 		sigwait(&signals_set, &sig);
345*49cdfc7eSAndroid Build Coastguard Worker 		if (debug)
346*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TINFO, "Signal handler caught signal %d", sig);
347*49cdfc7eSAndroid Build Coastguard Worker 
348*49cdfc7eSAndroid Build Coastguard Worker 		switch (sig) {
349*49cdfc7eSAndroid Build Coastguard Worker 		case SIGALRM:
350*49cdfc7eSAndroid Build Coastguard Worker 		case SIGUSR1:
351*49cdfc7eSAndroid Build Coastguard Worker 		case SIGINT:
352*49cdfc7eSAndroid Build Coastguard Worker 			if (sig_cancel)
353*49cdfc7eSAndroid Build Coastguard Worker 				tst_resm(TINFO,
354*49cdfc7eSAndroid Build Coastguard Worker 					 "Signal handler: already finished; "
355*49cdfc7eSAndroid Build Coastguard Worker 					 "ignoring signal");
356*49cdfc7eSAndroid Build Coastguard Worker 			else {
357*49cdfc7eSAndroid Build Coastguard Worker 				/*
358*49cdfc7eSAndroid Build Coastguard Worker 				 * Have to signal all non started threads...
359*49cdfc7eSAndroid Build Coastguard Worker 				 */
360*49cdfc7eSAndroid Build Coastguard Worker 
361*49cdfc7eSAndroid Build Coastguard Worker 				retvalsig = pthread_mutex_lock(&sig_mutex);
362*49cdfc7eSAndroid Build Coastguard Worker 				if (retvalsig != 0)
363*49cdfc7eSAndroid Build Coastguard Worker 					sys_error
364*49cdfc7eSAndroid Build Coastguard Worker 					    ("handle_signal : mutex_lock(&sig_mutex) FAILED",
365*49cdfc7eSAndroid Build Coastguard Worker 					     __LINE__);
366*49cdfc7eSAndroid Build Coastguard Worker 
367*49cdfc7eSAndroid Build Coastguard Worker 				sig_cancel = 1;
368*49cdfc7eSAndroid Build Coastguard Worker 				retvalsig = pthread_mutex_unlock(&sig_mutex);
369*49cdfc7eSAndroid Build Coastguard Worker 				if (retvalsig != 0)
370*49cdfc7eSAndroid Build Coastguard Worker 					sys_error
371*49cdfc7eSAndroid Build Coastguard Worker 					    ("handle_signal : mutex_unlock(&sig_mutex) FAILED",
372*49cdfc7eSAndroid Build Coastguard Worker 					     __LINE__);
373*49cdfc7eSAndroid Build Coastguard Worker 
374*49cdfc7eSAndroid Build Coastguard Worker 				/*
375*49cdfc7eSAndroid Build Coastguard Worker 				 * ......... and all started
376*49cdfc7eSAndroid Build Coastguard Worker 				 */
377*49cdfc7eSAndroid Build Coastguard Worker 				for (thd = 0; thd < indice; thd++) {
378*49cdfc7eSAndroid Build Coastguard Worker 					if (debug)
379*49cdfc7eSAndroid Build Coastguard Worker 						tst_resm(TINFO,
380*49cdfc7eSAndroid Build Coastguard Worker 							 "signal handler: "
381*49cdfc7eSAndroid Build Coastguard Worker 							 "cancelling thread (%d of "
382*49cdfc7eSAndroid Build Coastguard Worker 							 "%d)", thd, indice);
383*49cdfc7eSAndroid Build Coastguard Worker 					retvalsig =
384*49cdfc7eSAndroid Build Coastguard Worker 					    pthread_cancel(threads[thd]);
385*49cdfc7eSAndroid Build Coastguard Worker 					if (retvalsig != 0)
386*49cdfc7eSAndroid Build Coastguard Worker 						sys_error
387*49cdfc7eSAndroid Build Coastguard Worker 						    ("handle_signal : cancel FAILED",
388*49cdfc7eSAndroid Build Coastguard Worker 						     __LINE__);
389*49cdfc7eSAndroid Build Coastguard Worker 				}
390*49cdfc7eSAndroid Build Coastguard Worker 			}
391*49cdfc7eSAndroid Build Coastguard Worker 			break;
392*49cdfc7eSAndroid Build Coastguard Worker 		case SIGQUIT:
393*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TINFO,
394*49cdfc7eSAndroid Build Coastguard Worker 				 "Signal handler: Caught SIGQUIT; doing nothing");
395*49cdfc7eSAndroid Build Coastguard Worker 			break;
396*49cdfc7eSAndroid Build Coastguard Worker 		case SIGTERM:
397*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TINFO,
398*49cdfc7eSAndroid Build Coastguard Worker 				 "Signal handler: Caught SIGTERM; doing nothing");
399*49cdfc7eSAndroid Build Coastguard Worker 			break;
400*49cdfc7eSAndroid Build Coastguard Worker 		default:
401*49cdfc7eSAndroid Build Coastguard Worker 			exit(1);
402*49cdfc7eSAndroid Build Coastguard Worker 		}
403*49cdfc7eSAndroid Build Coastguard Worker 	}
404*49cdfc7eSAndroid Build Coastguard Worker 	return NULL;
405*49cdfc7eSAndroid Build Coastguard Worker }
406*49cdfc7eSAndroid Build Coastguard Worker 
407*49cdfc7eSAndroid Build Coastguard Worker /*----------------------------------------------------------------------+
408*49cdfc7eSAndroid Build Coastguard Worker  |				error ()				|
409*49cdfc7eSAndroid Build Coastguard Worker  | =====================================================================|
410*49cdfc7eSAndroid Build Coastguard Worker  |									|
411*49cdfc7eSAndroid Build Coastguard Worker  | Function:  Prints out message and exits...				|
412*49cdfc7eSAndroid Build Coastguard Worker  |									|
413*49cdfc7eSAndroid Build Coastguard Worker  +----------------------------------------------------------------------*/
error(const char * msg,int line)414*49cdfc7eSAndroid Build Coastguard Worker static void error(const char *msg, int line)
415*49cdfc7eSAndroid Build Coastguard Worker {
416*49cdfc7eSAndroid Build Coastguard Worker 	tst_brkm(TFAIL, cleanup, "ERROR [line: %d] %s", line, msg);
417*49cdfc7eSAndroid Build Coastguard Worker }
418*49cdfc7eSAndroid Build Coastguard Worker 
419*49cdfc7eSAndroid Build Coastguard Worker /*----------------------------------------------------------------------+
420*49cdfc7eSAndroid Build Coastguard Worker  |			     sys_error ()				|
421*49cdfc7eSAndroid Build Coastguard Worker  | =====================================================================|
422*49cdfc7eSAndroid Build Coastguard Worker  |									|
423*49cdfc7eSAndroid Build Coastguard Worker  | Function:  Creates system error message and calls error ()		|
424*49cdfc7eSAndroid Build Coastguard Worker  |									|
425*49cdfc7eSAndroid Build Coastguard Worker  +----------------------------------------------------------------------*/
426*49cdfc7eSAndroid Build Coastguard Worker /*
427*49cdfc7eSAndroid Build Coastguard Worker  * XXX (garrcoop): the way that this is being called is just plain wrong.
428*49cdfc7eSAndroid Build Coastguard Worker  * pthread(5) returns 0 or errnos, not necessarily sets errno to a sensible
429*49cdfc7eSAndroid Build Coastguard Worker  * value.
430*49cdfc7eSAndroid Build Coastguard Worker  */
sys_error(const char * msg,int line)431*49cdfc7eSAndroid Build Coastguard Worker static void sys_error(const char *msg, int line)
432*49cdfc7eSAndroid Build Coastguard Worker {
433*49cdfc7eSAndroid Build Coastguard Worker 	char syserr_msg[256];
434*49cdfc7eSAndroid Build Coastguard Worker 
435*49cdfc7eSAndroid Build Coastguard Worker 	sprintf(syserr_msg, "%s: %s", msg, strerror(errno));
436*49cdfc7eSAndroid Build Coastguard Worker 	error(syserr_msg, line);
437*49cdfc7eSAndroid Build Coastguard Worker }
438