int main(int argc, char *argv[]) { int thr_id1, thr_id2; atomic_set(0,&flag); setup(); pass_criteria = THRESHOLD; rt_init("l:h", parse_args, argc, argv); /* we need the buffered print system */ printf("-------------------------------\n"); printf("pthread_kill Latency\n"); printf("-------------------------------\n\n"); printf("Iterations: %d\n", ITERATIONS); debug(DBG_DEBUG, "Main creating threads\n"); fflush(stdout); thr_id1 = create_fifo_thread(signal_receiving_thread, (void*)0, PRIO); thr_id2 = create_fifo_thread(signal_sending_thread, (void*)(intptr_t)thr_id1, PRIO-1); // thr_id2 = create_other_thread(signal_sending_thread, (void*)(intptr_t)thr_id1); debug(DBG_DEBUG, "Main joining threads debug\n"); join_thread(thr_id1); join_thread(thr_id2); buffer_print(); return fail; }
void *master_thread(void *arg) { int i, pri_boost; pthread_barrier_init(&barrier, NULL, 2); /* start interrupter thread */ if (int_threads) { pri_boost = 90; for (i = 0; i < rt_threads; i++) { create_fifo_thread(int_thread, (void *)0, sched_get_priority_min(SCHED_FIFO) + pri_boost); } } /* start the (N-1) busy threads */ pri_boost = 80; for (i = rt_threads; i > 1; i--) { create_fifo_thread(busy_thread, (void *)(intptr_t) i, sched_get_priority_min(SCHED_FIFO) + pri_boost); } /* make sure children are started */ while (busy_threads < (rt_threads - 1)) usleep(100); printf("Busy threads created!\n"); /* start NUM_WORKERS worker threads */ for (i = 0, pri_boost = 10; i < NUM_WORKERS; i++, pri_boost += 2) { pthread_mutex_init(&mutex[i], NULL); pthread_cond_init(&cond[i], NULL); create_fifo_thread(worker_thread, (void *)(intptr_t) i, sched_get_priority_min(SCHED_FIFO) + pri_boost); } printf("Worker threads created\n"); /* Let the worker threads wait on the cond vars */ while (threads_running < NUM_WORKERS) usleep(100); /* Ensure the first worker has called cond_wait */ pthread_barrier_wait(&barrier); printf("Signaling first thread\n"); pthread_mutex_lock(&mutex[0]); pthread_cond_signal(&cond[0]); pthread_mutex_unlock(&mutex[0]); while (threads_running) usleep(500000); /* this period greatly affects the number of failures! */ test_over = 1; return NULL; }
/* * Test pthread creation at different thread priorities. */ int main(int argc, char* argv[]) { pthread_mutexattr_t mutexattr; int i, retc, protocol, nopi = 0; cpu_set_t mask; CPU_ZERO(&mask); CPU_SET(0, &mask); setup(); rt_init("h",parse_args,argc,argv); if ((retc = pthread_barrier_init(&barrier, NULL, 5))) { printf("pthread_barrier_init failed: %s\n", strerror(retc)); exit(retc); } retc = sched_setaffinity(0, sizeof(mask), &mask); if (retc < 0) { printf("Main Thread: Can't set affinity: %d %s\n", retc, strerror(retc)); exit(-1); } for (i=0;i<argc;i++) { if (strcmp(argv[i],"nopi") == 0) nopi = 1; } printf("Start %s\n",argv[0]); if (!nopi) { if (pthread_mutexattr_init(&mutexattr) != 0) { printf("Failed to init mutexattr\n"); }; if (pthread_mutexattr_setprotocol(&mutexattr, PTHREAD_PRIO_INHERIT) != 0) { printf("Can't set protocol prio inherit\n"); } if (pthread_mutexattr_getprotocol(&mutexattr, &protocol) != 0) { printf("Can't get mutexattr protocol\n"); } else { printf("protocol in mutexattr is %d\n", protocol); } if ((retc = pthread_mutex_init(&glob_mutex, &mutexattr)) != 0) { printf("Failed to init mutex: %d\n", retc); } } create_rr_thread(func_lowrt, NULL, 10); create_rr_thread(func_rt, NULL, 20); create_fifo_thread(func_rt, NULL, 30); create_fifo_thread(func_rt, NULL, 40); create_rr_thread(func_noise, NULL, 40); printf("Joining threads\n"); join_threads(); printf("Done\n"); printf("Criteria: Low Priority Thread and High Priority Thread should prempt each other multiple times\n"); return 0; }
int main(int argc, char *argv[]) { long i; int ret; setup(); pass_criteria = THRESHOLD; rt_init("hi:n:w:", parse_args, argc, argv); if (iterations < 100) { printf("Number of iterations cannot be less than 100\n"); exit(1); } busy_work_time = low_work_time; if (num_busy == -1) { /* Number of busy threads = No. of CPUs */ num_busy = sysconf(_SC_NPROCESSORS_ONLN); } if ((ret = pthread_barrier_init(&bar1, NULL, (num_busy + 2)))) { printf("pthread_barrier_init failed: %s\n", strerror(ret)); exit(ret); } if ((ret = pthread_barrier_init(&bar2, NULL, (num_busy + 2)))) { printf("pthread_barrier_init failed: %s\n", strerror(ret)); exit(ret); } init_pi_mutex(&lock); if ((ret = create_fifo_thread(low_prio_thread, (void *)0, LOWPRIO)) < 0) exit(ret); if ((ret = create_fifo_thread(high_prio_thread, (void *)0, HIGHPRIO)) < 0) exit(ret); for (i = 0; i < num_busy; i++) { if ((ret = create_fifo_thread(busy_thread, (void *)i, BUSYPRIO)) < 0) exit(ret); } join_threads(); printf("Criteria: High prio lock wait time < " "(Low prio lock held time + %d us)\n", (int)pass_criteria); ret = 0; if (max_pi_delay > pass_criteria) ret = 1; printf("Result: %s\n", ret ? "FAIL" : "PASS"); return ret; }
//./a.out fifo1 fifo2 int main(int argc, const char *argv[]) { pthread_t tid[2]; tid[0] = create_fifo_thread(argv[1],O_WRONLY,write_fifo); tid[1] = create_fifo_thread(argv[2],O_RDONLY,read_fifo); pthread_join(tid[0],NULL); pthread_join(tid[1],NULL); return 0; }
/* * Test pthread creation at different thread priorities. */ int main(int argc, char *argv[]) { int i, retc, nopi = 0; cpu_set_t mask; CPU_ZERO(&mask); CPU_SET(0, &mask); setup(); rt_init("h", parse_args, argc, argv); retc = pthread_barrier_init(&barrier, NULL, 5); if (retc) { printf("pthread_barrier_init failed: %s\n", strerror(retc)); exit(retc); } retc = sched_setaffinity(0, sizeof(mask), &mask); if (retc < 0) { printf("Main Thread: Can't set affinity: %d %s\n", retc,\ strerror(retc)); exit(-1); } for (i = 0; i < argc; i++) { if (strcmp(argv[i], "nopi") == 0) nopi = 1; } printf("Start %s\n", argv[0]); if (!nopi) init_pi_mutex(&glob_mutex); create_rr_thread(func_lowrt, NULL, 10); create_rr_thread(func_rt, NULL, 20); create_fifo_thread(func_rt, NULL, 30); create_fifo_thread(func_rt, NULL, 40); create_rr_thread(func_noise, NULL, 40); printf("Joining threads\n"); join_threads(); printf("Done\n"); printf("Criteria: Low Priority Thread and High Priority Thread "\ "should prempt each other multiple times\n"); pthread_mutex_destroy(&glob_mutex); pthread_mutex_destroy(&cond_mutex); pthread_cond_destroy(&cond_var); return 0; }
int main(int argc, char *argv[]) { int worker, interrupter; setup(); rt_init("h",parse_args,argc,argv); interrupter = create_fifo_thread(thread_interrupter, NULL, 80); sleep(1); worker = create_fifo_thread(thread_worker, NULL, 10); join_thread(worker); flag = 1; join_thread(interrupter); return 0; }
void *master_thread(void* arg) { int i; struct timespec ts_abs_timeout; struct thread *t = (struct thread *)arg; // 1 pthread_mutex_lock(&MM); for (i = 0; i < NUM_SLAVES; i++) { create_fifo_thread(slave_thread, (void *)(intptr_t)i, SLAVE_PRIO); } // 2 printf("Master waiting till slaves wait()\n"); pthread_cond_wait(&CM, &MM); printf("Master awoken\n"); // 6 pthread_mutex_lock(&MS); // 7 printf("Master doing 3 signals\n"); pthread_cond_signal(&CS); pthread_cond_signal(&CS); pthread_cond_signal(&CS); // 8 printf("Master doing 3 broadcasts\n"); pthread_cond_broadcast(&CS); pthread_cond_broadcast(&CS); pthread_cond_broadcast(&CS); pthread_mutex_unlock(&MS); // if we should timedwait on MS, then we don't // need to unlock it here // 9 printf("Master waiting 10 seconds\n"); clock_gettime(CLOCK_REALTIME, &ts_abs_timeout); ts_abs_timeout.tv_sec += 10; pthread_cond_timedwait(&CM, &MM, &ts_abs_timeout); // docs say CS and MS, but // that doesn't seem correct // 13 pthread_mutex_unlock(&MM); // 14 printf("Master doing notify of all remaining slaves\n"); pthread_mutex_lock(&MS); pthread_cond_broadcast(&CS); // 15 pthread_mutex_unlock(&MS); // docs say MM, but that doesn't make sense... // 16 pthread_mutex_lock(&MT); clock_gettime(CLOCK_REALTIME, &ts_abs_timeout); ts_abs_timeout.tv_sec += 2; pthread_cond_timedwait(&CT, &MT, &ts_abs_timeout); // 18 while (!thread_quit(t)) usleep(10); printf("All slaves have terminated\n"); return NULL; }
static unsigned long long calibrate(void) { struct timespec start, end, delta; const int crunch_loops = 10000; unsigned long long ns, lps; unsigned long count; struct timespec req; char label[8]; int n; count = 0; clock_gettime(CLOCK_MONOTONIC, &start); do_work(crunch_loops, &count); clock_gettime(CLOCK_MONOTONIC, &end); timespec_sub(&delta, &end, &start); ns = delta.tv_sec * ONE_BILLION + delta.tv_nsec; crunch_per_sec = (unsigned long long)((double)ONE_BILLION / (double)ns * crunch_loops); for (n = 0; n < nrthreads; n++) { sprintf(label, "t%d", n); create_fifo_thread(threads[n], label, counts[n]); sem_wait(&ready); } pthread_mutex_lock(&lock); started = 1; pthread_cond_broadcast(&barrier); pthread_mutex_unlock(&lock); req.tv_sec = 1; req.tv_nsec = 0; clock_nanosleep(CLOCK_MONOTONIC, 0, &req, NULL); for (n = 0, lps = 0; n < nrthreads; n++) { lps += counts[n]; pthread_kill(threads[n], SIGDEMT); } atomic_set(&throttle, 1); smp_wmb(); for (n = 0; n < nrthreads; n++) { pthread_cancel(threads[n]); pthread_join(threads[n], NULL); } started = 0; atomic_set(&throttle, 0); return lps; }
int main(int argc, char* argv[]) { int m, ret, robust; intptr_t t; pthread_mutexattr_t mutexattr; setup(); rt_init("h",parse_args,argc,argv); if (pthread_mutexattr_init(&mutexattr) != 0) { printf("Failed to init mutexattr\n"); } if (pthread_mutexattr_setrobust_np(&mutexattr, PTHREAD_MUTEX_ROBUST_NP) != 0) { printf("Can't set mutexattr robust\n"); } if (pthread_mutexattr_getrobust_np(&mutexattr, &robust) != 0) { printf("Can't get mutexattr robust\n"); } else { printf("robust in mutexattr is %d\n", robust); } /* malloc and initialize the mutexes */ printf("allocating and initializing %d mutexes\n", NUM_MUTEXES); for (m = 0; m < NUM_MUTEXES; m++) { if (!(mutexes[m] = malloc(sizeof(pthread_mutex_t)))) { perror("malloc failed\n"); } if ((ret = pthread_mutex_init(mutexes[m], &mutexattr))) { perror("pthread_mutex_init() failed\n"); } } printf("mutexes allocated and initialized successfully\n"); /* start children threads to walk the array, grabbing the locks */ for (t = 0; t < NUM_THREADS; t++) { create_fifo_thread(worker_thread, (void*)t, sched_get_priority_min(SCHED_FIFO)); } /* wait for the children to complete */ printf("joining threads\n"); join_threads(); /* destroy all the mutexes */ for (m = 0; m < NUM_MUTEXES; m++) { if (mutexes[m]) { if ((ret = pthread_mutex_destroy(mutexes[m]))) perror("pthread_mutex_destroy() failed\n"); free(mutexes[m]); } } return 0; }
int main(int argc, char *argv[]) { int pri_boost, numcpus; setup(); pass_criteria = CHECK_LIMIT; rt_init("hin:", parse_args, argc, argv); numcpus = sysconf(_SC_NPROCESSORS_ONLN); /* Max no. of busy threads should always be less than/equal the no. of cpus Otherwise, the box will hang */ if (rt_threads == -1 || rt_threads > numcpus) { rt_threads = numcpus; printf("Maximum busy thread count(%d), " "should not exceed number of cpus(%d)\n", rt_threads, numcpus); printf("Using %d\n", numcpus); } /* Test boilder plate: title and parameters */ printf("\n-------------------\n"); printf("Priority Preemption\n"); printf("-------------------\n\n"); printf("Busy Threads: %d\n", rt_threads); printf("Interrupter Threads: %s\n", int_threads ? "Enabled" : "Disabled"); printf("Worker Threads: %d\n\n", NUM_WORKERS); pri_boost = 81; create_fifo_thread(master_thread, (void *)0, sched_get_priority_min(SCHED_FIFO) + pri_boost); /* wait for threads to complete */ join_threads(); printf ("\nCriteria: All threads appropriately preempted within %d loop(s)\n", (int)pass_criteria); printf("Result: %s\n", ret ? "FAIL" : "PASS"); return ret; }
int main(int argc, char *argv[]) { int per_id; setup(); pass_criteria = PASS_US; rt_init("d:l:ht:i:", parse_args, argc, argv); printf("-------------------------------\n"); printf("Scheduling Latency\n"); printf("-------------------------------\n\n"); if (load_ms*NS_PER_MS >= period-OVERHEAD) { printf("ERROR: load must be < period - %d us\n", OVERHEAD/NS_PER_US); exit(1); } if (iterations == 0) iterations = DEFAULT_ITERATIONS; if (iterations < MIN_ITERATIONS) { printf("Too few iterations (%d), use min iteration instead (%d)\n", iterations, MIN_ITERATIONS); iterations = MIN_ITERATIONS; } printf("Running %d iterations with a period of %llu ms\n", iterations, period/NS_PER_MS); printf("Periodic load duration: %d ms\n", load_ms); printf("Expected running time: %d s\n", (int)(iterations*((float)period / NS_PER_SEC))); if (stats_container_init(&dat, iterations)) exit(1); if (stats_container_init(&hist, HIST_BUCKETS)) { stats_container_free(&dat); exit(1); } /* use the highest value for the quantiles */ if (stats_quantiles_init(&quantiles, (int)log10(iterations))) { stats_container_free(&hist); stats_container_free(&dat); exit(1); } /* wait one quarter second to execute */ start = rt_gettime() + 250 * NS_PER_MS; per_id = create_fifo_thread(periodic_thread, (void*)0, PRIO); join_thread(per_id); join_threads(); printf("\nCriteria: latencies < %d us\n", (int)pass_criteria); printf("Result: %s\n", ret ? "FAIL" : "PASS"); stats_container_free(&dat); stats_container_free(&hist); stats_quantiles_free(&quantiles); return ret; }
int main(int argc, char* argv[]) { int threads_per_prio; int numcpus; int numprios; int prio; int i; setup(); rt_init("hn:l:", parse_args, argc, argv); if (rt_threads == 0) { numcpus = sysconf(_SC_NPROCESSORS_ONLN); rt_threads = numcpus; } wakeup.arr = (int *)malloc(rt_threads * sizeof(int)); wakeup.counter = 0; printf("\n-----------------------\n"); printf("Priority Ordered Wakeup\n"); printf("-----------------------\n"); printf("Worker Threads: %d\n", rt_threads); printf("Calling pthread_cond_broadcast() with mutex: %s\n\n", locked_broadcast ? "LOCKED" : "UNLOCKED"); beginrun = rt_gettime(); init_pi_mutex(&mutex); /* calculate the number of threads per priority */ /* we get num numprios -1 for the workers, leaving one for the master */ numprios = sched_get_priority_max(SCHED_FIFO) - sched_get_priority_min(SCHED_FIFO); threads_per_prio = rt_threads / numprios; if (rt_threads % numprios) threads_per_prio++; /* start the worker threads */ prio = sched_get_priority_min(SCHED_FIFO); for (i = rt_threads; i > 0; i--) { if ((i != rt_threads && (i % threads_per_prio) == 0)) prio++; create_fifo_thread(worker_thread, (void*)(intptr_t)i, prio); } /* start the master thread */ create_fifo_thread(master_thread, (void*)(intptr_t)i, ++prio); /* wait for threads to complete */ join_threads(); pthread_mutex_destroy(&mutex); printf("\nCriteria: Threads should be woken up in priority order\n"); for (i = 0; i < (wakeup.counter-1); i++) { if (wakeup.arr[i] < wakeup.arr[i+1]) { printf("FAIL: Thread %d woken before %d\n", wakeup.arr[i], wakeup.arr[i+1]); ret++; } } printf("Result: %s\n", ret ? "FAIL" : "PASS"); return ret; }
int main(int argc, char *argv[]) { int i; setup(); rt_init("hi:", parse_args, argc, argv); if (iterations < 100) { fprintf(stderr, "Number of iteration cannot be less than 100.\n"); exit(1); } printf("------------------------------------\n"); printf("Periodic CPU Load Execution Variance\n"); printf("------------------------------------\n\n"); printf("Running %d iterations per thread\n", iterations); printf("Thread Group A:\n"); printf(" threads: %d\n", THREADS_PER_GROUP); printf(" priority: %d\n", PRIO_A); printf(" period: %d ms\n", PERIOD_A/NS_PER_MS); printf("Thread Group B:\n"); printf(" threads: %d\n", THREADS_PER_GROUP); printf(" priority: %d\n", PRIO_B); printf(" period: %d ms\n", PERIOD_B/NS_PER_MS); printf("Thread Group C:\n"); printf(" threads: %d\n", THREADS_PER_GROUP); printf(" priority: %d\n", PRIO_C); printf(" period: %d ms\n", PERIOD_C/NS_PER_MS); printf("\n"); for (i=0; i<(THREADS_PER_GROUP * NUM_GROUPS); i++) { stats_container_init(&dat[i], iterations); stats_quantiles_init(&quantiles[i], (int)log10(iterations)); } struct periodic_arg parg_a = {PERIOD_A, iterations, calc, (void *)CALC_LOOPS_A }; struct periodic_arg parg_b = {PERIOD_B, iterations, calc, (void *)CALC_LOOPS_B }; struct periodic_arg parg_c = {PERIOD_C, iterations, calc, (void *)CALC_LOOPS_C }; for (i=0; i < THREADS_PER_GROUP; i++) create_fifo_thread(periodic_thread, (void*)&parg_a, PRIO_A); for (i=0; i < THREADS_PER_GROUP; i++) create_fifo_thread(periodic_thread, (void*)&parg_b, PRIO_B); for (i=0; i < THREADS_PER_GROUP; i++) create_fifo_thread(periodic_thread, (void*)&parg_c, PRIO_C); join_threads(); printf("\nExecution Time Statistics:\n\n"); for (i=0; i<(THREADS_PER_GROUP * NUM_GROUPS); i++) { printf("TID %d (%c)\n", i, groupname[i>>2]); printf(" Min: %ld us\n", stats_min(&dat[i])); printf(" Max: %ld us\n", stats_max(&dat[i])); printf(" Avg: %f us\n", stats_avg(&dat[i])); printf(" StdDev: %f us\n\n", stats_stddev(&dat[i])); printf(" Quantiles:\n"); stats_quantiles_calc(&dat[i], &quantiles[i]); stats_quantiles_print(&quantiles[i]); printf("Criteria: TID %d did not miss a period\n", i); printf("Result: %s\n", fail[i] ? "FAIL":"PASS"); printf("\n"); if (fail[i]) ret = 1; } // FIXME: define pass criteria // printf("\nCriteria: latencies < %d us\n", PASS_US); // printf("Result: %s\n", ret ? "FAIL" : "PASS"); for (i=0; i<(THREADS_PER_GROUP * NUM_GROUPS); i++) { stats_container_free(&dat[i]); stats_quantiles_free(&quantiles[i]); } return ret; }
void main_thread(void) { int ret, i, j; nsec_t start, end; long smin = 0, smax = 0, cmin = 0, cmax = 0, delta = 0; float savg, cavg; int cpuid; if ( stats_container_init(&sdat, iterations) || stats_container_init(&shist, HIST_BUCKETS) || stats_container_init(&cdat, iterations) || stats_container_init(&chist, HIST_BUCKETS) ) { fprintf (stderr, "Cannot init stats container\n"); exit(1); } tids = malloc(sizeof(int) * numcpus); if (!tids) { perror("malloc"); exit(1); } memset(tids, 0, numcpus); cpuid = set_affinity(); if (cpuid == -1) { fprintf(stderr, "Main thread: Can't set affinity.\n"); exit(1); } /* run matrix mult operation sequentially */ curdat = &sdat; curdat->index = iterations-1; printf("\nRunning sequential operations\n"); start = rt_gettime(); for (i = 0; i < iterations; i++) matrix_mult_record(MATRIX_SIZE, i); end = rt_gettime(); delta = (long)((end - start)/NS_PER_US); savg = delta/iterations; /* don't use the stats record, use the total time recorded */ smin = stats_min(&sdat); smax = stats_max(&sdat); printf("Min: %ld us\n", smin); printf("Max: %ld us\n", smax); printf("Avg: %.4f us\n", savg); printf("StdDev: %.4f us\n", stats_stddev(&sdat)); if ( stats_hist(&shist, &sdat) || stats_container_save("sequential", "Matrix Multiplication Sequential Execution Runtime Scatter Plot", "Iteration", "Runtime (us)", &sdat, "points") || stats_container_save("sequential_hist", "Matrix Multiplicatoin Sequential Execution Runtime Histogram", "Runtime (us)", "Samples", &shist, "steps") ) { fprintf(stderr, "Warning: could not save sequential mults stats\n"); } pthread_barrier_init(&mult_start, NULL, numcpus+1); set_priority(PRIO); curdat = &cdat; curdat->index = iterations-1; online_cpu_id = -1; /* Redispatch cpus */ /* Create numcpus-1 concurrent threads */ for (j = 0; j < numcpus; j++) { tids[j] = create_fifo_thread(concurrent_thread, NULL, PRIO); if (tids[j] == -1) { printf("Thread creation failed (max threads exceeded?)\n"); exit(1); } } /* run matrix mult operation concurrently */ printf("\nRunning concurrent operations\n"); pthread_barrier_wait(&mult_start); start = rt_gettime(); join_threads(); end = rt_gettime(); delta = (long)((end - start)/NS_PER_US); cavg = delta/iterations; /* don't use the stats record, use the total time recorded */ cmin = stats_min(&cdat); cmax = stats_max(&cdat); printf("Min: %ld us\n", cmin); printf("Max: %ld us\n", cmax); printf("Avg: %.4f us\n", cavg); printf("StdDev: %.4f us\n", stats_stddev(&cdat)); if ( stats_hist(&chist, &cdat) || stats_container_save("concurrent", "Matrix Multiplication Concurrent Execution Runtime Scatter Plot", "Iteration", "Runtime (us)", &cdat, "points") || stats_container_save("concurrent_hist", "Matrix Multiplication Concurrent Execution Runtime Histogram", "Iteration", "Runtime (us)", &chist, "steps") ) { fprintf(stderr, "Warning: could not save concurrent mults stats\n"); } printf("\nConcurrent Multipliers:\n"); printf("Min: %.4f\n", (float)smin/cmin); printf("Max: %.4f\n", (float)smax/cmax); printf("Avg: %.4f\n", (float)savg/cavg); ret = 1; if (savg > (cavg * criteria)) ret = 0; printf("\nCriteria: %.2f * average concurrent time < average sequential time\n", criteria); printf("Result: %s\n", ret ? "FAIL" : "PASS"); return; }
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; }