xref: /aosp_15_r20/external/ltp/testcases/realtime/func/prio-preempt/prio-preempt.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker /******************************************************************************
2*49cdfc7eSAndroid Build Coastguard Worker  *
3*49cdfc7eSAndroid Build Coastguard Worker  *   Copyright © International Business Machines  Corp., 2006, 2008
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  * NAME
20*49cdfc7eSAndroid Build Coastguard Worker  *     prio-preempt.c
21*49cdfc7eSAndroid Build Coastguard Worker  *
22*49cdfc7eSAndroid Build Coastguard Worker  * DESCRIPTION
23*49cdfc7eSAndroid Build Coastguard Worker  *     Test whether priority pre-emption works fine.
24*49cdfc7eSAndroid Build Coastguard Worker  *
25*49cdfc7eSAndroid Build Coastguard Worker  *    The main thread:
26*49cdfc7eSAndroid Build Coastguard Worker  *     - Creates a minimum of (N-1) busy threads at priority starting at
27*49cdfc7eSAndroid Build Coastguard Worker  *		     SCHED_FIFO + 80
28*49cdfc7eSAndroid Build Coastguard Worker  *     - Creates 26 FIFO (T1, T2,...,T26) threads with priorities 10, 11,...,36.
29*49cdfc7eSAndroid Build Coastguard Worker  *     - Each of these worker threads executes the following piece of code:
30*49cdfc7eSAndroid Build Coastguard Worker  *		   pthread_mutex_lock(Mi);
31*49cdfc7eSAndroid Build Coastguard Worker  *		   pthread_cond_wait(CVi);
32*49cdfc7eSAndroid Build Coastguard Worker  *		   pthread_mutex_unlock(Mi);
33*49cdfc7eSAndroid Build Coastguard Worker  *
34*49cdfc7eSAndroid Build Coastguard Worker  *       where Mi is the ith pthread_mutex_t and CVi is the ith conditional
35*49cdfc7eSAndroid Build Coastguard Worker  *       variable.So, at the end of this loop, 26 threads are all waiting on
36*49cdfc7eSAndroid Build Coastguard Worker  *       seperate condvars and mutexes.
37*49cdfc7eSAndroid Build Coastguard Worker  *     - Wakes up thread at priority 10 (T1) by executing:
38*49cdfc7eSAndroid Build Coastguard Worker  *	   pthread_mutex_lock(M1);
39*49cdfc7eSAndroid Build Coastguard Worker  *	   pthread_cond_signal(CV1);
40*49cdfc7eSAndroid Build Coastguard Worker  *	   pthread_mutex_unlock(M1);
41*49cdfc7eSAndroid Build Coastguard Worker  *
42*49cdfc7eSAndroid Build Coastguard Worker  *     - Waits for all the worker threads to finish execution.
43*49cdfc7eSAndroid Build Coastguard Worker  *	 T1 then wakes up T2 by signalling on the condvar CV2 and sets a flag
44*49cdfc7eSAndroid Build Coastguard Worker  *	 called T1_after_wait to indicate that it is after the wait. It then
45*49cdfc7eSAndroid Build Coastguard Worker  *	 checks if T2_after_wait has been set or not. If not, the test fails,
46*49cdfc7eSAndroid Build Coastguard Worker  *	 else the process continues with other threads. The thread T1 expects
47*49cdfc7eSAndroid Build Coastguard Worker  *	 T2_after_wait to be set as, the moment T1 signals on CV2, T2 is
48*49cdfc7eSAndroid Build Coastguard Worker  *	 supposed to be scheduled (in accordance with priority preemption).
49*49cdfc7eSAndroid Build Coastguard Worker  *
50*49cdfc7eSAndroid Build Coastguard Worker  * USAGE:
51*49cdfc7eSAndroid Build Coastguard Worker  *      Use run_auto.sh script in current directory to build and run test.
52*49cdfc7eSAndroid Build Coastguard Worker  *
53*49cdfc7eSAndroid Build Coastguard Worker  * AUTHOR
54*49cdfc7eSAndroid Build Coastguard Worker  *      Dinakar Guniguntala <[email protected]>
55*49cdfc7eSAndroid Build Coastguard Worker  *
56*49cdfc7eSAndroid Build Coastguard Worker  * HISTORY
57*49cdfc7eSAndroid Build Coastguard Worker  *      2006-Jun-01: Initial version by Dinakar Guniguntala
58*49cdfc7eSAndroid Build Coastguard Worker  *		    Changes from John Stultz and Vivek Pallantla
59*49cdfc7eSAndroid Build Coastguard Worker  *
60*49cdfc7eSAndroid Build Coastguard Worker  *****************************************************************************/
61*49cdfc7eSAndroid Build Coastguard Worker 
62*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
63*49cdfc7eSAndroid Build Coastguard Worker #include <stdlib.h>
64*49cdfc7eSAndroid Build Coastguard Worker #include <signal.h>
65*49cdfc7eSAndroid Build Coastguard Worker #include <time.h>
66*49cdfc7eSAndroid Build Coastguard Worker #include <pthread.h>
67*49cdfc7eSAndroid Build Coastguard Worker #include <sched.h>
68*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
69*49cdfc7eSAndroid Build Coastguard Worker #include <sys/syscall.h>
70*49cdfc7eSAndroid Build Coastguard Worker #include <librttest.h>
71*49cdfc7eSAndroid Build Coastguard Worker 
72*49cdfc7eSAndroid Build Coastguard Worker #define NUM_WORKERS	27
73*49cdfc7eSAndroid Build Coastguard Worker #define CHECK_LIMIT	1
74*49cdfc7eSAndroid Build Coastguard Worker 
75*49cdfc7eSAndroid Build Coastguard Worker volatile int busy_threads = 0;
76*49cdfc7eSAndroid Build Coastguard Worker volatile int test_over = 0;
77*49cdfc7eSAndroid Build Coastguard Worker volatile int threads_running = 0;
78*49cdfc7eSAndroid Build Coastguard Worker static int rt_threads = -1;
79*49cdfc7eSAndroid Build Coastguard Worker static int int_threads = 0;
80*49cdfc7eSAndroid Build Coastguard Worker static pthread_mutex_t bmutex = PTHREAD_MUTEX_INITIALIZER;
81*49cdfc7eSAndroid Build Coastguard Worker 
82*49cdfc7eSAndroid Build Coastguard Worker static pthread_mutex_t mutex[NUM_WORKERS + 1];
83*49cdfc7eSAndroid Build Coastguard Worker static pthread_cond_t cond[NUM_WORKERS + 1];
84*49cdfc7eSAndroid Build Coastguard Worker static int t_after_wait[NUM_WORKERS];
85*49cdfc7eSAndroid Build Coastguard Worker 
86*49cdfc7eSAndroid Build Coastguard Worker static int ret = 0;
87*49cdfc7eSAndroid Build Coastguard Worker 
88*49cdfc7eSAndroid Build Coastguard Worker pthread_barrier_t barrier;
89*49cdfc7eSAndroid Build Coastguard Worker 
usage(void)90*49cdfc7eSAndroid Build Coastguard Worker void usage(void)
91*49cdfc7eSAndroid Build Coastguard Worker {
92*49cdfc7eSAndroid Build Coastguard Worker 	rt_help();
93*49cdfc7eSAndroid Build Coastguard Worker 	printf("prio-preempt specific options:\n");
94*49cdfc7eSAndroid Build Coastguard Worker 	printf("  -i	    #: enable interrupter threads\n");
95*49cdfc7eSAndroid Build Coastguard Worker 	printf("  -n#	   #: number of busy threads\n");
96*49cdfc7eSAndroid Build Coastguard Worker }
97*49cdfc7eSAndroid Build Coastguard Worker 
parse_args(int c,char * v)98*49cdfc7eSAndroid Build Coastguard Worker int parse_args(int c, char *v)
99*49cdfc7eSAndroid Build Coastguard Worker {
100*49cdfc7eSAndroid Build Coastguard Worker 
101*49cdfc7eSAndroid Build Coastguard Worker 	int handled = 1;
102*49cdfc7eSAndroid Build Coastguard Worker 	switch (c) {
103*49cdfc7eSAndroid Build Coastguard Worker 	case 'h':
104*49cdfc7eSAndroid Build Coastguard Worker 		usage();
105*49cdfc7eSAndroid Build Coastguard Worker 		exit(0);
106*49cdfc7eSAndroid Build Coastguard Worker 	case 'i':
107*49cdfc7eSAndroid Build Coastguard Worker 		int_threads = 1;
108*49cdfc7eSAndroid Build Coastguard Worker 		break;
109*49cdfc7eSAndroid Build Coastguard Worker 	case 'n':
110*49cdfc7eSAndroid Build Coastguard Worker 		rt_threads = atoi(v);
111*49cdfc7eSAndroid Build Coastguard Worker 		break;
112*49cdfc7eSAndroid Build Coastguard Worker 	default:
113*49cdfc7eSAndroid Build Coastguard Worker 		handled = 0;
114*49cdfc7eSAndroid Build Coastguard Worker 		break;
115*49cdfc7eSAndroid Build Coastguard Worker 	}
116*49cdfc7eSAndroid Build Coastguard Worker 	return handled;
117*49cdfc7eSAndroid Build Coastguard Worker }
118*49cdfc7eSAndroid Build Coastguard Worker 
int_thread(void * arg)119*49cdfc7eSAndroid Build Coastguard Worker void *int_thread(void *arg)
120*49cdfc7eSAndroid Build Coastguard Worker {
121*49cdfc7eSAndroid Build Coastguard Worker 	intptr_t a = 0;
122*49cdfc7eSAndroid Build Coastguard Worker 	while (!test_over) {
123*49cdfc7eSAndroid Build Coastguard Worker 		/* do some busy work */
124*49cdfc7eSAndroid Build Coastguard Worker 		if (!(a % 4))
125*49cdfc7eSAndroid Build Coastguard Worker 			a = a * 3;
126*49cdfc7eSAndroid Build Coastguard Worker 		else if (!(a % 6))
127*49cdfc7eSAndroid Build Coastguard Worker 			a = a / 2;
128*49cdfc7eSAndroid Build Coastguard Worker 		else
129*49cdfc7eSAndroid Build Coastguard Worker 			a++;
130*49cdfc7eSAndroid Build Coastguard Worker 		usleep(20);
131*49cdfc7eSAndroid Build Coastguard Worker 	}
132*49cdfc7eSAndroid Build Coastguard Worker 	return (void *)a;
133*49cdfc7eSAndroid Build Coastguard Worker }
134*49cdfc7eSAndroid Build Coastguard Worker 
busy_thread(void * arg)135*49cdfc7eSAndroid Build Coastguard Worker void *busy_thread(void *arg)
136*49cdfc7eSAndroid Build Coastguard Worker {
137*49cdfc7eSAndroid Build Coastguard Worker 	struct sched_param sched_param;
138*49cdfc7eSAndroid Build Coastguard Worker 	int policy, mypri = 0, tid;
139*49cdfc7eSAndroid Build Coastguard Worker 	tid = (intptr_t) (((struct thread *)arg)->arg);
140*49cdfc7eSAndroid Build Coastguard Worker 
141*49cdfc7eSAndroid Build Coastguard Worker 	if (pthread_getschedparam(pthread_self(), &policy, &sched_param) != 0) {
142*49cdfc7eSAndroid Build Coastguard Worker 		printf("ERR: Couldn't get pthread info \n");
143*49cdfc7eSAndroid Build Coastguard Worker 	} else {
144*49cdfc7eSAndroid Build Coastguard Worker 		mypri = sched_param.sched_priority;
145*49cdfc7eSAndroid Build Coastguard Worker 	}
146*49cdfc7eSAndroid Build Coastguard Worker 
147*49cdfc7eSAndroid Build Coastguard Worker 	pthread_mutex_lock(&bmutex);
148*49cdfc7eSAndroid Build Coastguard Worker 	busy_threads++;
149*49cdfc7eSAndroid Build Coastguard Worker 	printf("Busy Thread %d(%d): Running...\n", tid, mypri);
150*49cdfc7eSAndroid Build Coastguard Worker 	pthread_mutex_unlock(&bmutex);
151*49cdfc7eSAndroid Build Coastguard Worker 
152*49cdfc7eSAndroid Build Coastguard Worker 	/* TODO: Add sched set affinity here */
153*49cdfc7eSAndroid Build Coastguard Worker 
154*49cdfc7eSAndroid Build Coastguard Worker 	/* Busy loop */
155*49cdfc7eSAndroid Build Coastguard Worker 	while (!test_over) ;
156*49cdfc7eSAndroid Build Coastguard Worker 
157*49cdfc7eSAndroid Build Coastguard Worker 	printf("Busy Thread %d(%d): Exiting\n", tid, mypri);
158*49cdfc7eSAndroid Build Coastguard Worker 	return NULL;
159*49cdfc7eSAndroid Build Coastguard Worker }
160*49cdfc7eSAndroid Build Coastguard Worker 
worker_thread(void * arg)161*49cdfc7eSAndroid Build Coastguard Worker void *worker_thread(void *arg)
162*49cdfc7eSAndroid Build Coastguard Worker {
163*49cdfc7eSAndroid Build Coastguard Worker 	struct sched_param sched_param;
164*49cdfc7eSAndroid Build Coastguard Worker 	int policy, rc, mypri = 0, tid, times = 0;
165*49cdfc7eSAndroid Build Coastguard Worker 	tid = (intptr_t) (((struct thread *)arg)->arg);
166*49cdfc7eSAndroid Build Coastguard Worker 	nsec_t pstart, pend;
167*49cdfc7eSAndroid Build Coastguard Worker 
168*49cdfc7eSAndroid Build Coastguard Worker 	if (pthread_getschedparam(pthread_self(), &policy, &sched_param) != 0) {
169*49cdfc7eSAndroid Build Coastguard Worker 		printf("ERR: Couldn't get pthread info \n");
170*49cdfc7eSAndroid Build Coastguard Worker 	} else {
171*49cdfc7eSAndroid Build Coastguard Worker 		mypri = sched_param.sched_priority;
172*49cdfc7eSAndroid Build Coastguard Worker 	}
173*49cdfc7eSAndroid Build Coastguard Worker 	/* check in */
174*49cdfc7eSAndroid Build Coastguard Worker 	pthread_mutex_lock(&bmutex);
175*49cdfc7eSAndroid Build Coastguard Worker 	threads_running++;
176*49cdfc7eSAndroid Build Coastguard Worker 	pthread_mutex_unlock(&bmutex);
177*49cdfc7eSAndroid Build Coastguard Worker 
178*49cdfc7eSAndroid Build Coastguard Worker 	/* block */
179*49cdfc7eSAndroid Build Coastguard Worker 	rc = pthread_mutex_lock(&mutex[tid]);
180*49cdfc7eSAndroid Build Coastguard Worker 	if (tid == 0)
181*49cdfc7eSAndroid Build Coastguard Worker 		pthread_barrier_wait(&barrier);
182*49cdfc7eSAndroid Build Coastguard Worker 	rc = pthread_cond_wait(&cond[tid], &mutex[tid]);
183*49cdfc7eSAndroid Build Coastguard Worker 	rc = pthread_mutex_unlock(&mutex[tid]);
184*49cdfc7eSAndroid Build Coastguard Worker 
185*49cdfc7eSAndroid Build Coastguard Worker 	debug(DBG_INFO, "%llu: Thread %d(%d) wakes up from sleep \n",
186*49cdfc7eSAndroid Build Coastguard Worker 	      rt_gettime(), tid, mypri);
187*49cdfc7eSAndroid Build Coastguard Worker 
188*49cdfc7eSAndroid Build Coastguard Worker 	/*check if we're the last thread */
189*49cdfc7eSAndroid Build Coastguard Worker 	if (tid == NUM_WORKERS - 1) {
190*49cdfc7eSAndroid Build Coastguard Worker 		t_after_wait[tid] = 1;
191*49cdfc7eSAndroid Build Coastguard Worker 		pthread_mutex_lock(&bmutex);
192*49cdfc7eSAndroid Build Coastguard Worker 		threads_running--;
193*49cdfc7eSAndroid Build Coastguard Worker 		pthread_mutex_unlock(&bmutex);
194*49cdfc7eSAndroid Build Coastguard Worker 		return NULL;
195*49cdfc7eSAndroid Build Coastguard Worker 	}
196*49cdfc7eSAndroid Build Coastguard Worker 
197*49cdfc7eSAndroid Build Coastguard Worker 	/* Signal next thread */
198*49cdfc7eSAndroid Build Coastguard Worker 	rc = pthread_mutex_lock(&mutex[tid + 1]);
199*49cdfc7eSAndroid Build Coastguard Worker 	rc = pthread_cond_signal(&cond[tid + 1]);
200*49cdfc7eSAndroid Build Coastguard Worker 	debug(DBG_INFO, "%llu: Thread %d(%d): Sent signal (%d) to (%d)\n",
201*49cdfc7eSAndroid Build Coastguard Worker 	      rt_gettime(), tid, mypri, rc, tid + 1);
202*49cdfc7eSAndroid Build Coastguard Worker 
203*49cdfc7eSAndroid Build Coastguard Worker 	pstart = pend = rt_gettime();
204*49cdfc7eSAndroid Build Coastguard Worker 	rc = pthread_mutex_unlock(&mutex[tid + 1]);
205*49cdfc7eSAndroid Build Coastguard Worker 
206*49cdfc7eSAndroid Build Coastguard Worker 	debug(DBG_INFO, "%llu: Thread %d(%d) setting it's bit \n", rt_gettime(),
207*49cdfc7eSAndroid Build Coastguard Worker 	      tid, mypri);
208*49cdfc7eSAndroid Build Coastguard Worker 
209*49cdfc7eSAndroid Build Coastguard Worker 	t_after_wait[tid] = 1;
210*49cdfc7eSAndroid Build Coastguard Worker 
211*49cdfc7eSAndroid Build Coastguard Worker 	while (t_after_wait[tid + 1] != 1) {
212*49cdfc7eSAndroid Build Coastguard Worker 		pend = rt_gettime();
213*49cdfc7eSAndroid Build Coastguard Worker 		times++;
214*49cdfc7eSAndroid Build Coastguard Worker 	}
215*49cdfc7eSAndroid Build Coastguard Worker 
216*49cdfc7eSAndroid Build Coastguard Worker 	if (times >= (int)pass_criteria) {
217*49cdfc7eSAndroid Build Coastguard Worker 		printf
218*49cdfc7eSAndroid Build Coastguard Worker 		    ("Thread %d(%d): Non-Preempt limit reached. %llu ns latency\n",
219*49cdfc7eSAndroid Build Coastguard Worker 		     tid, mypri, pend - pstart);
220*49cdfc7eSAndroid Build Coastguard Worker 		ret = 1;
221*49cdfc7eSAndroid Build Coastguard Worker 	}
222*49cdfc7eSAndroid Build Coastguard Worker 
223*49cdfc7eSAndroid Build Coastguard Worker 	/* check out */
224*49cdfc7eSAndroid Build Coastguard Worker 	pthread_mutex_lock(&bmutex);
225*49cdfc7eSAndroid Build Coastguard Worker 	threads_running--;
226*49cdfc7eSAndroid Build Coastguard Worker 	pthread_mutex_unlock(&bmutex);
227*49cdfc7eSAndroid Build Coastguard Worker 
228*49cdfc7eSAndroid Build Coastguard Worker 	return NULL;
229*49cdfc7eSAndroid Build Coastguard Worker }
230*49cdfc7eSAndroid Build Coastguard Worker 
master_thread(void * arg)231*49cdfc7eSAndroid Build Coastguard Worker void *master_thread(void *arg)
232*49cdfc7eSAndroid Build Coastguard Worker {
233*49cdfc7eSAndroid Build Coastguard Worker 	int i, pri_boost;
234*49cdfc7eSAndroid Build Coastguard Worker 
235*49cdfc7eSAndroid Build Coastguard Worker 	pthread_barrier_init(&barrier, NULL, 2);
236*49cdfc7eSAndroid Build Coastguard Worker 
237*49cdfc7eSAndroid Build Coastguard Worker 	/* start interrupter thread */
238*49cdfc7eSAndroid Build Coastguard Worker 	if (int_threads) {
239*49cdfc7eSAndroid Build Coastguard Worker 		pri_boost = 90;
240*49cdfc7eSAndroid Build Coastguard Worker 		for (i = 0; i < rt_threads; i++) {
241*49cdfc7eSAndroid Build Coastguard Worker 			create_fifo_thread(int_thread, NULL,
242*49cdfc7eSAndroid Build Coastguard Worker 					   sched_get_priority_min(SCHED_FIFO) +
243*49cdfc7eSAndroid Build Coastguard Worker 					   pri_boost);
244*49cdfc7eSAndroid Build Coastguard Worker 		}
245*49cdfc7eSAndroid Build Coastguard Worker 	}
246*49cdfc7eSAndroid Build Coastguard Worker 
247*49cdfc7eSAndroid Build Coastguard Worker 	/* start the (N-1) busy threads */
248*49cdfc7eSAndroid Build Coastguard Worker 	pri_boost = 80;
249*49cdfc7eSAndroid Build Coastguard Worker 	for (i = rt_threads; i > 1; i--) {
250*49cdfc7eSAndroid Build Coastguard Worker 		create_fifo_thread(busy_thread, (void *)(intptr_t) i,
251*49cdfc7eSAndroid Build Coastguard Worker 				   sched_get_priority_min(SCHED_FIFO) +
252*49cdfc7eSAndroid Build Coastguard Worker 				   pri_boost);
253*49cdfc7eSAndroid Build Coastguard Worker 	}
254*49cdfc7eSAndroid Build Coastguard Worker 
255*49cdfc7eSAndroid Build Coastguard Worker 	/* make sure children are started */
256*49cdfc7eSAndroid Build Coastguard Worker 	while (busy_threads < (rt_threads - 1))
257*49cdfc7eSAndroid Build Coastguard Worker 		usleep(100);
258*49cdfc7eSAndroid Build Coastguard Worker 
259*49cdfc7eSAndroid Build Coastguard Worker 	printf("Busy threads created!\n");
260*49cdfc7eSAndroid Build Coastguard Worker 
261*49cdfc7eSAndroid Build Coastguard Worker 	/* start NUM_WORKERS worker threads */
262*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0, pri_boost = 10; i < NUM_WORKERS; i++, pri_boost += 2) {
263*49cdfc7eSAndroid Build Coastguard Worker 		pthread_mutex_init(&mutex[i], NULL);
264*49cdfc7eSAndroid Build Coastguard Worker 		pthread_cond_init(&cond[i], NULL);
265*49cdfc7eSAndroid Build Coastguard Worker 		create_fifo_thread(worker_thread, (void *)(intptr_t) i,
266*49cdfc7eSAndroid Build Coastguard Worker 				   sched_get_priority_min(SCHED_FIFO) +
267*49cdfc7eSAndroid Build Coastguard Worker 				   pri_boost);
268*49cdfc7eSAndroid Build Coastguard Worker 	}
269*49cdfc7eSAndroid Build Coastguard Worker 
270*49cdfc7eSAndroid Build Coastguard Worker 	printf("Worker threads created\n");
271*49cdfc7eSAndroid Build Coastguard Worker 	/* Let the worker threads wait on the cond vars */
272*49cdfc7eSAndroid Build Coastguard Worker 	while (threads_running < NUM_WORKERS)
273*49cdfc7eSAndroid Build Coastguard Worker 		usleep(100);
274*49cdfc7eSAndroid Build Coastguard Worker 
275*49cdfc7eSAndroid Build Coastguard Worker 	/* Ensure the first worker has called cond_wait */
276*49cdfc7eSAndroid Build Coastguard Worker 	pthread_barrier_wait(&barrier);
277*49cdfc7eSAndroid Build Coastguard Worker 
278*49cdfc7eSAndroid Build Coastguard Worker 	printf("Signaling first thread\n");
279*49cdfc7eSAndroid Build Coastguard Worker 	pthread_mutex_lock(&mutex[0]);
280*49cdfc7eSAndroid Build Coastguard Worker 	pthread_cond_signal(&cond[0]);
281*49cdfc7eSAndroid Build Coastguard Worker 	pthread_mutex_unlock(&mutex[0]);
282*49cdfc7eSAndroid Build Coastguard Worker 
283*49cdfc7eSAndroid Build Coastguard Worker 	while (threads_running)
284*49cdfc7eSAndroid Build Coastguard Worker 		usleep(500000);	/* this period greatly affects the number of failures! */
285*49cdfc7eSAndroid Build Coastguard Worker 
286*49cdfc7eSAndroid Build Coastguard Worker 	test_over = 1;
287*49cdfc7eSAndroid Build Coastguard Worker 	return NULL;
288*49cdfc7eSAndroid Build Coastguard Worker }
289*49cdfc7eSAndroid Build Coastguard Worker 
main(int argc,char * argv[])290*49cdfc7eSAndroid Build Coastguard Worker int main(int argc, char *argv[])
291*49cdfc7eSAndroid Build Coastguard Worker {
292*49cdfc7eSAndroid Build Coastguard Worker 	int pri_boost, numcpus;
293*49cdfc7eSAndroid Build Coastguard Worker 	setup();
294*49cdfc7eSAndroid Build Coastguard Worker 
295*49cdfc7eSAndroid Build Coastguard Worker 	pass_criteria = CHECK_LIMIT;
296*49cdfc7eSAndroid Build Coastguard Worker 	rt_init("hin:", parse_args, argc, argv);
297*49cdfc7eSAndroid Build Coastguard Worker 
298*49cdfc7eSAndroid Build Coastguard Worker 	numcpus = sysconf(_SC_NPROCESSORS_ONLN);
299*49cdfc7eSAndroid Build Coastguard Worker 
300*49cdfc7eSAndroid Build Coastguard Worker 	/* Max no. of busy threads should always be less than/equal the no. of cpus
301*49cdfc7eSAndroid Build Coastguard Worker 	   Otherwise, the box will hang */
302*49cdfc7eSAndroid Build Coastguard Worker 
303*49cdfc7eSAndroid Build Coastguard Worker 	if (rt_threads == -1 || rt_threads > numcpus) {
304*49cdfc7eSAndroid Build Coastguard Worker 		rt_threads = numcpus;
305*49cdfc7eSAndroid Build Coastguard Worker 		printf("Maximum busy thread count(%d), "
306*49cdfc7eSAndroid Build Coastguard Worker 		       "should not exceed number of cpus(%d)\n", rt_threads,
307*49cdfc7eSAndroid Build Coastguard Worker 		       numcpus);
308*49cdfc7eSAndroid Build Coastguard Worker 		printf("Using %d\n", numcpus);
309*49cdfc7eSAndroid Build Coastguard Worker 	}
310*49cdfc7eSAndroid Build Coastguard Worker 
311*49cdfc7eSAndroid Build Coastguard Worker 	/* Test boilder plate: title and parameters */
312*49cdfc7eSAndroid Build Coastguard Worker 	printf("\n-------------------\n");
313*49cdfc7eSAndroid Build Coastguard Worker 	printf("Priority Preemption\n");
314*49cdfc7eSAndroid Build Coastguard Worker 	printf("-------------------\n\n");
315*49cdfc7eSAndroid Build Coastguard Worker 	printf("Busy Threads: %d\n", rt_threads);
316*49cdfc7eSAndroid Build Coastguard Worker 	printf("Interrupter Threads: %s\n",
317*49cdfc7eSAndroid Build Coastguard Worker 	       int_threads ? "Enabled" : "Disabled");
318*49cdfc7eSAndroid Build Coastguard Worker 	printf("Worker Threads: %d\n\n", NUM_WORKERS);
319*49cdfc7eSAndroid Build Coastguard Worker 
320*49cdfc7eSAndroid Build Coastguard Worker 	pri_boost = 81;
321*49cdfc7eSAndroid Build Coastguard Worker 	create_fifo_thread(master_thread, NULL,
322*49cdfc7eSAndroid Build Coastguard Worker 			   sched_get_priority_min(SCHED_FIFO) + pri_boost);
323*49cdfc7eSAndroid Build Coastguard Worker 
324*49cdfc7eSAndroid Build Coastguard Worker 	/* wait for threads to complete */
325*49cdfc7eSAndroid Build Coastguard Worker 	join_threads();
326*49cdfc7eSAndroid Build Coastguard Worker 
327*49cdfc7eSAndroid Build Coastguard Worker 	printf
328*49cdfc7eSAndroid Build Coastguard Worker 	    ("\nCriteria: All threads appropriately preempted within %d loop(s)\n",
329*49cdfc7eSAndroid Build Coastguard Worker 	     (int)pass_criteria);
330*49cdfc7eSAndroid Build Coastguard Worker 	printf("Result: %s\n", ret ? "FAIL" : "PASS");
331*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
332*49cdfc7eSAndroid Build Coastguard Worker }
333