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, ¶m); 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); }
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, ¶m); 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); }
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, ¶m); 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); }
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"); }
void sighandler() { ftrace_write(marker_fd, "main killed!\n"); write(trace_fd, "0", 1); close(trace_fd); close(marker_fd); exit(-1); }
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, ¶m); 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); }
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, ¶m); 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); }
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; }
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, ¶m); 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); }
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, ¶m); 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); }
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, ¶m); 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); }
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, ¶m); 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); }
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); } }
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(¶m, 0, sizeof(param)); param.sched_priority = nr_tasks + prio_start; if (sched_setscheduler(0, SCHED_FIFO, ¶m)) 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; }