int main(int argc, char *argv[]) { int i, j, k, err; unsigned long long delta; unsigned long long max, min; struct sched_param param; stats_container_t dat; stats_container_t hist; stats_quantiles_t quantiles; stats_record_t rec; struct timespec *start_data; struct timespec *stop_data; if (stats_cmdline(argc, argv) < 0) { printf("usage: %s help\n", argv[0]); exit(1); } if (iterations < MIN_ITERATION) { iterations = MIN_ITERATION; printf("user \"iterations\" value is too small (use: %d)\n", iterations); } stats_container_init(&dat, iterations); stats_container_init(&hist, HIST_BUCKETS); stats_quantiles_init(&quantiles, (int)log10(iterations)); setup(); mlockall(MCL_CURRENT | MCL_FUTURE); start_data = calloc(iterations, sizeof(struct timespec)); if (start_data == NULL) { printf("Memory allocation Failed (too many Iteration: %d)\n", iterations); exit(1); } stop_data = calloc(iterations, sizeof(struct timespec)); if (stop_data == NULL) { printf("Memory allocation Failed (too many Iteration: %d)\n", iterations); free(start_data); exit(1); } /* switch to SCHED_FIFO 99 */ param.sched_priority = sched_get_priority_max(SCHED_FIFO); err = sched_setscheduler(0, SCHED_FIFO, ¶m); /* Check that the user has the appropriate privileges */ if (err) { if (errno == EPERM) { fprintf(stderr, "This program runs with a scheduling policy of SCHED_FIFO at priority %d\n", param.sched_priority); fprintf(stderr, "You don't have the necessary privileges to create such a real-time process.\n"); } else { fprintf(stderr, "Failed to set scheduler, errno %d\n", errno); } exit(1); } printf("\n----------------------\n"); printf("Gettimeofday() Latency\n"); printf("----------------------\n"); printf("Iterations: %d\n\n", iterations); /* collect iterations pairs of gtod calls */ max = min = 0; if (latency_threshold) { latency_trace_enable(); latency_trace_start(); } /* This loop runs for a long time, hence can cause soft lockups. Calling sleep periodically avoids this. */ for (i = 0; i < (iterations / 10000); i++) { for (j = 0; j < 10000; j++) { k = (i * 10000) + j; clock_gettime(CLOCK_MONOTONIC, &start_data[k]); clock_gettime(CLOCK_MONOTONIC, &stop_data[k]); } usleep(1000); } for (i = 0; i < iterations; i++) { delta = timespec_subtract(&start_data[i], &stop_data[i]); rec.x = i; rec.y = delta; stats_container_append(&dat, rec); if (i == 0 || delta < min) min = delta; if (delta > max) max = delta; if (latency_threshold && delta > latency_threshold) break; } if (latency_threshold) { latency_trace_stop(); if (i != iterations) { printf ("Latency threshold (%lluus) exceeded at iteration %d\n", latency_threshold, i); latency_trace_print(); stats_container_resize(&dat, i + 1); } } stats_hist(&hist, &dat); stats_container_save(filenames[SCATTER_FILENAME], titles[SCATTER_TITLE], labels[SCATTER_LABELX], labels[SCATTER_LABELY], &dat, "points"); stats_container_save(filenames[HIST_FILENAME], titles[HIST_TITLE], labels[HIST_LABELX], labels[HIST_LABELY], &hist, "steps"); /* report on deltas */ printf("Min: %llu ns\n", min); printf("Max: %llu ns\n", max); printf("Avg: %.4f ns\n", stats_avg(&dat)); printf("StdDev: %.4f ns\n", stats_stddev(&dat)); printf("Quantiles:\n"); stats_quantiles_calc(&dat, &quantiles); stats_quantiles_print(&quantiles); stats_container_free(&dat); stats_container_free(&hist); stats_quantiles_free(&quantiles); return 0; }
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 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; }