long long diff_timespec(struct timespec start, struct timespec end) { long long start_ns, end_ns; start_ns = ts_to_nsec(start); end_ns = ts_to_nsec(end); return end_ns - start_ns; }
void get_monotonic_and_raw(struct timespec *mon, struct timespec *raw) { struct timespec start, mid, end; long long diff = 0, tmp; int i; for (i = 0; i < 3; i++) { long long newdiff; clock_gettime(CLOCK_MONOTONIC, &start); clock_gettime(CLOCK_MONOTONIC_RAW, &mid); clock_gettime(CLOCK_MONOTONIC, &end); newdiff = diff_timespec(start, end); if (diff == 0 || newdiff < diff) { diff = newdiff; *raw = mid; tmp = (ts_to_nsec(start) + ts_to_nsec(end))/2; *mon = nsec_to_ts(tmp); } } }
static jack_nframes_t dummy_driver_wait (dummy_driver_t *driver, int extra_fd, int *status, float *delayed_usecs) { jack_nframes_t nframes = driver->period_size; struct timespec now; *status = 0; /* this driver doesn't work so well if we report a delay */ *delayed_usecs = 0; /* lie about it */ clock_gettime(CLOCK_REALTIME, &now); if (cmp_lt_ts(driver->next_wakeup, now)) { if (driver->next_wakeup.tv_sec == 0) { /* first time through */ clock_gettime(CLOCK_REALTIME, &driver->next_wakeup); } else if ((ts_to_nsec(now) - ts_to_nsec(driver->next_wakeup))/1000LL > (PRETEND_BUFFER_SIZE * 1000000LL / driver->sample_rate)) { /* xrun */ jack_error("**** dummy: xrun of %ju usec", (uintmax_t)(ts_to_nsec(now) - ts_to_nsec(driver->next_wakeup))/1000LL); nframes = 0; driver->next_wakeup.tv_sec = 0; } else { /* late, but handled by our "buffer"; try to * get back on track */ } driver->next_wakeup = add_ts(driver->next_wakeup, driver->wait_time); } else { if(clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &driver->next_wakeup, NULL)) { jack_error("error while sleeping"); *status = -1; } else { clock_gettime(CLOCK_REALTIME, &now); // guaranteed to sleep long enough for this to be correct *delayed_usecs = (ts_to_nsec(now) - ts_to_nsec(driver->next_wakeup)); *delayed_usecs /= 1000.0; } driver->next_wakeup = add_ts(driver->next_wakeup, driver->wait_time); } driver->last_wait_ust = driver->engine->get_microseconds (); driver->engine->transport_cycle_start (driver->engine, driver->last_wait_ust); return nframes; }
static inline struct timespec add_ts (struct timespec ts, uint64_t add_nsecs) { uint64_t nsecs = ts_to_nsec(ts); nsecs += add_nsecs; return nsec_to_ts (nsecs); }
int main(int argc, char *argv[]) { int/* i,*/ rc; struct timespec ts, p_ts; nsec_t s_time, e_time, diff_time; nsec_t max_time = START_MAX; // cpu_set_t mask; struct sched_param param; time_t tt; unsigned int wi; struct sigaction sact; setup(); /* Set signal handler for SIGALRM */ sigfillset(&sact.sa_mask); sact.sa_handler = alarm_handler; rc = sigaction(SIGALRM, &sact, NULL); if (rc) { perror("sigaction"); exit(1); } /* CPU_ZERO(&mask); CPU_SET(0, &mask); rc = sched_setaffinity(0, sizeof(mask), &mask); if (rc) { perror("sched_setaffinity"); exit(1); } */ rt_init("hw:t:", parse_args, argc, argv); mlockall(MCL_CURRENT|MCL_FUTURE); if (max_window > 0) { printf("%d iterations in max calculation window\n", max_window); } param.sched_priority = sched_get_priority_min(SCHED_FIFO) + 80; rc = sched_setscheduler(0, SCHED_FIFO, ¶m); if (rc) { perror("sched_setscheduler"); exit(1); } rc = clock_gettime(CLOCK_TO_USE, &p_ts); if (rc) { perror("clock_gettime"); exit(1); } /* Set alarm for test duration, if specified */ if (test_duration > 0) { rc = alarm(test_duration * 60 * 60 ); if (rc) { perror("alarm"); exit(1); } } wi = 0; while(test_stop != 1) { rc = clock_gettime(CLOCK_TO_USE, &p_ts); rc = clock_gettime(CLOCK_TO_USE, &ts); if (rc) { perror("clock_gettime"); exit(1); } ts_to_nsec(&p_ts, &s_time); ts_to_nsec(&ts, &e_time); diff_time = e_time - s_time; if (max_window > 0 || ((diff_time > max_time) || (diff_time > REPORT_MIN))) { if (diff_time > max_time) max_time = diff_time; if (max_window == 0 || ++wi == max_window) { tt = (time_t)ts.tv_sec; printf("Task delayed for %lld nsec!!! %s", max_time, ctime(&tt)); fflush(stdout); if (wi == max_window) { max_time = 0; wi = 0; } } } } return 0; }
static inline struct timespec add_ts(struct timespec ts, unsigned int usecs) { unsigned long long nsecs = ts_to_nsec(ts); nsecs += usecs * 1000LL; return nsec_to_ts(nsecs); }
int main(int argc, char* argv[]) { struct sched_param sp; sp.sched_priority = 30; sched_setscheduler(0, SCHED_FIFO, &sp); std::cout << "--------------------------------------------------------------------------------" << std::endl; std::cout << "" << std::endl; std::cout << "" << std::endl; std::cout << "Get time using clock_gettime(CLOCK_MONOTONIC):" << std::endl; int64_t timeall = 0; timespec* times1 = new timespec[ITERATION_NUM]; for(int i=0;i<ITERATION_NUM;i++){ gettime(×1[i]); } for(int i=0;i<ITERATION_NUM-1;i++){ timespec m_elapsed = TIMESPEC_INITIALIZER; ts_sub(×1[i+1], ×1[i], &m_elapsed); timeall += ts_to_nsec(&m_elapsed); //std::cout << i << ": " << ts_to_nsec(&m_elapsed) << std::endl; } double clockmon_avg = ((double)timeall)/(ITERATION_NUM-1); std::cout << "clock_gettime(CLOCK_MONOTONIC) AVG: " << clockmon_avg << " nsec" << std::endl; std::cout << "--------------------------------------------------------------------------------" << std::endl; std::cout << "" << std::endl; std::cout << "" << std::endl; std::cout << "Get time using RDTSC:" << std::endl; timeall = 0; timespec* times2 = new timespec[ITERATION_NUM]; for(int i=0;i<ITERATION_NUM;i++){ gettimerdtsc(×2[i]); } for(int i=0;i<ITERATION_NUM-1;i++){ timespec m_elapsed = TIMESPEC_INITIALIZER; ts_sub(×2[i+1], ×2[i], &m_elapsed); if (i > 0) timeall += ts_to_nsec(&m_elapsed); //std::cout << i << ": " << ts_to_nsec(&m_elapsed) << std::endl; } double rdtsc_avg = ((double)timeall)/(ITERATION_NUM-2); std::cout << "RDTSC AVG: " << rdtsc_avg << " nsec" << std::endl; std::cout << "--------------------------------------------------------------------------------" << std::endl; std::cout << "" << std::endl; std::cout << "" << std::endl; std::cout << "Get time using gettimeofday:" << std::endl; timeall = 0; timeval* times = new timeval[ITERATION_NUM]; for(int i=0;i<ITERATION_NUM;i++){ gettime(×[i]); } for(int i=0;i<ITERATION_NUM-1;i++){ timeval m_elapsed = TIMEVAL_INITIALIZER; tv_sub(×[i+1], ×[i], &m_elapsed); timeall += tv_to_nsec(&m_elapsed); //std::cout << i << ": " << tv_to_nsec(&m_elapsed) << std::endl; } double timeofday_avg = ((double)timeall)/(ITERATION_NUM-1); std::cout << "gettimeofday AVG: " << timeofday_avg << " nsec" << std::endl; std::cout << "--------------------------------------------------------------------------------" << std::endl; std::cout << "" << std::endl; std::cout << "" << std::endl; std::cout << "Get time using clock_gettime(CLOCK_MONOTONIC) - low pps:" << std::endl; timeall = 0; for(int i=0;i<ITERATION_NUM_LOW_PPS;i++){ usleep(LOW_PPS_SLEEP_USEC); timespec m_start = TIMESPEC_INITIALIZER; timespec m_elapsed = TIMESPEC_INITIALIZER; timespec m_current = TIMESPEC_INITIALIZER; gettime(&m_start); gettime(&m_current); ts_sub(&m_current, &m_start, &m_elapsed); timeall += ts_to_nsec(&m_elapsed); //std::cout << i << ": " << ts_to_nsec(&m_elapsed) << std::endl; } double clockmon_avg_lowpps = ((double)timeall)/(ITERATION_NUM_LOW_PPS-1); std::cout << "clock_gettime(CLOCK_MONOTONIC) - low pps AVG: " << clockmon_avg_lowpps << " nsec" << std::endl; std::cout << "--------------------------------------------------------------------------------" << std::endl; std::cout << "" << std::endl; std::cout << "" << std::endl; std::cout << "Get time using RDTSC - low pps:" << std::endl; timeall = 0; for(int i=0;i<ITERATION_NUM_LOW_PPS;i++){ usleep(LOW_PPS_SLEEP_USEC); timespec m_start = TIMESPEC_INITIALIZER; timespec m_elapsed = TIMESPEC_INITIALIZER; timespec m_current = TIMESPEC_INITIALIZER; gettimerdtsc(&m_start); gettimerdtsc(&m_current); ts_sub(&m_current, &m_start, &m_elapsed); if(i > 0) timeall += ts_to_nsec(&m_elapsed); //std::cout << i << ": " << ts_to_nsec(&m_elapsed) << std::endl; } double rdtsc_avg_lowpps = ((double)timeall)/(ITERATION_NUM_LOW_PPS-2); std::cout << "RDTSC - low pps AVG: " << rdtsc_avg_lowpps << " nsec" << std::endl; std::cout << "--------------------------------------------------------------------------------" << std::endl; std::cout << "" << std::endl; std::cout << "" << std::endl; std::cout << "Get time using gettimeofday - low pps:" << std::endl; timeall = 0; for(int i=0;i<ITERATION_NUM_LOW_PPS;i++){ usleep(LOW_PPS_SLEEP_USEC); timeval start = TIMEVAL_INITIALIZER, current = TIMEVAL_INITIALIZER, elapsed = TIMEVAL_INITIALIZER; gettime(&start); gettime(¤t); tv_sub(¤t, &start, &elapsed); timeall += tv_to_nsec(&elapsed); //std::cout << i << ": " << tv_to_nsec(&elapsed) << std::endl; } double timeofday_avg_lowpps = ((double)timeall)/(ITERATION_NUM_LOW_PPS-1); std::cout << "gettimeofday - low pps AVG: " << timeofday_avg_lowpps << " nsec" << std::endl; std::cout << "--------------------------------------------------------------------------------" << std::endl; std::cout << "" << std::endl; std::cout << "" << std::endl; std::cout << "" << std::endl; std::cout << "SUMMARY:" << std::endl; std::cout << "" << std::endl; std::cout << "Timer resolution:" << std::endl; std::cout << "------------------" << std::endl; std::cout << "clock_gettime(CLOCK_MONOTONIC) AVG: " << clockmon_avg << " nsec" << std::endl; std::cout << "RDTSC AVG: " << rdtsc_avg << " nsec" << std::endl; std::cout << "gettimeofday AVG: " << timeofday_avg << " nsec" << std::endl; std::cout << "" << std::endl; std::cout << "Timer resolution - 100 samples per sec:" << std::endl; std::cout << "----------------------------------------" << std::endl; std::cout << "clock_gettime(CLOCK_MONOTONIC) - low pps AVG: " << clockmon_avg_lowpps << " nsec" << std::endl; std::cout << "RDTSC - low pps AVG: " << rdtsc_avg_lowpps << " nsec" << std::endl; std::cout << "gettimeofday - low pps AVG: " << timeofday_avg_lowpps << " nsec" << std::endl; delete [] times; delete [] times1; delete [] times2; return 0; }