Esempio n. 1
0
void *annoyer(void *d)
{
	int ret;
	struct timespec twait;
	struct sched_param param;
	cpu_set_t mask;
	pid_t my_pid = gettid();
	
	CPU_ZERO(&mask);
	CPU_SET(0, &mask);
	ret = sched_setaffinity(0, sizeof(mask), &mask);
	if (ret != 0) {
		printf("pthread_setaffinity failed\n"); 
		exit(EXIT_FAILURE);
	}
	
	param.sched_priority = 94;
	ret = pthread_setschedparam(pthread_self(), 
				    SCHED_FIFO, 
				    &param);
	if (ret != 0) {
		printf("pthread_setschedparam failed\n"); 
		exit(EXIT_FAILURE);
	}
	ftrace_write(marker_fd, "Starting annoyer(): pid %d prio 94\n", my_pid);

	ftrace_write(marker_fd, "annoyer(): should preempt inc_count for 5sec\n");

	twait = usec_to_timespec(5000000L);
	ftrace_write(marker_fd, "annoyer(): starts running...\n");
	busywait(&twait);

	ftrace_write(marker_fd, "annoyer(): dies...\n");
	pthread_exit(NULL);
}
Esempio n. 2
0
void *annoyer(void *d)
{
	int ret;
	long id = (long) d;
	struct timespec twait, now;
	struct sched_param param;
	cpu_set_t mask;
	pid_t my_pid = gettid();

	pids[id] = my_pid;
	

	if (global_args.affinity) {
		CPU_ZERO(&mask);
		CPU_SET(0, &mask);
		ret = sched_setaffinity(0, sizeof(mask), &mask);
		if (ret != 0) {
			printf("pthread_setaffinity failed\n"); 
			exit(EXIT_FAILURE);
		}
	}
	
	param.sched_priority = 93;
	ret = pthread_setschedparam(pthread_self(), 
				    SCHED_FIFO, 
				    &param);
	if (ret != 0) {
		printf("pthread_setschedparam failed\n"); 
		exit(EXIT_FAILURE);
	}

	/**
	 * Give other some time to warm up.
	 */
	sleep(2);

	if (global_args.ftrace)
		ftrace_write(marker_fd, "Starting annoyer(): prio 93\n");

	while(1) {
		/* 300ms */
		twait = usec_to_timespec(300000L);
		if (global_args.ftrace)
			ftrace_write(marker_fd,
				     "[annoyer %d] starts running...\n",
				     my_pid);
		clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now);
		twait = timespec_add(&now, &twait);
		busywait(&twait);
		if (global_args.ftrace)
			ftrace_write(marker_fd,
				     "[annoyer %d] sleeps.\n",
				     my_pid);
		sleep(1);
	}
	pthread_exit(NULL);
}
Esempio n. 3
0
void *helper(void *d) 
{
	int i, ret;
	struct timespec twait;
	struct sched_param param;
	cpu_set_t mask;
	pid_t my_pid = gettid();
	
	CPU_ZERO(&mask);
	CPU_SET(0, &mask);
	ret = sched_setaffinity(0, sizeof(mask), &mask);
	if (ret != 0) {
		printf("pthread_setaffinity failed\n"); 
		exit(EXIT_FAILURE);
	}

	param.sched_priority = 93;
	ret = pthread_setschedparam(pthread_self(), 
				    SCHED_FIFO, 
				    &param);
	if (ret != 0) {
		printf("pthread_setschedparam failed\n"); 
		exit(EXIT_FAILURE);
	}

	if (pi_cv_enabled) {
		ftrace_write(marker_fd, "Adding helper() thread: pid %d prio 93\n", my_pid);
		pthread_cond_helpers_add(&count_threshold_cv, my_pid);
		ftrace_write(marker_fd, "helper(): helps on cv %p\n", &count_threshold_cv);
	}

	sleep(1);
	ftrace_write(marker_fd, "Starting helper(): pid %d prio 93\n", my_pid);
	
	pthread_mutex_lock(&count_mutex);

	/* Do some work (e.g., fill up the queue) */
	twait = usec_to_timespec(3000000L);
	busywait(&twait);
	
	/* Then block on an rt_mutex */
	ftrace_write(marker_fd, "helper() blocks on rt_mutex %p\n", &rt_mutex);
	pthread_mutex_lock(&rt_mutex);
	twait = usec_to_timespec(3000000L);
	busywait(&twait);
	pthread_mutex_unlock(&rt_mutex);
	
	ftrace_write(marker_fd, "helper() signals on cv %p\n", &count_threshold_cv);
	pthread_cond_broadcast(&count_threshold_cv);
	ftrace_write(marker_fd, "helper(): just sent signal.\n");
	ftrace_write(marker_fd, "helper(): pid %d, unlocking mutex\n", my_pid);
	pthread_mutex_unlock(&count_mutex);

	if (pi_cv_enabled) {
		pthread_cond_helpers_del(&count_threshold_cv, my_pid);
		ftrace_write(marker_fd, "helper(): stop helping on cv %p\n", &count_threshold_cv);
		ftrace_write(marker_fd, "Removing helper() thread: pid %d prio 93\n", my_pid);
	}
	pthread_exit(NULL);
}
Esempio n. 4
0
int main(int argc, char **argv) {
	struct sched_param2 dl_params;
	int i, retval;
	pthread_t thread[MAX_THREADS];
	char *debugfs = "/debug";
	char path[256];
	long tid = gettid();

	if (argc > 1) {
		printf("[main] MBWI enabled\n");
		bwi_enabled = atoi(argv[1]);
	}

	printf("main opening trace fds\n");
	strcpy(path, debugfs);
	strcat(path, "/tracing/tracing_on");
	trace_fd = open(path, O_WRONLY);
	if (trace_fd < 0) {
		printf("can't open trace_fd!\n");
		exit(-1);
	}

	strcpy(path, debugfs);
	strcat(path, "/tracing/trace_marker");
	marker_fd = open(path, O_WRONLY);
	if (marker_fd < 0) {
		printf("can't open marker_fd!\n");
		exit(-1);
	}

	/* Initialize mutex variable objects */
	pthread_mutexattr_init(&my_mutex_attr);
	if (bwi_enabled)
		pthread_mutexattr_setprotocol(&my_mutex_attr,
					      PTHREAD_PRIO_INHERIT);
	pthread_mutex_init(&my_mutex, &my_mutex_attr);

	printf("[main] creates %d threads\n", MAX_THREADS);
	write(trace_fd, "1", 1);
	ftrace_write(marker_fd, "[main] creates %d threads\n", MAX_THREADS);

	pthread_create(&thread[0], NULL, t_1, NULL);
	pthread_create(&thread[1], NULL, t_2, NULL);

	for (i = 0; i < MAX_THREADS; i++)
		pthread_join(thread[i], NULL);

	write(trace_fd, "0", 1);
	close(trace_fd);
	close(marker_fd);

	printf("[main] exits\n");
	ftrace_write(marker_fd, "[main] exits\n");
}
Esempio n. 5
0
void sighandler()
{
	ftrace_write(marker_fd, "main killed!\n");
	write(trace_fd, "0", 1);
	close(trace_fd);
	close(marker_fd);
	exit(-1);	
}
Esempio n. 6
0
void *rt_owner(void *d) 
{
	int i, ret;
	struct timespec twait;
	struct sched_param param;
	cpu_set_t mask;
	pid_t my_pid = gettid();
	
	CPU_ZERO(&mask);
	CPU_SET(0, &mask);
	ret = sched_setaffinity(0, sizeof(mask), &mask);
	if (ret != 0) {
		printf("pthread_setaffinity failed\n"); 
		exit(EXIT_FAILURE);
	}

	param.sched_priority = 92;
	ret = pthread_setschedparam(pthread_self(), 
				    SCHED_FIFO, 
				    &param);
	if (ret != 0) {
		printf("pthread_setschedparam failed\n"); 
		exit(EXIT_FAILURE);
	}

	ftrace_write(marker_fd, "Starting rt_owner(): pid %d prio 92\n", my_pid);
	
	pthread_mutex_lock(&rt_mutex);

	/* Do some work (e.g., fill up the queue) */
	twait = usec_to_timespec(6000000L);
	busywait(&twait);
	
	ftrace_write(marker_fd, "rt_owner(): pid %d, unlocking mutex\n", my_pid);
	pthread_mutex_unlock(&rt_mutex);

	pthread_exit(NULL);
}
Esempio n. 7
0
void *waiter(void *d) 
{
	int ret;
	struct timespec twait;
	struct sched_param param;
	cpu_set_t mask;
	pid_t my_pid = gettid();
	
	sleep(1);

	CPU_ZERO(&mask);
	CPU_SET(0, &mask);
	ret = sched_setaffinity(0, sizeof(mask), &mask);
	if (ret != 0) {
		printf("pthread_setaffinity failed\n"); 
		exit(EXIT_FAILURE);
	}

	param.sched_priority = 95;
	ret = pthread_setschedparam(pthread_self(), 
				    SCHED_FIFO, 
				    &param);
	if (ret != 0) {
		printf("pthread_setschedparam failed\n"); 
		exit(EXIT_FAILURE);
	}
	ftrace_write(marker_fd, "Starting waiter(): pid %d prio 95\n", my_pid);
	twait = usec_to_timespec(500000L);
	busywait(&twait);
	
	/*
	Lock mutex and wait for signal.  Note that the pthread_cond_wait routine
	will automatically and atomically unlock mutex while it waits. 
	*/
	pthread_mutex_lock(&count_mutex);
	ftrace_write(marker_fd, "waiter(): pid %d. Going into wait...\n", my_pid);
	ftrace_write(marker_fd, "waiter(): waits on cv %p\n", &count_threshold_cv);
	pthread_cond_wait(&count_threshold_cv, &count_mutex);
	ftrace_write(marker_fd, "waiter(): wakes on cv %p\n", &count_threshold_cv);
	/* "Consume" the item... */
	ftrace_write(marker_fd, "waiter(): pid %d Condition signal received.\n", my_pid);
	ftrace_write(marker_fd, "waiter(): pid %d Consuming an item...\n", my_pid);
	twait = usec_to_timespec(2000000L);
	busywait(&twait);
	
	ftrace_write(marker_fd, "waiter(): pid %ld Unlocking mutex.\n", my_pid);
	pthread_mutex_unlock(&count_mutex);

	pthread_exit(NULL);
}
Esempio n. 8
0
void *start_task(void *data)
{
    struct thread *thr = (struct thread *)data;
    long id = (long) thr->arg;
    thread_pids[id] = gettid();
    unsigned long long start_time;
    int ret;
    int high = 0;
    cpu_set_t cpumask;
    cpu_set_t save_cpumask;
    int cpu = 0;
    unsigned long l;
    long pid;

    ret = sched_getaffinity(0, sizeof(save_cpumask), &save_cpumask);
    if (ret < 0)
        debug(DBG_ERR, "sched_getaffinity failed: %s\n", strerror(ret));

    pid = gettid();

    /* Check if we are the highest prio task */
    if (id == nr_tasks-1)
        high = 1;

    while (!done) {
        if (high) {
            /* rotate around the CPUS */
            if (!CPU_ISSET(cpu, &save_cpumask))
                cpu = 0;
            CPU_ZERO(&cpumask);
            CPU_SET(cpu, &cpumask);
            cpu++;
            sched_setaffinity(0, sizeof(cpumask), &cpumask);
        }
        pthread_barrier_wait(&start_barrier);
        start_time = rt_gettime();
        ftrace_write("Thread %d: started %lld diff %lld\n",
                     pid, start_time, start_time - now);
        l = busy_loop(start_time);
        record_time(id, start_time / NS_PER_US, l);
        pthread_barrier_wait(&end_barrier);
    }

    return (void *)pid;
}
Esempio n. 9
0
void *producer(void *d)
{
	int ret;
	struct sched_param param;
	long id = (long) d;
	long wait;
	int item = id;
	buffer_t *b = &buffer;
	struct timespec twait, now;
	cpu_set_t mask;
	pid_t my_pid = gettid();

	pids[id] = my_pid;
	
	if (global_args.affinity) {
		CPU_ZERO(&mask);
		CPU_SET(0, &mask);
		ret = sched_setaffinity(0, sizeof(mask), &mask);
		if (ret != 0) {
			printf("pthread_setaffinity failed\n"); 
			exit(EXIT_FAILURE);
		}
	}
	
	param.sched_priority = 92;
	ret = pthread_setschedparam(pthread_self(), 
				    SCHED_FIFO, 
				    &param);
	if (ret != 0) {
		printf("pthread_setschedparam failed\n"); 
		exit(EXIT_FAILURE);
	}

	if (global_args.pi_cv_enabled) {
		if (global_args.ftrace)
			ftrace_write(marker_fd, "Adding helper thread: pid %d,"
				     " prio 92\n", my_pid);
		pthread_cond_helpers_add(&buffer.more, my_pid);
		if (global_args.ftrace)
			ftrace_write(marker_fd, "[prod %d] helps on cv %p\n",
				     my_pid, &buffer.more);
	}

	while(!shutdown) {
		pthread_mutex_lock(&b->mutex);

		while (b->occupied >= BSIZE)
			pthread_cond_wait(&b->less, &b->mutex);

		assert(b->occupied < BSIZE);

		b->buf[b->nextin++] = item;
		wait = rand_wait() * 1000;
		twait = usec_to_timespec(wait);
		clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now);
		twait = timespec_add(&now, &twait);
		busywait(&twait);
		if (global_args.ftrace)
			ftrace_write(marker_fd, "[prod %d] executed for %d usec"
				     " and produced %d\n", my_pid, wait, item);

		b->nextin %= BSIZE;
		b->occupied++;

		/*
		 * now: either b->occupied < BSIZE and b->nextin is the index
		 * of the next empty slot in the buffer, or
		 * b->occupied == BSIZE and b->nextin is the index of the
		 * next (occupied) slot that will be emptied by a consumer
		 * (such as b->nextin == b->nextout)
		 */
	
		pthread_cond_signal(&b->more);
	
		pthread_mutex_unlock(&b->mutex);
		sleep(1);
	}

	if (global_args.pi_cv_enabled) {
		pthread_cond_helpers_del(&buffer.more, my_pid);
		if (global_args.ftrace) {
			ftrace_write(marker_fd, "[prod %d] stop helping"
				     " on cv %p\n", my_pid, &buffer.more);
			ftrace_write(marker_fd, "Removing helper thread:"
				     " pid %d, prio 92\n", my_pid);
		}
	}

	pthread_exit(NULL);
}
Esempio n. 10
0
int main(int argc, char *argv[])
{
	int i, ret, opt = 0; 
	long id = 0;
	pthread_t threads[MAX_PROD + MAX_CONS + MAX_ANNOY];
	pthread_attr_t attr;
	struct sched_param param;
	cpu_set_t mask;
	char *debugfs;
	char path[256];

	global_args.num_prod = 1;
	global_args.num_cons = 1;
	global_args.num_annoy = 1;
	global_args.pi_cv_enabled = 0;
	global_args.ftrace = 0;
	global_args.duration = 10;
	global_args.affinity = 0;

	opt = getopt(argc, argv, opt_string);
	while (opt != -1) {
		switch (opt) {
		case 'p':
			global_args.num_prod = atoi(optarg);
			break;
		case 'c':
			global_args.num_cons = atoi(optarg);
			break;
		case 'a':
			global_args.num_annoy = atoi(optarg);
			break;
		case 'P':
			global_args.pi_cv_enabled = 1;
			break;
		case 'f':
			global_args.ftrace = 1;
			break;
		case 'd':
			global_args.duration = atoi(optarg);
			break;
		case 'A':
			global_args.affinity = 1;
			break;
		}
		
		opt = getopt(argc, argv, opt_string);
	}

	if (global_args.ftrace) {
		debugfs = "/debug";
		strcpy(path, debugfs);
		strcat(path,"/tracing/tracing_on");
		trace_fd = open(path, O_WRONLY);
		if (trace_fd >= 0)
		        write(trace_fd, "1", 1);

		strcpy(path, debugfs);
		strcat(path,"/tracing/trace_marker");
		marker_fd = open(path, O_WRONLY);
	}
	

	if (global_args.affinity) {
		CPU_ZERO(&mask);
		CPU_SET(1, &mask);
		ret = sched_setaffinity(0, sizeof(mask), &mask);
		if (ret != 0) {
			printf("pthread_setaffinity failed\n"); 
			exit(EXIT_FAILURE);
		}
	}
	
	param.sched_priority = 99;
	ret = pthread_setschedparam(pthread_self(), 
				    SCHED_FIFO, 
				    &param);
	if (ret != 0) {
		printf("pthread_setschedparam failed\n"); 
		exit(EXIT_FAILURE);
	}

	srand(time(NULL));
	
	/* Initialize mutex and condition variable objects */
	pthread_mutexattr_init(&buffer.mutex_attr);
	pthread_mutexattr_setprotocol(&buffer.mutex_attr, PTHREAD_PRIO_INHERIT);
	pthread_mutex_init(&buffer.mutex, &buffer.mutex_attr);
	pthread_cond_init (&buffer.more, NULL);
	pthread_cond_init (&buffer.less, NULL);
	
	/* For portability, explicitly create threads in a joinable state */
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
	
	for (i = 0; i < global_args.num_cons; i++) {
		if (global_args.ftrace)
			ftrace_write(marker_fd, "[main]: creating consumer()\n");
		pthread_create(&threads[i], &attr, consumer, (void *)id);
		id++;
	}

	for (i = global_args.num_cons; i < (global_args.num_cons +
					    global_args.num_prod); i++) {
		if (global_args.ftrace)
			ftrace_write(marker_fd, "[main]: creating producer()\n");
		pthread_create(&threads[i], &attr, producer, (void *)id);
		id++;
	}

	for (; i < (global_args.num_cons + global_args.num_prod +
		    global_args.num_annoy); i++) {
		if (global_args.ftrace)
			ftrace_write(marker_fd, "[main]: creating annoyer()\n");
		pthread_create(&threads[i], &attr, annoyer, (void *)id);
		id++;
	}

	sleep(global_args.duration);
	shutdown = 1;
	for (i = 0; i < (global_args.num_cons + global_args.num_prod +
			 global_args.num_annoy); i++) {
		kill(pids[i], 9);
	}
	
	/* Wait for all threads to complete */
	for (i = 0; i < (global_args.num_cons + global_args.num_prod +
			 global_args.num_annoy); i++) {
		pthread_join(threads[i], NULL);
	}
	printf ("Main(): Waited and joined with %d threads. Done.\n", 
		global_args.num_cons + global_args.num_prod +
		global_args.num_annoy);
	
	if (global_args.ftrace && trace_fd >= 0)
	        write(trace_fd, "0", 1);

	/* Clean up and exit */
	pthread_attr_destroy(&attr);
	pthread_mutex_destroy(&buffer.mutex);
	pthread_cond_destroy(&buffer.more);
	pthread_cond_destroy(&buffer.less);
	pthread_exit (NULL);
}
Esempio n. 11
0
void *consumer(void *d)
{
	int ret;
	struct sched_param param;
	long id = (long) d;
	long wait;
	int item;
	buffer_t *b = &buffer;
	struct timespec twait, now;
	cpu_set_t mask;
	pid_t my_pid = gettid();

	pids[id] = my_pid;
	

	if (global_args.affinity) {
		CPU_ZERO(&mask);
		CPU_SET(0, &mask);
		ret = sched_setaffinity(0, sizeof(mask), &mask);
		if (ret != 0) {
			printf("pthread_setaffinity failed\n"); 
			exit(EXIT_FAILURE);
		}
	}
	
	param.sched_priority = 94;
	ret = pthread_setschedparam(pthread_self(), 
				    SCHED_FIFO, 
				    &param);
	if (ret != 0) {
		printf("pthread_setschedparam failed\n"); 
		exit(EXIT_FAILURE);
	}
	
	/**
	 * Give producers some time to set up.
	 */
	sleep(1);

	while(!shutdown) {
		pthread_mutex_lock(&b->mutex);
		while(b->occupied <= 0) {
			if (global_args.ftrace)
				ftrace_write(marker_fd, "[cons %d] waits\n",
					     my_pid);
			pthread_cond_wait(&b->more, &b->mutex);
		}
	
		assert(b->occupied > 0);
	
		item = b->buf[b->nextout++];
		wait = rand_wait() * 1000;
		twait = usec_to_timespec(wait);
		clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now);
		twait = timespec_add(&now, &twait);
		busywait(&twait);
		if (global_args.ftrace)
			ftrace_write(marker_fd, "[cons %d] executed for %d usec"
				     " and consumed %d\n", my_pid, wait, item);

		b->nextout %= BSIZE;
		b->occupied--;
	
		/*
		 * now: either b->occupied > 0 and b->nextout is the index
		 * of the next occupied slot in the buffer, or
		 * b->occupied == 0 and b->nextout is the index of the next
		 * (empty) slot that will be filled by a producer (such as
		 * b->nextout == b->nextin)
		 */
	
		pthread_cond_signal(&b->less);
		pthread_mutex_unlock(&b->mutex);
	}

	pthread_exit(NULL);
}
Esempio n. 12
0
int main(int argc, char *argv[])
{
	int i, rc, ret; 
	pthread_t threads[NUM_THREADS];
	pthread_attr_t attr;
	struct sched_param param;
	cpu_set_t mask;
	char *debugfs;
	char path[256];
	
	if (argc > 1)
		pi_cv_enabled = atoi(argv[1]);

	debugfs = "/debug";
	strcpy(path, debugfs);
	strcat(path,"/tracing/tracing_on");
	trace_fd = open(path, O_WRONLY);
	if (trace_fd >= 0)
	        write(trace_fd, "1", 1);

	strcpy(path, debugfs);
	strcat(path,"/tracing/trace_marker");
	marker_fd = open(path, O_WRONLY);
	
	CPU_ZERO(&mask);
	CPU_SET(1, &mask);
	ret = sched_setaffinity(0, sizeof(mask), &mask);
	if (ret != 0) {
		printf("pthread_setaffinity failed\n"); 
		exit(EXIT_FAILURE);
	}
	
	param.sched_priority = 96;
	ret = pthread_setschedparam(pthread_self(), 
				    SCHED_FIFO, 
				    &param);
	if (ret != 0) {
		printf("pthread_setschedparam failed\n"); 
		exit(EXIT_FAILURE);
	}
	
	/* Initialize mutex and condition variable objects */
	pthread_mutexattr_init(&count_mutex_attr);
	pthread_mutexattr_setprotocol(&count_mutex_attr, PTHREAD_PRIO_INHERIT);
	pthread_mutex_init(&count_mutex, &count_mutex_attr);
	pthread_cond_init (&count_threshold_cv, NULL);
	pthread_mutexattr_init(&rt_mutex_attr);
	pthread_mutexattr_setprotocol(&rt_mutex_attr, PTHREAD_PRIO_INHERIT);
	pthread_mutex_init(&rt_mutex, &rt_mutex_attr);
	
	/* For portability, explicitly create threads in a joinable state */
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
	ftrace_write(marker_fd, "[main]: creating helper()\n");
	pthread_create(&threads[0], &attr, helper, NULL);
	ftrace_write(marker_fd, "[main]: creating rt_owner()\n");
	pthread_create(&threads[1], &attr, rt_owner, NULL);
	ftrace_write(marker_fd, "[main]: creating waiter()\n");
	pthread_create(&threads[2], &attr, waiter, NULL);
	sleep(3);
	ftrace_write(marker_fd, "[main]: creating annoyer()\n");
	pthread_create(&threads[3], &attr, annoyer, NULL);
	
	/* Wait for all threads to complete */
	for (i = 0; i < NUM_THREADS; i++) {
		pthread_join(threads[i], NULL);
	}
	printf ("Main(): Waited and joined with %d threads. Done.\n", 
	        NUM_THREADS);
	
	if (trace_fd >= 0)
	        write(trace_fd, "0", 1);
	/* Clean up and exit */
	pthread_attr_destroy(&attr);
	pthread_mutex_destroy(&count_mutex);
	pthread_cond_destroy(&count_threshold_cv);
	pthread_mutex_destroy(&rt_mutex);
	pthread_exit (NULL);
}
Esempio n. 13
0
void *t_1(void *thread_params) {
	struct sched_param2 dl_params;
	struct timespec t_next, t_period, t_start, t_stop, ran_for,
			t_now, t_crit, t_exec;
	long tid = gettid();
	int retval, i;
	cpu_set_t mask;
	__u64 crit, run1, runtime, deadline, period;

	/*
	 * t_1 should go in budget overflow while in critical section
	 */
	run1 = 8U * NSEC_PER_MSEC;
	crit = 12U * NSEC_PER_MSEC;
	runtime =  run1 + crit + (8U * NSEC_PER_MSEC);
	deadline = 40U * NSEC_PER_MSEC;
	period = deadline;
	t_period = nsec_to_timespec(&period);
	t_crit = nsec_to_timespec(&crit);

	signal(SIGHUP, sighandler);
	signal(SIGINT, sighandler);
	signal(SIGQUIT, sighandler);

	CPU_ZERO(&mask);
	CPU_SET(0, &mask);
	retval = sched_setaffinity(0, sizeof(mask), &mask);
	if (retval) {
		fprintf(stderr, "WARNING: could not set task affinity\n");
		exit(-1);
	}

	memset(&dl_params, 0, sizeof(dl_params));
	dl_params.sched_priority = 0;
	dl_params.sched_runtime = runtime;
	dl_params.sched_deadline = deadline;
	dl_params.sched_period = period;
	ftrace_write(marker_fd, "[thread %ld (t_1)]: setting rt=%llums dl=%llums\n", tid,
	       runtime/NSEC_PER_MSEC,
	       deadline/NSEC_PER_MSEC);
	retval = sched_setscheduler2(0, SCHED_DEADLINE, &dl_params);
	if (retval) {
		fprintf(stderr, "WARNING: could not set SCHED_DEADLINE"
				" policy!\n");
		exit(-1);
	}

	clock_gettime(CLOCK_MONOTONIC, &t_next);
	for (i = 0; i < NRUN; i++) {
		ftrace_write(marker_fd, "[t_1] run starts\n");
		clock_gettime(CLOCK_MONOTONIC, &t_start);
		ftrace_write(marker_fd, "[t_1] exec for %lluns\n", run1);
		busywait(run1);
		ftrace_write(marker_fd, "[t_1] locks mutex\n");
		pthread_mutex_lock(&my_mutex);
		ftrace_write(marker_fd, "[t_1] exec for %lluns\n", crit);
		busywait(crit);
		ftrace_write(marker_fd, "[t_1] unlocks mutex\n");
		pthread_mutex_unlock(&my_mutex);
		clock_gettime(CLOCK_MONOTONIC, &t_stop);
		t_next = timespec_add(&t_next, &t_period);
		ran_for = timespec_sub(&t_stop, &t_start);
		printf("[thread %ld]: run %d for %lluus\n",
			tid,
			i,
			timespec_to_usec(&ran_for));
		ftrace_write(marker_fd, "[t_1] run ends\n");
		clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t_next, NULL);
	}

	retval = sched_setscheduler2(0, SCHED_OTHER, &dl_params);
	if (retval) {
		fprintf(stderr, "WARNING: could not set SCHED_OTHER"
				"policy!\n");
		exit(-1);
	}
}
Esempio n. 14
0
int main(int argc, char **argv)
{
    pthread_t *threads;
    long i;
    int ret;
    struct timespec intv;
    struct sched_param param;

    rt_init("a:r:t:e:l:h:", parse_args, argc, argv);
    signal(SIGINT, stop_log);

    if (argc >= (optind + 1))
        nr_tasks = atoi(argv[optind]);
    else {
        numcpus = sysconf(_SC_NPROCESSORS_ONLN);
        nr_tasks = numcpus + 1;
    }

    intervals = malloc(sizeof(stats_container_t) * nr_tasks);
    if (!intervals)
        debug(DBG_ERR, "malloc failed\n");
    memset(intervals, 0, sizeof(stats_container_t) * nr_tasks);

    intervals_length = malloc(sizeof(stats_container_t) * nr_tasks);
    if (!intervals_length)
        debug(DBG_ERR, "malloc failed\n");
    memset(intervals_length, 0, sizeof(stats_container_t) * nr_tasks);

    if (!intervals_loops)
        debug(DBG_ERR, "malloc failed\n");
    intervals_loops = malloc(sizeof(stats_container_t) * nr_tasks);
    memset(intervals_loops, 0, sizeof(stats_container_t) * nr_tasks);

    threads = malloc(sizeof(*threads) * nr_tasks);
    if (!threads)
        debug(DBG_ERR, "malloc failed\n");
    memset(threads, 0, sizeof(*threads) * nr_tasks);

    ret = pthread_barrier_init(&start_barrier, NULL, nr_tasks + 1);
    ret = pthread_barrier_init(&end_barrier, NULL, nr_tasks + 1);
    if (ret < 0)
        debug(DBG_ERR, "pthread_barrier_init failed: %s\n",
              strerror(ret));


    for (i = 0; i < nr_tasks; i++) {
        stats_container_init(&intervals[i], nr_runs);
        stats_container_init(&intervals_length[i], nr_runs);
        stats_container_init(&intervals_loops[i], nr_runs);
    }

    thread_pids = malloc(sizeof(long) * nr_tasks);
    if (!thread_pids)
        debug(DBG_ERR, "malloc thread_pids failed\n");

    for (i = 0; i < nr_tasks; i++) {
        threads[i] = create_fifo_thread(start_task, (void *)i,
                                        prio_start + i);
    }

    /*
     * Progress bar uses stderr to let users see it when
     * redirecting output. So we convert stderr to use line
     * buffering so the progress bar doesn't flicker.
     */
    setlinebuf(stderr);

    /* up our prio above all tasks */
    memset(&param, 0, sizeof(param));
    param.sched_priority = nr_tasks + prio_start;
    if (sched_setscheduler(0, SCHED_FIFO, &param))
        debug(DBG_WARN, "Warning, can't set priority of"
              "main thread !\n");
    intv.tv_sec = INTERVAL / NS_PER_SEC;
    intv.tv_nsec = INTERVAL % (1 * NS_PER_SEC);

    print_progress_bar(0);

    setup_ftrace_marker();

    for (loop = 0; loop < nr_runs; loop++) {
        unsigned long long end;

        now = rt_gettime() / NS_PER_US;

        ftrace_write("Loop %d now=%lld\n", loop, now);

        pthread_barrier_wait(&start_barrier);

        ftrace_write("All running!!!\n");

        rt_nanosleep(intv.tv_nsec);
        print_progress_bar((loop * 100) / nr_runs);

        end = rt_gettime() / NS_PER_US;
        ftrace_write("Loop %d end now=%lld diff=%lld\n",
                     loop, end, end - now);
        ret = pthread_barrier_wait(&end_barrier);

        if (stop || (check && check_times(loop))) {
            loop++;
            nr_runs = loop;
            break;
        }
    }
    putc('\n', stderr);

    pthread_barrier_wait(&start_barrier);
    done = 1;
    pthread_barrier_wait(&end_barrier);

    join_threads();
    print_results();

    if (stop) {
        /*
         * We use this test in bash while loops
         * So if we hit Ctrl-C then let the while
         * loop know to break.
         */
        if (check < 0)
            exit(-1);
        else
            exit(1);
    }
    if (check < 0)
        exit(-1);
    else
        exit(0);

    return 0;
}