#include #include #include #include #include "utils.h" #define HZ_ACCURACY 3 #define NUM_REC_JITTER 10000 #define WARMUP_ITERATIONS 500 // from Dr. Baker's bisection.c /* This example is very sloppy about checking and recovering from failed system calls. Essentially, we are assuming everything goes right. One sloppy detail is that we are not distinguishing functions that return -1 for failure and set errno from functions that return the errno value for failure instead of setting errno. Another sloppy detail is that with Linux threads exiting the process does not kill off all the threads; a bunch of threads may be left running. */ #define CHECK(CALL) if (CALL) { perror (#CALL); exit (-1); } struct time_jitter { cycles_t theo_start; cycles_t actual_start; struct timespec clock_theo_start; struct timespec clock_actual_start; }; /********** globals ***********/ double secs_per_cycle; double cpu_hz; struct time_jitter rec_jitter[NUM_REC_JITTER]; cycles_t cvt_microsecs_cycles(double microsecs) { cycles_t rtn_val = 0; rtn_val = (1.0L/secs_per_cycle)*(microsecs/1.0E6L); return rtn_val; } double cvt_cycles_microsecs(cycles_t cycles) { double rtn_val = 0; rtn_val = secs_per_cycle*cycles; rtn_val = rtn_val*1E6L; return rtn_val; } void print_pthread_attr_priority(pthread_attr_t* attr) { struct sched_param sched; pthread_attr_getschedparam(attr, &sched); printf("priority: %d\n", sched.sched_priority); } void *test_period() { int i; int ret; double nano_period; cycles_t cycle_period, cyc_prev_start; struct timespec timeout; nano_period = 500000; printf("period(nsec): %.16f\n", nano_period); cycles_t cyc_actual_start; printf("test will take approx: %u sec(s)\n", (unsigned int)((nano_period*NUM_REC_JITTER)/1.0E9) ); // get our initial time values clock_gettime(CLOCK_REALTIME,&timeout); // we want to get the theoretical time the pthread should continue cycle_period = cvt_microsecs_cycles(nano_period/1.0E3L); printf("period(cycles): %llu\n", cycle_period); // get our initial time value clock_gettime(CLOCK_REALTIME,&timeout); cyc_actual_start = get_cycles(); timeout.tv_sec = 0; timeout.tv_nsec = nano_period; for (i=0; i= neg_num_buckets) { printf("error: no (neg)bucket[%d] to put value %.16f in\n",put_bucket,diff_secs); printf("%llu %llu\n", rec_jitter[i].theo_start, rec_jitter[i].actual_start); printf("%.16f %.16f\n", cvt_cycles_microsecs(rec_jitter[i].theo_start), cvt_cycles_microsecs(rec_jitter[i].actual_start) ); } else { bucket[put_bucket]++; } } else { put_bucket = (int)diff_secs; if (put_bucket >= pos_num_buckets) { printf("error: no (pos)bucket[%d] to put value %.16f in\n",put_bucket,diff_secs); printf("%llu %llu\n", rec_jitter[i].theo_start, rec_jitter[i].actual_start); printf("%.16f %.16f\n", cvt_cycles_microsecs(rec_jitter[i].theo_start), cvt_cycles_microsecs(rec_jitter[i].actual_start) ); } else { bucket[put_bucket+neg_num_buckets]++; } } } fp=fopen(OUTPUT_FILE, "w+"); if (!fp) { printf("error opening %s\n", OUTPUT_FILE); return; } for (i=0; i