xref: /aosp_15_r20/external/ltp/testcases/kernel/sched/nptl/nptl01.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker /*
2*49cdfc7eSAndroid Build Coastguard Worker  * Copyright (c) International Business Machines  Corp., 2004.
3*49cdfc7eSAndroid Build Coastguard Worker  *
4*49cdfc7eSAndroid Build Coastguard Worker  * This program is free software; you can redistribute it and/or modify it
5*49cdfc7eSAndroid Build Coastguard Worker  * under the terms of version 2 of the GNU General Public License as
6*49cdfc7eSAndroid Build Coastguard Worker  * published by the Free Software Foundation.
7*49cdfc7eSAndroid Build Coastguard Worker  *
8*49cdfc7eSAndroid Build Coastguard Worker  * This program is distributed in the hope that it would be useful, but
9*49cdfc7eSAndroid Build Coastguard Worker  * WITHOUT ANY WARRANTY; without even the implied warranty of
10*49cdfc7eSAndroid Build Coastguard Worker  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11*49cdfc7eSAndroid Build Coastguard Worker  *
12*49cdfc7eSAndroid Build Coastguard Worker  * You should have received a copy of the GNU General Public License along
13*49cdfc7eSAndroid Build Coastguard Worker  * with this program; if not, write the Free Software Foundation, Inc.,
14*49cdfc7eSAndroid Build Coastguard Worker  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
15*49cdfc7eSAndroid Build Coastguard Worker  *
16*49cdfc7eSAndroid Build Coastguard Worker  */
17*49cdfc7eSAndroid Build Coastguard Worker /**********************************************************
18*49cdfc7eSAndroid Build Coastguard Worker  *
19*49cdfc7eSAndroid Build Coastguard Worker  *    TEST IDENTIFIER   : nptl01
20*49cdfc7eSAndroid Build Coastguard Worker  *
21*49cdfc7eSAndroid Build Coastguard Worker  *    EXECUTED BY       : root
22*49cdfc7eSAndroid Build Coastguard Worker  *
23*49cdfc7eSAndroid Build Coastguard Worker  *    TEST TITLE        : NPTL test for pthread_cond_timedwait() error
24*49cdfc7eSAndroid Build Coastguard Worker  *			  path bug.
25*49cdfc7eSAndroid Build Coastguard Worker  *
26*49cdfc7eSAndroid Build Coastguard Worker  *    TEST CASE TOTAL   : 1
27*49cdfc7eSAndroid Build Coastguard Worker  *
28*49cdfc7eSAndroid Build Coastguard Worker  *    AUTHOR            : Neil Richards <[email protected]>
29*49cdfc7eSAndroid Build Coastguard Worker  *
30*49cdfc7eSAndroid Build Coastguard Worker  *    DESCRIPTION
31*49cdfc7eSAndroid Build Coastguard Worker  *      This is a test for a bug found in the pthread_cond_timedwait() system call.
32*49cdfc7eSAndroid Build Coastguard Worker  *	of the Native POSIX Thread Library (NPTL) library code.
33*49cdfc7eSAndroid Build Coastguard Worker  *      There was an error path in the system call, where the sequence counters were
34*49cdfc7eSAndroid Build Coastguard Worker  *      getting updated w/o holding the internal condvar lock. A FAIL is indicated
35*49cdfc7eSAndroid Build Coastguard Worker  *	by the test hanging and not completing execution.
36*49cdfc7eSAndroid Build Coastguard Worker  *
37*49cdfc7eSAndroid Build Coastguard Worker  ****************************************************************/
38*49cdfc7eSAndroid Build Coastguard Worker #define _GNU_SOURCE
39*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
40*49cdfc7eSAndroid Build Coastguard Worker #include <stdlib.h>
41*49cdfc7eSAndroid Build Coastguard Worker #include <string.h>
42*49cdfc7eSAndroid Build Coastguard Worker #include <pthread.h>
43*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
44*49cdfc7eSAndroid Build Coastguard Worker #include <unistd.h>
45*49cdfc7eSAndroid Build Coastguard Worker #include <time.h>
46*49cdfc7eSAndroid Build Coastguard Worker #include <sys/time.h>
47*49cdfc7eSAndroid Build Coastguard Worker #include "test.h"
48*49cdfc7eSAndroid Build Coastguard Worker 
49*49cdfc7eSAndroid Build Coastguard Worker #define MAXTIME 72000		/* Maximum # of secs to wait before failing */
50*49cdfc7eSAndroid Build Coastguard Worker #define NUMLOOPS 100000		/* # of loops */
51*49cdfc7eSAndroid Build Coastguard Worker 
52*49cdfc7eSAndroid Build Coastguard Worker char *TCID = "nptl01";		/* Test program identifier.    */
53*49cdfc7eSAndroid Build Coastguard Worker int TST_TOTAL = 1;		/* Total number of test cases. */
54*49cdfc7eSAndroid Build Coastguard Worker void cleanup();
55*49cdfc7eSAndroid Build Coastguard Worker 
56*49cdfc7eSAndroid Build Coastguard Worker pthread_mutex_t req;
57*49cdfc7eSAndroid Build Coastguard Worker pthread_mutex_t ack;
58*49cdfc7eSAndroid Build Coastguard Worker pthread_mutex_t wait;
59*49cdfc7eSAndroid Build Coastguard Worker pthread_cond_t parent;
60*49cdfc7eSAndroid Build Coastguard Worker pthread_cond_t child;
61*49cdfc7eSAndroid Build Coastguard Worker int idle_count = 0;
62*49cdfc7eSAndroid Build Coastguard Worker 
63*49cdfc7eSAndroid Build Coastguard Worker /*
64*49cdfc7eSAndroid Build Coastguard Worker  * The time to wait should be set appropriately so that the waiting thread
65*49cdfc7eSAndroid Build Coastguard Worker  * is coming out of the wait at around the same time as the other thread is
66*49cdfc7eSAndroid Build Coastguard Worker  * signalling it.
67*49cdfc7eSAndroid Build Coastguard Worker  * The value of 1000 seems to work (ie. demonstrate the problem) on my
68*49cdfc7eSAndroid Build Coastguard Worker  * 8 way (hyperthreaded) 2GHz Xeon box.
69*49cdfc7eSAndroid Build Coastguard Worker  */
70*49cdfc7eSAndroid Build Coastguard Worker #define NSECS_TO_WAIT	(1)
71*49cdfc7eSAndroid Build Coastguard Worker 
call_mutex_init(pthread_mutex_t * mutex,char * buf,size_t buf_len)72*49cdfc7eSAndroid Build Coastguard Worker void call_mutex_init(pthread_mutex_t * mutex, char *buf, size_t buf_len)
73*49cdfc7eSAndroid Build Coastguard Worker {
74*49cdfc7eSAndroid Build Coastguard Worker 	int ret;
75*49cdfc7eSAndroid Build Coastguard Worker 
76*49cdfc7eSAndroid Build Coastguard Worker 	if ((ret = pthread_mutex_init(mutex, NULL)) != 0) {
77*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, cleanup, "pthread_mutex_init failed: %s",
78*49cdfc7eSAndroid Build Coastguard Worker 			 strerror_r(ret, buf, buf_len));
79*49cdfc7eSAndroid Build Coastguard Worker 	}
80*49cdfc7eSAndroid Build Coastguard Worker }
81*49cdfc7eSAndroid Build Coastguard Worker 
call_mutex_lock(pthread_mutex_t * mutex,char * buf,size_t buf_len)82*49cdfc7eSAndroid Build Coastguard Worker void call_mutex_lock(pthread_mutex_t * mutex, char *buf, size_t buf_len)
83*49cdfc7eSAndroid Build Coastguard Worker {
84*49cdfc7eSAndroid Build Coastguard Worker 	int ret;
85*49cdfc7eSAndroid Build Coastguard Worker 
86*49cdfc7eSAndroid Build Coastguard Worker 	if ((ret = pthread_mutex_lock(mutex)) != 0) {
87*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, cleanup, "pthread_mutex_lock failed: %s",
88*49cdfc7eSAndroid Build Coastguard Worker 			 strerror_r(ret, buf, buf_len));
89*49cdfc7eSAndroid Build Coastguard Worker 	}
90*49cdfc7eSAndroid Build Coastguard Worker }
91*49cdfc7eSAndroid Build Coastguard Worker 
call_mutex_unlock(pthread_mutex_t * mutex,char * buf,size_t buf_len)92*49cdfc7eSAndroid Build Coastguard Worker void call_mutex_unlock(pthread_mutex_t * mutex, char *buf, size_t buf_len)
93*49cdfc7eSAndroid Build Coastguard Worker {
94*49cdfc7eSAndroid Build Coastguard Worker 	int ret;
95*49cdfc7eSAndroid Build Coastguard Worker 
96*49cdfc7eSAndroid Build Coastguard Worker 	if ((ret = pthread_mutex_unlock(mutex)) != 0) {
97*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, cleanup, "pthread_mutex_unlock failed: %s",
98*49cdfc7eSAndroid Build Coastguard Worker 			 strerror_r(ret, buf, buf_len));
99*49cdfc7eSAndroid Build Coastguard Worker 	}
100*49cdfc7eSAndroid Build Coastguard Worker }
101*49cdfc7eSAndroid Build Coastguard Worker 
call_cond_init(pthread_cond_t * cond,char * buf,size_t buf_len)102*49cdfc7eSAndroid Build Coastguard Worker void call_cond_init(pthread_cond_t * cond, char *buf, size_t buf_len)
103*49cdfc7eSAndroid Build Coastguard Worker {
104*49cdfc7eSAndroid Build Coastguard Worker 	int ret;
105*49cdfc7eSAndroid Build Coastguard Worker 
106*49cdfc7eSAndroid Build Coastguard Worker 	if ((ret = pthread_cond_init(cond, NULL)) != 0) {
107*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, cleanup, "pthread_cond_init failed: %s",
108*49cdfc7eSAndroid Build Coastguard Worker 			 strerror_r(ret, buf, buf_len));
109*49cdfc7eSAndroid Build Coastguard Worker 	}
110*49cdfc7eSAndroid Build Coastguard Worker }
111*49cdfc7eSAndroid Build Coastguard Worker 
call_cond_wait(pthread_cond_t * cond,pthread_mutex_t * mutex,char * buf,size_t buf_len)112*49cdfc7eSAndroid Build Coastguard Worker void call_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex,
113*49cdfc7eSAndroid Build Coastguard Worker 		    char *buf, size_t buf_len)
114*49cdfc7eSAndroid Build Coastguard Worker {
115*49cdfc7eSAndroid Build Coastguard Worker 	int ret;
116*49cdfc7eSAndroid Build Coastguard Worker 
117*49cdfc7eSAndroid Build Coastguard Worker 	if ((ret = pthread_cond_wait(cond, mutex)) != 0) {
118*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, cleanup, "pthread_cond_wait failed: %s",
119*49cdfc7eSAndroid Build Coastguard Worker 			 strerror_r(ret, buf, buf_len));
120*49cdfc7eSAndroid Build Coastguard Worker 	}
121*49cdfc7eSAndroid Build Coastguard Worker }
122*49cdfc7eSAndroid Build Coastguard Worker 
call_cond_signal(pthread_cond_t * cond,char * buf,size_t buf_len)123*49cdfc7eSAndroid Build Coastguard Worker void call_cond_signal(pthread_cond_t * cond, char *buf, size_t buf_len)
124*49cdfc7eSAndroid Build Coastguard Worker {
125*49cdfc7eSAndroid Build Coastguard Worker 	int ret;
126*49cdfc7eSAndroid Build Coastguard Worker 
127*49cdfc7eSAndroid Build Coastguard Worker 	if ((ret = pthread_cond_signal(cond)) != 0) {
128*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, cleanup, "pthread_cond_signal failed: %s",
129*49cdfc7eSAndroid Build Coastguard Worker 			 strerror_r(ret, buf, buf_len));
130*49cdfc7eSAndroid Build Coastguard Worker 	}
131*49cdfc7eSAndroid Build Coastguard Worker }
132*49cdfc7eSAndroid Build Coastguard Worker 
do_timedwait(pthread_cond_t * cond,pthread_mutex_t * mutex,char * buf,size_t buf_len,int i)133*49cdfc7eSAndroid Build Coastguard Worker void do_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
134*49cdfc7eSAndroid Build Coastguard Worker 		  char *buf, size_t buf_len, int i)
135*49cdfc7eSAndroid Build Coastguard Worker {
136*49cdfc7eSAndroid Build Coastguard Worker 	struct timeval tv;
137*49cdfc7eSAndroid Build Coastguard Worker 	struct timespec ts;
138*49cdfc7eSAndroid Build Coastguard Worker 	int ret;
139*49cdfc7eSAndroid Build Coastguard Worker 
140*49cdfc7eSAndroid Build Coastguard Worker 	if (gettimeofday(&tv, NULL) != 0) {
141*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, cleanup, "gettimeofday failed: %s",
142*49cdfc7eSAndroid Build Coastguard Worker 			 strerror_r(errno, buf, buf_len));
143*49cdfc7eSAndroid Build Coastguard Worker 	}
144*49cdfc7eSAndroid Build Coastguard Worker 
145*49cdfc7eSAndroid Build Coastguard Worker 	ts.tv_sec = tv.tv_sec;
146*49cdfc7eSAndroid Build Coastguard Worker 	ts.tv_nsec = (tv.tv_usec * 1000) + NSECS_TO_WAIT;
147*49cdfc7eSAndroid Build Coastguard Worker 	ts.tv_sec += ts.tv_nsec / 1000000000;
148*49cdfc7eSAndroid Build Coastguard Worker 	ts.tv_nsec = ts.tv_nsec % 1000000000;
149*49cdfc7eSAndroid Build Coastguard Worker 
150*49cdfc7eSAndroid Build Coastguard Worker 	call_mutex_lock(mutex, buf, buf_len);
151*49cdfc7eSAndroid Build Coastguard Worker 	if ((ret = pthread_cond_timedwait(cond, mutex, &ts)) != ETIMEDOUT) {
152*49cdfc7eSAndroid Build Coastguard Worker #if DEBUG
153*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TINFO,
154*49cdfc7eSAndroid Build Coastguard Worker 			 "Loop %d of 1000000: pthread_cond_timedwait() didn't timeout",
155*49cdfc7eSAndroid Build Coastguard Worker 			 i);
156*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TINFO,
157*49cdfc7eSAndroid Build Coastguard Worker 			 "You may want to try reducing the value of NSECS_TO_WAIT (currently=%d)",
158*49cdfc7eSAndroid Build Coastguard Worker 			 NSECS_TO_WAIT);
159*49cdfc7eSAndroid Build Coastguard Worker #endif
160*49cdfc7eSAndroid Build Coastguard Worker 	}
161*49cdfc7eSAndroid Build Coastguard Worker 	call_mutex_unlock(mutex, buf, buf_len);
162*49cdfc7eSAndroid Build Coastguard Worker 
163*49cdfc7eSAndroid Build Coastguard Worker }
164*49cdfc7eSAndroid Build Coastguard Worker 
run(void * arg)165*49cdfc7eSAndroid Build Coastguard Worker void *run(void *arg)
166*49cdfc7eSAndroid Build Coastguard Worker {
167*49cdfc7eSAndroid Build Coastguard Worker 	char buf[1024];
168*49cdfc7eSAndroid Build Coastguard Worker 
169*49cdfc7eSAndroid Build Coastguard Worker 	while (1) {
170*49cdfc7eSAndroid Build Coastguard Worker 		call_mutex_lock(&ack, buf, sizeof(buf));
171*49cdfc7eSAndroid Build Coastguard Worker 		idle_count = 1;
172*49cdfc7eSAndroid Build Coastguard Worker 		call_cond_signal(&parent, buf, sizeof(buf));
173*49cdfc7eSAndroid Build Coastguard Worker 		call_mutex_lock(&req, buf, sizeof(buf));
174*49cdfc7eSAndroid Build Coastguard Worker 		call_mutex_unlock(&ack, buf, sizeof(buf));
175*49cdfc7eSAndroid Build Coastguard Worker 
176*49cdfc7eSAndroid Build Coastguard Worker 		call_mutex_lock(&wait, buf, sizeof(buf));
177*49cdfc7eSAndroid Build Coastguard Worker 		call_cond_signal(&parent, buf, sizeof(buf));
178*49cdfc7eSAndroid Build Coastguard Worker 		call_mutex_unlock(&wait, buf, sizeof(buf));
179*49cdfc7eSAndroid Build Coastguard Worker 
180*49cdfc7eSAndroid Build Coastguard Worker 		call_cond_wait(&child, &req, buf, sizeof(buf));
181*49cdfc7eSAndroid Build Coastguard Worker 		call_mutex_unlock(&req, buf, sizeof(buf));
182*49cdfc7eSAndroid Build Coastguard Worker 	}
183*49cdfc7eSAndroid Build Coastguard Worker }
184*49cdfc7eSAndroid Build Coastguard Worker 
create_child_thread(char * buf,size_t buf_len)185*49cdfc7eSAndroid Build Coastguard Worker void create_child_thread(char *buf, size_t buf_len)
186*49cdfc7eSAndroid Build Coastguard Worker {
187*49cdfc7eSAndroid Build Coastguard Worker 	pthread_attr_t attr;
188*49cdfc7eSAndroid Build Coastguard Worker 	pthread_t child_tid;
189*49cdfc7eSAndroid Build Coastguard Worker 	int ret;
190*49cdfc7eSAndroid Build Coastguard Worker 
191*49cdfc7eSAndroid Build Coastguard Worker 	if ((ret = pthread_attr_init(&attr)) != 0) {
192*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, cleanup, "pthread_attr_init failed: %s",
193*49cdfc7eSAndroid Build Coastguard Worker 			 strerror_r(ret, buf, buf_len));
194*49cdfc7eSAndroid Build Coastguard Worker 	}
195*49cdfc7eSAndroid Build Coastguard Worker 	if ((ret = pthread_attr_setdetachstate(&attr,
196*49cdfc7eSAndroid Build Coastguard Worker 					       PTHREAD_CREATE_DETACHED)) != 0) {
197*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, cleanup,
198*49cdfc7eSAndroid Build Coastguard Worker 			 "pthread_attr_setdetachstate failed: %s",
199*49cdfc7eSAndroid Build Coastguard Worker 			 strerror_r(ret, buf, buf_len));
200*49cdfc7eSAndroid Build Coastguard Worker 	}
201*49cdfc7eSAndroid Build Coastguard Worker 	if ((ret = pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM)) != 0) {
202*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, cleanup, "pthread_attr_setscope failed: %s",
203*49cdfc7eSAndroid Build Coastguard Worker 			 strerror_r(ret, buf, buf_len));
204*49cdfc7eSAndroid Build Coastguard Worker 	}
205*49cdfc7eSAndroid Build Coastguard Worker 
206*49cdfc7eSAndroid Build Coastguard Worker 	if ((ret = pthread_create(&child_tid, &attr, run, NULL)) != 0) {
207*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK, cleanup, "pthread_create failed: %s",
208*49cdfc7eSAndroid Build Coastguard Worker 			 strerror_r(ret, buf, buf_len));
209*49cdfc7eSAndroid Build Coastguard Worker 	}
210*49cdfc7eSAndroid Build Coastguard Worker }
211*49cdfc7eSAndroid Build Coastguard Worker 
trap_alarm(int sig)212*49cdfc7eSAndroid Build Coastguard Worker void trap_alarm(int sig)
213*49cdfc7eSAndroid Build Coastguard Worker {
214*49cdfc7eSAndroid Build Coastguard Worker 	tst_brkm(TFAIL, cleanup, "Test hang longer than %d sec detected",
215*49cdfc7eSAndroid Build Coastguard Worker 		 MAXTIME);
216*49cdfc7eSAndroid Build Coastguard Worker }
217*49cdfc7eSAndroid Build Coastguard Worker 
usage(const char * progname)218*49cdfc7eSAndroid Build Coastguard Worker static void usage(const char *progname)
219*49cdfc7eSAndroid Build Coastguard Worker {
220*49cdfc7eSAndroid Build Coastguard Worker 	fprintf(stderr, "usage: %s -l loops\n", progname);
221*49cdfc7eSAndroid Build Coastguard Worker 	fprintf(stderr, "\t-l specify the number of loops to carry out\n");
222*49cdfc7eSAndroid Build Coastguard Worker }
223*49cdfc7eSAndroid Build Coastguard Worker 
main(int argc,char ** argv)224*49cdfc7eSAndroid Build Coastguard Worker int main(int argc, char **argv)
225*49cdfc7eSAndroid Build Coastguard Worker {
226*49cdfc7eSAndroid Build Coastguard Worker #ifdef USING_NPTL
227*49cdfc7eSAndroid Build Coastguard Worker 	char buf[1024];
228*49cdfc7eSAndroid Build Coastguard Worker 	int i;
229*49cdfc7eSAndroid Build Coastguard Worker 	extern char *optarg;
230*49cdfc7eSAndroid Build Coastguard Worker 	int numloops = NUMLOOPS;
231*49cdfc7eSAndroid Build Coastguard Worker 
232*49cdfc7eSAndroid Build Coastguard Worker 	while ((i = getopt(argc, argv, "l:")) != -1) {
233*49cdfc7eSAndroid Build Coastguard Worker 		switch (i) {
234*49cdfc7eSAndroid Build Coastguard Worker 		case 'l':
235*49cdfc7eSAndroid Build Coastguard Worker 			if (optarg)
236*49cdfc7eSAndroid Build Coastguard Worker 				numloops = atoi(optarg);
237*49cdfc7eSAndroid Build Coastguard Worker 			else
238*49cdfc7eSAndroid Build Coastguard Worker 				fprintf(stderr,
239*49cdfc7eSAndroid Build Coastguard Worker 					"%s: option -l requires an argument\n",
240*49cdfc7eSAndroid Build Coastguard Worker 					argv[0]);
241*49cdfc7eSAndroid Build Coastguard Worker 			break;
242*49cdfc7eSAndroid Build Coastguard Worker 		default:
243*49cdfc7eSAndroid Build Coastguard Worker 			usage(argv[0]);
244*49cdfc7eSAndroid Build Coastguard Worker 			exit(1);
245*49cdfc7eSAndroid Build Coastguard Worker 		}
246*49cdfc7eSAndroid Build Coastguard Worker 	}
247*49cdfc7eSAndroid Build Coastguard Worker 
248*49cdfc7eSAndroid Build Coastguard Worker 	signal(SIGALRM, trap_alarm);
249*49cdfc7eSAndroid Build Coastguard Worker 	alarm(MAXTIME);
250*49cdfc7eSAndroid Build Coastguard Worker 
251*49cdfc7eSAndroid Build Coastguard Worker 	call_mutex_init(&req, buf, sizeof(buf));
252*49cdfc7eSAndroid Build Coastguard Worker 	call_mutex_init(&ack, buf, sizeof(buf));
253*49cdfc7eSAndroid Build Coastguard Worker 	call_mutex_init(&wait, buf, sizeof(buf));
254*49cdfc7eSAndroid Build Coastguard Worker 	call_cond_init(&parent, buf, sizeof(buf));
255*49cdfc7eSAndroid Build Coastguard Worker 	call_cond_init(&child, buf, sizeof(buf));
256*49cdfc7eSAndroid Build Coastguard Worker 
257*49cdfc7eSAndroid Build Coastguard Worker 	call_mutex_lock(&ack, buf, sizeof(buf));
258*49cdfc7eSAndroid Build Coastguard Worker 
259*49cdfc7eSAndroid Build Coastguard Worker 	create_child_thread(buf, sizeof(buf));
260*49cdfc7eSAndroid Build Coastguard Worker 
261*49cdfc7eSAndroid Build Coastguard Worker 	tst_resm(TINFO, "Starting test, please wait.");
262*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < numloops; i++) {
263*49cdfc7eSAndroid Build Coastguard Worker 		while (idle_count == 0) {
264*49cdfc7eSAndroid Build Coastguard Worker 			call_cond_wait(&parent, &ack, buf, sizeof(buf));
265*49cdfc7eSAndroid Build Coastguard Worker 		};
266*49cdfc7eSAndroid Build Coastguard Worker 		idle_count = 0;
267*49cdfc7eSAndroid Build Coastguard Worker 		call_mutex_unlock(&ack, buf, sizeof(buf));
268*49cdfc7eSAndroid Build Coastguard Worker 
269*49cdfc7eSAndroid Build Coastguard Worker 		do_timedwait(&parent, &wait, buf, sizeof(buf), i);
270*49cdfc7eSAndroid Build Coastguard Worker 
271*49cdfc7eSAndroid Build Coastguard Worker 		call_mutex_lock(&req, buf, sizeof(buf));
272*49cdfc7eSAndroid Build Coastguard Worker 		call_cond_signal(&child, buf, sizeof(buf));
273*49cdfc7eSAndroid Build Coastguard Worker 		call_mutex_unlock(&req, buf, sizeof(buf));
274*49cdfc7eSAndroid Build Coastguard Worker #ifdef DEBUG
275*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TINFO, "Success in loop %d", i);
276*49cdfc7eSAndroid Build Coastguard Worker #else
277*49cdfc7eSAndroid Build Coastguard Worker 		if (((i % (numloops / 10)) == 0) && (i != 0))
278*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TINFO, "Success thru loop %d of %i", i,
279*49cdfc7eSAndroid Build Coastguard Worker 				 numloops);
280*49cdfc7eSAndroid Build Coastguard Worker #endif
281*49cdfc7eSAndroid Build Coastguard Worker 		call_mutex_lock(&ack, buf, sizeof(buf));
282*49cdfc7eSAndroid Build Coastguard Worker 	}
283*49cdfc7eSAndroid Build Coastguard Worker 
284*49cdfc7eSAndroid Build Coastguard Worker 	alarm(0);
285*49cdfc7eSAndroid Build Coastguard Worker 	tst_resm(TPASS, "Test completed successfully!");
286*49cdfc7eSAndroid Build Coastguard Worker 	cleanup();
287*49cdfc7eSAndroid Build Coastguard Worker 
288*49cdfc7eSAndroid Build Coastguard Worker #else
289*49cdfc7eSAndroid Build Coastguard Worker 	tst_brkm(TCONF, NULL,
290*49cdfc7eSAndroid Build Coastguard Worker 		 "Skipping Execution - This system is not using NPTL");
291*49cdfc7eSAndroid Build Coastguard Worker #endif
292*49cdfc7eSAndroid Build Coastguard Worker 
293*49cdfc7eSAndroid Build Coastguard Worker 	return 1;
294*49cdfc7eSAndroid Build Coastguard Worker }
295*49cdfc7eSAndroid Build Coastguard Worker 
296*49cdfc7eSAndroid Build Coastguard Worker /*
297*49cdfc7eSAndroid Build Coastguard Worker  *cleanup() -  performs all ONE TIME cleanup for this test at
298*49cdfc7eSAndroid Build Coastguard Worker  *              completion or premature exit.
299*49cdfc7eSAndroid Build Coastguard Worker  */
cleanup()300*49cdfc7eSAndroid Build Coastguard Worker void cleanup()
301*49cdfc7eSAndroid Build Coastguard Worker {
302*49cdfc7eSAndroid Build Coastguard Worker 
303*49cdfc7eSAndroid Build Coastguard Worker 	tst_exit();
304*49cdfc7eSAndroid Build Coastguard Worker }
305