10dc076565f772bb1953209fb69ea150b494aaa40robbiew
20dc076565f772bb1953209fb69ea150b494aaa40robbiew/*
30dc076565f772bb1953209fb69ea150b494aaa40robbiew *  Copyright (c) 2003, Intel Corporation. All rights reserved.
40dc076565f772bb1953209fb69ea150b494aaa40robbiew *  Created by:  crystal.xiong REMOVE-THIS AT intel DOT com
50dc076565f772bb1953209fb69ea150b494aaa40robbiew *  This file is licensed under the GPL license.  For the full content
60dc076565f772bb1953209fb69ea150b494aaa40robbiew *  of this license, see the COPYING file at the top level of this
70dc076565f772bb1953209fb69ea150b494aaa40robbiew *  source tree.
80dc076565f772bb1953209fb69ea150b494aaa40robbiew */
90dc076565f772bb1953209fb69ea150b494aaa40robbiew
100dc076565f772bb1953209fb69ea150b494aaa40robbiew/* There are n TF threads, n is equal to the processors in the system minus
112c28215423293e443469a07ae7011135d058b671Garrett Cooper * one. TFs are used to keep busy these CPUs, which have priority 3. A
122c28215423293e443469a07ae7011135d058b671Garrett Cooper * TL thread with lower priority 1 is created, which locks a mutex and
130dc076565f772bb1953209fb69ea150b494aaa40robbiew * does workload. A TB thread with higher priority 4 is created and try
140dc076565f772bb1953209fb69ea150b494aaa40robbiew * to lock TL's mutex. A TP thread with priority 2 is created to reflect the
152c28215423293e443469a07ae7011135d058b671Garrett Cooper * priority change of TL. Main thread has the highest priority 6, which will
162c28215423293e443469a07ae7011135d058b671Garrett Cooper * control the running steps of those threads, including creating threads,
170dc076565f772bb1953209fb69ea150b494aaa40robbiew * stopping threads. There is another thread to collect the sample data with
180dc076565f772bb1953209fb69ea150b494aaa40robbiew * priority 5.
192c28215423293e443469a07ae7011135d058b671Garrett Cooper *
200dc076565f772bb1953209fb69ea150b494aaa40robbiew * Steps:
212c28215423293e443469a07ae7011135d058b671Garrett Cooper * 1.	Create n TF threads, n is equal to processors number minus one. TF
220dc076565f772bb1953209fb69ea150b494aaa40robbiew * 	will do workload.
232c28215423293e443469a07ae7011135d058b671Garrett Cooper * 2.	Create 1 TP thread and do workload. The thread will keep running when
242c28215423293e443469a07ae7011135d058b671Garrett Cooper * 	TL is created.
252c28215423293e443469a07ae7011135d058b671Garrett Cooper * 3.	Create 1 TL thread to lock a mutex. TL will get a chance to run
260dc076565f772bb1953209fb69ea150b494aaa40robbiew *      when TP sleep a wee bit in between.
272c28215423293e443469a07ae7011135d058b671Garrett Cooper * 4.	Create 1 TB thread to lock the mutex. TL's priority will boost to
280dc076565f772bb1953209fb69ea150b494aaa40robbiew *  	TB's priority, which will cause TP having no chance to run.
292c28215423293e443469a07ae7011135d058b671Garrett Cooper * 5.	Set TB's prioirty to 1, TL's priority will decrease. So TP and TL
300dc076565f772bb1953209fb69ea150b494aaa40robbiew * 	will keep working as before.
310dc076565f772bb1953209fb69ea150b494aaa40robbiew * 6.	Stop these threads.
322c28215423293e443469a07ae7011135d058b671Garrett Cooper *
330dc076565f772bb1953209fb69ea150b494aaa40robbiew * NOTE: Most of the code is ported from test-11 written by inkay.
340dc076565f772bb1953209fb69ea150b494aaa40robbiew */
350dc076565f772bb1953209fb69ea150b494aaa40robbiew
368d785b4e9eda424552e5bd87883826c615c10f8dGarrett Cooper#warning "Contains Linux-isms that need fixing."
378d785b4e9eda424552e5bd87883826c615c10f8dGarrett Cooper
388d785b4e9eda424552e5bd87883826c615c10f8dGarrett Cooper#include <errno.h>
390dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <pthread.h>
408d785b4e9eda424552e5bd87883826c615c10f8dGarrett Cooper#include <sched.h>
410dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <stdio.h>
420dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <stdlib.h>
438d785b4e9eda424552e5bd87883826c615c10f8dGarrett Cooper#include <string.h>
440dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <time.h>
458d785b4e9eda424552e5bd87883826c615c10f8dGarrett Cooper#include <unistd.h>
460dc076565f772bb1953209fb69ea150b494aaa40robbiew#include "test.h"
470dc076565f772bb1953209fb69ea150b494aaa40robbiew#include "pitest.h"
480dc076565f772bb1953209fb69ea150b494aaa40robbiew
490dc076565f772bb1953209fb69ea150b494aaa40robbiewint cpus;
500dc076565f772bb1953209fb69ea150b494aaa40robbiewpthread_mutex_t mutex;
510dc076565f772bb1953209fb69ea150b494aaa40robbiewvolatile int ts_stop = 0;
520dc076565f772bb1953209fb69ea150b494aaa40robbiewvolatile double base_time;
530dc076565f772bb1953209fb69ea150b494aaa40robbiew
54354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostruct thread_param {
550dc076565f772bb1953209fb69ea150b494aaa40robbiew	int index;
560dc076565f772bb1953209fb69ea150b494aaa40robbiew	volatile int stop;
570dc076565f772bb1953209fb69ea150b494aaa40robbiew	int sleep_ms;
580dc076565f772bb1953209fb69ea150b494aaa40robbiew	int priority;
590dc076565f772bb1953209fb69ea150b494aaa40robbiew	int policy;
600dc076565f772bb1953209fb69ea150b494aaa40robbiew	const char *name;
610dc076565f772bb1953209fb69ea150b494aaa40robbiew	int cpu;
620dc076565f772bb1953209fb69ea150b494aaa40robbiew	volatile unsigned futex;
630dc076565f772bb1953209fb69ea150b494aaa40robbiew	volatile unsigned should_stall;
640dc076565f772bb1953209fb69ea150b494aaa40robbiew	volatile unsigned progress;
658d785b4e9eda424552e5bd87883826c615c10f8dGarrett Cooper} tp[] = {
66354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	{
67354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	0, 0, 0, 1, SCHED_FIFO, "TL", 0, 0, 0, 0}, {
68354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	1, 0, 200, 2, SCHED_FIFO, "TP", 0, 0, 0, 0}, {
69354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	2, 0, 0, 3, SCHED_FIFO, "TF", 1, 0, 0, 0}, {
70354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	3, 0, 0, 3, SCHED_FIFO, "TF", 2, 0, 0, 0}, {
71354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	4, 0, 0, 3, SCHED_FIFO, "TF", 3, 0, 0, 0}, {
72354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	5, 0, 0, 3, SCHED_FIFO, "TF", 4, 0, 0, 0}, {
73354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	6, 0, 0, 3, SCHED_FIFO, "TF", 5, 0, 0, 0}, {
74354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	7, 0, 0, 3, SCHED_FIFO, "TF", 6, 0, 0, 0}
750dc076565f772bb1953209fb69ea150b494aaa40robbiew};
760dc076565f772bb1953209fb69ea150b494aaa40robbiew
770dc076565f772bb1953209fb69ea150b494aaa40robbiewvolatile unsigned do_work_dummy;
780dc076565f772bb1953209fb69ea150b494aaa40robbiewvoid do_work(unsigned granularity_top, volatile unsigned *progress)
790dc076565f772bb1953209fb69ea150b494aaa40robbiew{
800dc076565f772bb1953209fb69ea150b494aaa40robbiew	unsigned granularity_cnt, i;
810dc076565f772bb1953209fb69ea150b494aaa40robbiew	unsigned top = 5 * 1000 * 1000;
820dc076565f772bb1953209fb69ea150b494aaa40robbiew	unsigned dummy = do_work_dummy;
832c28215423293e443469a07ae7011135d058b671Garrett Cooper
842c28215423293e443469a07ae7011135d058b671Garrett Cooper	for (granularity_cnt = 0; granularity_cnt < granularity_top;
85354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	     granularity_cnt++) {
862c28215423293e443469a07ae7011135d058b671Garrett Cooper		for (i = 0; i < top; i++)
870dc076565f772bb1953209fb69ea150b494aaa40robbiew			dummy = i | dummy;
880dc076565f772bb1953209fb69ea150b494aaa40robbiew		(*progress)++;
890dc076565f772bb1953209fb69ea150b494aaa40robbiew	}
900dc076565f772bb1953209fb69ea150b494aaa40robbiew	return;
910dc076565f772bb1953209fb69ea150b494aaa40robbiew}
92354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
930dc076565f772bb1953209fb69ea150b494aaa40robbiewvoid *thread_fn(void *param)
940dc076565f772bb1953209fb69ea150b494aaa40robbiew{
950dc076565f772bb1953209fb69ea150b494aaa40robbiew	struct thread_param *tp = param;
960dc076565f772bb1953209fb69ea150b494aaa40robbiew	struct timespec ts;
970dc076565f772bb1953209fb69ea150b494aaa40robbiew	int rc;
980dc076565f772bb1953209fb69ea150b494aaa40robbiew	unsigned long mask = 1 << tp->cpu;
990dc076565f772bb1953209fb69ea150b494aaa40robbiew
1008d785b4e9eda424552e5bd87883826c615c10f8dGarrett Cooper#if __linux__
1010dc076565f772bb1953209fb69ea150b494aaa40robbiew	rc = sched_setaffinity(0, sizeof(mask), &mask);
1020dc076565f772bb1953209fb69ea150b494aaa40robbiew	if (rc < 0) {
1030dc076565f772bb1953209fb69ea150b494aaa40robbiew		EPRINTF("UNRESOLVED: Thread %s index %d: Can't set affinity: "
1040dc076565f772bb1953209fb69ea150b494aaa40robbiew			"%d %s", tp->name, tp->index, rc, strerror(rc));
1050dc076565f772bb1953209fb69ea150b494aaa40robbiew		exit(UNRESOLVED);
1060dc076565f772bb1953209fb69ea150b494aaa40robbiew	}
1078d785b4e9eda424552e5bd87883826c615c10f8dGarrett Cooper#endif
1080dc076565f772bb1953209fb69ea150b494aaa40robbiew	test_set_priority(pthread_self(), SCHED_FIFO, tp->priority);
109354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	DPRINTF(stderr, "Thread %s index %d: started\n", tp->name, tp->index);
1102c28215423293e443469a07ae7011135d058b671Garrett Cooper	DPRINTF(stdout, "#EVENT %f Thread %s Started\n",
1110dc076565f772bb1953209fb69ea150b494aaa40robbiew		seconds_read() - base_time, tp->name);
1122c28215423293e443469a07ae7011135d058b671Garrett Cooper
1130dc076565f772bb1953209fb69ea150b494aaa40robbiew	tp->progress = 0;
1140dc076565f772bb1953209fb69ea150b494aaa40robbiew	ts.tv_sec = 0;
1150dc076565f772bb1953209fb69ea150b494aaa40robbiew	ts.tv_nsec = tp->sleep_ms * 1000 * 1000;
116354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	while (!tp->stop) {
1170dc076565f772bb1953209fb69ea150b494aaa40robbiew		do_work(5, &tp->progress);
1180dc076565f772bb1953209fb69ea150b494aaa40robbiew		if (tp->sleep_ms == 0)
1190dc076565f772bb1953209fb69ea150b494aaa40robbiew			continue;
1200dc076565f772bb1953209fb69ea150b494aaa40robbiew		rc = nanosleep(&ts, NULL);
1210dc076565f772bb1953209fb69ea150b494aaa40robbiew		if (rc < 0) {
1220dc076565f772bb1953209fb69ea150b494aaa40robbiew			EPRINTF("UNRESOLVED: Thread %s %d: nanosleep returned "
1230dc076565f772bb1953209fb69ea150b494aaa40robbiew				"%d %s", tp->name, tp->index, rc, strerror(rc));
1240dc076565f772bb1953209fb69ea150b494aaa40robbiew			exit(UNRESOLVED);
1250dc076565f772bb1953209fb69ea150b494aaa40robbiew		}
1260dc076565f772bb1953209fb69ea150b494aaa40robbiew	}
1272c28215423293e443469a07ae7011135d058b671Garrett Cooper
1282c28215423293e443469a07ae7011135d058b671Garrett Cooper	DPRINTF(stdout, "#EVENT %f Thread %s Started\n",
1290dc076565f772bb1953209fb69ea150b494aaa40robbiew		seconds_read() - base_time, tp->name);
1300dc076565f772bb1953209fb69ea150b494aaa40robbiew	return NULL;
1310dc076565f772bb1953209fb69ea150b494aaa40robbiew}
132354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
1330dc076565f772bb1953209fb69ea150b494aaa40robbiewvoid *thread_tl(void *param)
1340dc076565f772bb1953209fb69ea150b494aaa40robbiew{
1350dc076565f772bb1953209fb69ea150b494aaa40robbiew	struct thread_param *tp = param;
1360dc076565f772bb1953209fb69ea150b494aaa40robbiew	unsigned long mask = 1 << tp->cpu;
1370dc076565f772bb1953209fb69ea150b494aaa40robbiew	int rc;
1380dc076565f772bb1953209fb69ea150b494aaa40robbiew
1398d785b4e9eda424552e5bd87883826c615c10f8dGarrett Cooper#if __linux__
140354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	rc = sched_setaffinity((pid_t) 0, sizeof(mask), &mask);
1410dc076565f772bb1953209fb69ea150b494aaa40robbiew	if (rc < 0) {
142354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		EPRINTF
143354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    ("UNRESOLVED: Thread %s index %d: Can't set affinity: %d %s",
144354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		     tp->name, tp->index, rc, strerror(rc));
1450dc076565f772bb1953209fb69ea150b494aaa40robbiew		exit(UNRESOLVED);
1460dc076565f772bb1953209fb69ea150b494aaa40robbiew	}
1478d785b4e9eda424552e5bd87883826c615c10f8dGarrett Cooper#endif
1488d785b4e9eda424552e5bd87883826c615c10f8dGarrett Cooper
1490dc076565f772bb1953209fb69ea150b494aaa40robbiew	test_set_priority(pthread_self(), SCHED_FIFO, tp->priority);
1502c28215423293e443469a07ae7011135d058b671Garrett Cooper
151354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	DPRINTF(stderr, "Thread %s index %d: started\n", tp->name, tp->index);
1522c28215423293e443469a07ae7011135d058b671Garrett Cooper	DPRINTF(stdout, "#EVENT %f Thread %s Started\n",
1530dc076565f772bb1953209fb69ea150b494aaa40robbiew		seconds_read() - base_time, tp->name);
1540dc076565f772bb1953209fb69ea150b494aaa40robbiew	tp->progress = 0;
1550dc076565f772bb1953209fb69ea150b494aaa40robbiew	pthread_mutex_lock(&mutex);
156354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	while (!tp->stop) {
1570dc076565f772bb1953209fb69ea150b494aaa40robbiew		do_work(5, &tp->progress);
1580dc076565f772bb1953209fb69ea150b494aaa40robbiew	}
1590dc076565f772bb1953209fb69ea150b494aaa40robbiew	pthread_mutex_unlock(&mutex);
1602c28215423293e443469a07ae7011135d058b671Garrett Cooper	DPRINTF(stdout, "#EVENT %f Thread %s Stopted\n",
1610dc076565f772bb1953209fb69ea150b494aaa40robbiew		seconds_read() - base_time, tp->name);
1620dc076565f772bb1953209fb69ea150b494aaa40robbiew	return NULL;
1630dc076565f772bb1953209fb69ea150b494aaa40robbiew}
1640dc076565f772bb1953209fb69ea150b494aaa40robbiew
1650dc076565f772bb1953209fb69ea150b494aaa40robbiewvoid *thread_sample(void *arg)
1660dc076565f772bb1953209fb69ea150b494aaa40robbiew{
1670dc076565f772bb1953209fb69ea150b494aaa40robbiew	char buffer[1024];
1680dc076565f772bb1953209fb69ea150b494aaa40robbiew	struct timespec ts;
1690dc076565f772bb1953209fb69ea150b494aaa40robbiew	double period = 250;
1700dc076565f772bb1953209fb69ea150b494aaa40robbiew	size_t size;
1710dc076565f772bb1953209fb69ea150b494aaa40robbiew	int i;
1720dc076565f772bb1953209fb69ea150b494aaa40robbiew	int rc;
1730dc076565f772bb1953209fb69ea150b494aaa40robbiew
1740dc076565f772bb1953209fb69ea150b494aaa40robbiew	test_set_priority(pthread_self(), SCHED_FIFO, 5);
175354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	DPRINTF(stderr, "Thread Sampler: started\n");
1760dc076565f772bb1953209fb69ea150b494aaa40robbiew	DPRINTF(stdout, "# COLUMNS %d Time TP TL ", 2 + cpus);
1770dc076565f772bb1953209fb69ea150b494aaa40robbiew	for (i = 0; i < (cpus - 1); i++)
1780dc076565f772bb1953209fb69ea150b494aaa40robbiew		DPRINTF(stdout, "TF%d ", i);
1790dc076565f772bb1953209fb69ea150b494aaa40robbiew	DPRINTF(stdout, "\n");
1800dc076565f772bb1953209fb69ea150b494aaa40robbiew	ts.tv_sec = 0;
1810dc076565f772bb1953209fb69ea150b494aaa40robbiew	ts.tv_nsec = period * 1000 * 1000;
1822c28215423293e443469a07ae7011135d058b671Garrett Cooper
183354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	while (!ts_stop) {
184354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		size =
185354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    snprintf(buffer, 1023, "%f ", seconds_read() - base_time);
1862c28215423293e443469a07ae7011135d058b671Garrett Cooper		for (i = 0; i < cpus + 1; i++)
187354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			size +=
188354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			    snprintf(buffer + size, 1023 - size, "%u ",
189354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				     tp[i].progress);
190354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		DPRINTF(stdout, "%s\n", buffer);
1910dc076565f772bb1953209fb69ea150b494aaa40robbiew		rc = nanosleep(&ts, NULL);
1920dc076565f772bb1953209fb69ea150b494aaa40robbiew		if (rc < 0)
1930dc076565f772bb1953209fb69ea150b494aaa40robbiew			EPRINTF("UNRESOLVED: Thread %s %d: nanosleep returned "
1940dc076565f772bb1953209fb69ea150b494aaa40robbiew				"%d %s", tp->name, tp->index, rc, strerror(rc));
1950dc076565f772bb1953209fb69ea150b494aaa40robbiew	}
1960dc076565f772bb1953209fb69ea150b494aaa40robbiew	return NULL;
1970dc076565f772bb1953209fb69ea150b494aaa40robbiew}
1980dc076565f772bb1953209fb69ea150b494aaa40robbiew
1990dc076565f772bb1953209fb69ea150b494aaa40robbiewvoid *thread_tb(void *arg)
2000dc076565f772bb1953209fb69ea150b494aaa40robbiew{
2010dc076565f772bb1953209fb69ea150b494aaa40robbiew	struct timespec boost_time;
2020dc076565f772bb1953209fb69ea150b494aaa40robbiew	double t0, t1;
2030dc076565f772bb1953209fb69ea150b494aaa40robbiew	int rc;
2040dc076565f772bb1953209fb69ea150b494aaa40robbiew
2050dc076565f772bb1953209fb69ea150b494aaa40robbiew	test_set_priority(pthread_self(), SCHED_FIFO, 4);
206354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	DPRINTF(stderr, "Thread TB: started\n");
2072c28215423293e443469a07ae7011135d058b671Garrett Cooper
2082c28215423293e443469a07ae7011135d058b671Garrett Cooper	DPRINTF(stdout, "#EVENT %f TB Started, waiting for mutex for %lu s\n",
209354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		seconds_read() - base_time, *(time_t *) arg);
2100dc076565f772bb1953209fb69ea150b494aaa40robbiew
211354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	boost_time.tv_sec = time(NULL) + *(time_t *) arg;
2120dc076565f772bb1953209fb69ea150b494aaa40robbiew	boost_time.tv_nsec = 0;
2130dc076565f772bb1953209fb69ea150b494aaa40robbiew
2140dc076565f772bb1953209fb69ea150b494aaa40robbiew	t0 = seconds_read();
2152c28215423293e443469a07ae7011135d058b671Garrett Cooper	rc = pthread_mutex_timedlock(&mutex, &boost_time);
2160dc076565f772bb1953209fb69ea150b494aaa40robbiew	t1 = seconds_read();
2172c28215423293e443469a07ae7011135d058b671Garrett Cooper	DPRINTF(stdout, "#EVENT %f TB Thread Waited for %.2f s\n",
2180dc076565f772bb1953209fb69ea150b494aaa40robbiew		seconds_read() - base_time, t1 - t0);
2192c28215423293e443469a07ae7011135d058b671Garrett Cooper
220df3eb16e38c6a163b0a7367c885679eed6140964Garrett Cooper	if (rc != ETIMEDOUT && rc != 0) {
2210dc076565f772bb1953209fb69ea150b494aaa40robbiew		EPRINTF("FAIL: Thread TB: lock returned %d %s, "
2220dc076565f772bb1953209fb69ea150b494aaa40robbiew			"slept %f", rc, strerror(rc), t1 - t0);
2230dc076565f772bb1953209fb69ea150b494aaa40robbiew		exit(FAIL);
2240dc076565f772bb1953209fb69ea150b494aaa40robbiew	}
2252c28215423293e443469a07ae7011135d058b671Garrett Cooper
226354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	DPRINTF(stdout, "#EVENT %f TB Stopped\n", seconds_read() - base_time);
2270dc076565f772bb1953209fb69ea150b494aaa40robbiew	return NULL;
2280dc076565f772bb1953209fb69ea150b494aaa40robbiew}
2290dc076565f772bb1953209fb69ea150b494aaa40robbiew
2300dc076565f772bb1953209fb69ea150b494aaa40robbiewint main(int argc, char **argv)
2310dc076565f772bb1953209fb69ea150b494aaa40robbiew{
2320dc076565f772bb1953209fb69ea150b494aaa40robbiew	cpus = sysconf(_SC_NPROCESSORS_ONLN);
2330dc076565f772bb1953209fb69ea150b494aaa40robbiew	pthread_mutexattr_t mutex_attr;
234354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	pthread_attr_t threadattr;
2350dc076565f772bb1953209fb69ea150b494aaa40robbiew	pthread_t threads[cpus - 1], threadsample, threadtp, threadtl, threadtb;
2360dc076565f772bb1953209fb69ea150b494aaa40robbiew
2375f2ba92bdbef089bad74906fd8a86b54617f7878Garrett Cooper	time_t multiplier = 1;
2380dc076565f772bb1953209fb69ea150b494aaa40robbiew	int i;
2390dc076565f772bb1953209fb69ea150b494aaa40robbiew	int rc;
2402c28215423293e443469a07ae7011135d058b671Garrett Cooper
2410dc076565f772bb1953209fb69ea150b494aaa40robbiew	test_set_priority(pthread_self(), SCHED_FIFO, 6);
2420dc076565f772bb1953209fb69ea150b494aaa40robbiew	base_time = seconds_read();
2430dc076565f772bb1953209fb69ea150b494aaa40robbiew
2440dc076565f772bb1953209fb69ea150b494aaa40robbiew	/* Initialize a mutex with PTHREAD_PRIO_INHERIT protocol */
2452c28215423293e443469a07ae7011135d058b671Garrett Cooper	mutex_attr_init(&mutex_attr);
2460dc076565f772bb1953209fb69ea150b494aaa40robbiew	mutex_init(&mutex, &mutex_attr);
2470dc076565f772bb1953209fb69ea150b494aaa40robbiew
2480dc076565f772bb1953209fb69ea150b494aaa40robbiew	/* Initialize thread attr */
2490dc076565f772bb1953209fb69ea150b494aaa40robbiew	threadattr_init(&threadattr);
2500dc076565f772bb1953209fb69ea150b494aaa40robbiew
2510dc076565f772bb1953209fb69ea150b494aaa40robbiew	/* Start the sample thread */
252354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	DPRINTF(stderr, "Main Thread: Creating sample thread\n");
2530dc076565f772bb1953209fb69ea150b494aaa40robbiew	rc = pthread_create(&threadsample, &threadattr, thread_sample, NULL);
254354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (rc != 0) {
255354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		EPRINTF("UNRESOLVED: pthread_create: %d %s", rc, strerror(rc));
256354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		exit(UNRESOLVED);
257354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
2580dc076565f772bb1953209fb69ea150b494aaa40robbiew
2590dc076565f772bb1953209fb69ea150b494aaa40robbiew	/* Start the TF threads */
260354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	DPRINTF(stderr, "Main Thread: Creating %d TF threads\n", cpus - 1);
261354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	for (i = 0; i < cpus - 1; i++) {
2622c28215423293e443469a07ae7011135d058b671Garrett Cooper		rc = pthread_create(&threads[i], &threadattr, thread_fn,
2630dc076565f772bb1953209fb69ea150b494aaa40robbiew				    &tp[i + 2]);
264354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (rc != 0) {
265354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			EPRINTF("UNRESOLVED: pthread_create: %d %s",
266354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				rc, strerror(rc));
267354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			exit(UNRESOLVED);
268354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		}
2690dc076565f772bb1953209fb69ea150b494aaa40robbiew	}
2700dc076565f772bb1953209fb69ea150b494aaa40robbiew
2710dc076565f772bb1953209fb69ea150b494aaa40robbiew	sleep(base_time + multiplier * 10 - seconds_read());
2720dc076565f772bb1953209fb69ea150b494aaa40robbiew
2730dc076565f772bb1953209fb69ea150b494aaa40robbiew	/* Start TP thread */
274354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	DPRINTF(stderr, "Main Thread: Creating TP thread\n");
2750dc076565f772bb1953209fb69ea150b494aaa40robbiew	rc = pthread_create(&threadtp, &threadattr, thread_fn, &tp[1]);
276354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (rc != 0) {
277354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		EPRINTF("UNRESOLVED: pthread_create: %d %s", rc, strerror(rc));
278354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		exit(UNRESOLVED);
279354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
2800dc076565f772bb1953209fb69ea150b494aaa40robbiew	sleep(base_time + multiplier * 20 - seconds_read());
2810dc076565f772bb1953209fb69ea150b494aaa40robbiew
2820dc076565f772bb1953209fb69ea150b494aaa40robbiew	/* Start TL thread */
283354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	DPRINTF(stderr, "Main Thread: Creating TL thread\n");
2840dc076565f772bb1953209fb69ea150b494aaa40robbiew	rc = pthread_create(&threadtl, &threadattr, thread_tl, &tp[0]);
285354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (rc != 0) {
286354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		EPRINTF("UNRESOLVED: pthread_create: %d %s", rc, strerror(rc));
287354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		exit(UNRESOLVED);
288354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
2890dc076565f772bb1953209fb69ea150b494aaa40robbiew	sleep(base_time + multiplier * 30 - seconds_read());
2900dc076565f772bb1953209fb69ea150b494aaa40robbiew
2910dc076565f772bb1953209fb69ea150b494aaa40robbiew	/* Start TB thread (boosting thread) */
2920dc076565f772bb1953209fb69ea150b494aaa40robbiew	unsigned long timeout = multiplier * 20;
293354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	rc = pthread_create(&threadtb, &threadattr, thread_tb, &timeout);
294354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (rc != 0) {
295354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		EPRINTF("UNRESOLVED: pthread_create: %d %s", rc, strerror(rc));
296354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		exit(UNRESOLVED);
297354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	}
2980dc076565f772bb1953209fb69ea150b494aaa40robbiew	sleep(base_time + multiplier * 40 - seconds_read());
2990dc076565f772bb1953209fb69ea150b494aaa40robbiew
3002c28215423293e443469a07ae7011135d058b671Garrett Cooper	/* Decrease TB's priority */
301354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	DPRINTF(stderr, "Main Thread: decrease TB's priority to 1\n");
3020dc076565f772bb1953209fb69ea150b494aaa40robbiew	test_set_priority(threadtb, SCHED_FIFO, 1);
3030dc076565f772bb1953209fb69ea150b494aaa40robbiew	DPRINTF(stdout, "#EVENT %f TB's priority decreased\n",
3040dc076565f772bb1953209fb69ea150b494aaa40robbiew		seconds_read() - base_time);
3050dc076565f772bb1953209fb69ea150b494aaa40robbiew	sleep(base_time + multiplier * 60 - seconds_read());
3060dc076565f772bb1953209fb69ea150b494aaa40robbiew
3070dc076565f772bb1953209fb69ea150b494aaa40robbiew	/* Stop TL thread */
3080dc076565f772bb1953209fb69ea150b494aaa40robbiew	tp[0].stop = 1;
3090dc076565f772bb1953209fb69ea150b494aaa40robbiew	sleep(base_time + multiplier * 70 - seconds_read());
3100dc076565f772bb1953209fb69ea150b494aaa40robbiew
3110dc076565f772bb1953209fb69ea150b494aaa40robbiew	/* Stop TP thread */
3120dc076565f772bb1953209fb69ea150b494aaa40robbiew	tp[1].stop = 1;
3130dc076565f772bb1953209fb69ea150b494aaa40robbiew	sleep(base_time + multiplier * 80 - seconds_read());
3140dc076565f772bb1953209fb69ea150b494aaa40robbiew
3150dc076565f772bb1953209fb69ea150b494aaa40robbiew	/* Stop TF threads */
316354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	for (i = 2; i < cpus - 1; i++) {
3170dc076565f772bb1953209fb69ea150b494aaa40robbiew		tp[i].stop = 1;
3180dc076565f772bb1953209fb69ea150b494aaa40robbiew	}
3190dc076565f772bb1953209fb69ea150b494aaa40robbiew
3200dc076565f772bb1953209fb69ea150b494aaa40robbiew	/* Stop sampler */
3210dc076565f772bb1953209fb69ea150b494aaa40robbiew	ts_stop = 1;
322354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	DPRINTF(stderr, "Main Thread: stop sampler thread\n");
32358c769b62e72818570fd719691f70121d7e0aa4bGarrett Cooper	return 0;
324ec6edca7aa42b6affd989ef91b5897f96795e40fChris Dearman}
325