10fdaab07SJon Dugan #include <stdio.h> 20fdaab07SJon Dugan #include <stdlib.h> 30fdaab07SJon Dugan #include <string.h> 40fdaab07SJon Dugan #include <sys/time.h> 50fdaab07SJon Dugan #include <sys/errno.h> 60fdaab07SJon Dugan #include <sys/types.h> 70fdaab07SJon Dugan #include <stdint.h> 80fdaab07SJon Dugan #include <time.h> 90fdaab07SJon Dugan 100fdaab07SJon Dugan #include "timer.h" 110fdaab07SJon Dugan 1281a2df59Skaustubhprabhu 1381a2df59Skaustubhprabhu 14c6ffef11Skaustubhprabhu double 15c6ffef11Skaustubhprabhu timeval_to_double(struct timeval * tv) 1681a2df59Skaustubhprabhu { 1781a2df59Skaustubhprabhu double d; 1881a2df59Skaustubhprabhu 1981a2df59Skaustubhprabhu d = tv->tv_sec + tv->tv_usec / 1000000; 2081a2df59Skaustubhprabhu 2181a2df59Skaustubhprabhu return d; 2281a2df59Skaustubhprabhu } 2381a2df59Skaustubhprabhu 24c6ffef11Skaustubhprabhu double 25c6ffef11Skaustubhprabhu timeval_diff(struct timeval * tv0, struct timeval * tv1) 2681a2df59Skaustubhprabhu { 27f4ca73a1Skaustubhprabhu //return timeval_to_double(tv1) - timeval_to_double(tv0); 28f4ca73a1Skaustubhprabhu return (tv1->tv_sec - tv0->tv_sec) + abs(tv1->tv_usec - tv0->tv_usec) / 1000000.0; 2981a2df59Skaustubhprabhu } 3081a2df59Skaustubhprabhu 310fdaab07SJon Dugan int 320fdaab07SJon Dugan timer_expired(struct timer * tp) 330fdaab07SJon Dugan { 34*e434aab6SBrian Tierney /* for timer with zero time */ 35c5038eeaSkaustubhprabhu if (tp->end.tv_sec == tp->begin.tv_sec && tp->end.tv_usec == tp->begin.tv_usec) 36c5038eeaSkaustubhprabhu return 0; 37c5038eeaSkaustubhprabhu 380fdaab07SJon Dugan struct timeval now; 3981a2df59Skaustubhprabhu int64_t end = 0, current = 0, diff = 0; 40*e434aab6SBrian Tierney if (gettimeofday(&now, NULL) < 0) 41*e434aab6SBrian Tierney { 42aa9ca268Skaustubhprabhu perror("gettimeofday"); 43aa9ca268Skaustubhprabhu return -1; 44aa9ca268Skaustubhprabhu } 4581a2df59Skaustubhprabhu end += tp->end.tv_sec * 1000000; 4681a2df59Skaustubhprabhu end += tp->end.tv_usec; 47aa9ca268Skaustubhprabhu 48aa9ca268Skaustubhprabhu current += now.tv_sec * 1000000; 49aa9ca268Skaustubhprabhu current += now.tv_usec; 50aa9ca268Skaustubhprabhu 5181a2df59Skaustubhprabhu diff = end - current; 52aa9ca268Skaustubhprabhu 5381a2df59Skaustubhprabhu return diff <= 0; 54aa9ca268Skaustubhprabhu 55*e434aab6SBrian Tierney /* 56*e434aab6SBrian Tierney * currently using microsecond limit. Else we need to introduce timespec 57*e434aab6SBrian Tierney * instread of timeval 58*e434aab6SBrian Tierney */ 59aa9ca268Skaustubhprabhu } 60aa9ca268Skaustubhprabhu 61c6ffef11Skaustubhprabhu void 62c6ffef11Skaustubhprabhu update_timer(struct timer * tp, time_t sec, suseconds_t usec) 63c6ffef11Skaustubhprabhu { 64*e434aab6SBrian Tierney if (gettimeofday(&tp->begin, NULL) < 0) 65*e434aab6SBrian Tierney { 66c6ffef11Skaustubhprabhu perror("gettimeofday"); 67c6ffef11Skaustubhprabhu } 68c6ffef11Skaustubhprabhu memcpy(&tp->end, &tp->begin, sizeof(struct timer)); 69c6ffef11Skaustubhprabhu tp->end.tv_sec = tp->begin.tv_sec + (time_t) sec; 70c6ffef11Skaustubhprabhu tp->end.tv_usec = tp->begin.tv_usec + (time_t) usec; 71c6ffef11Skaustubhprabhu 72c6ffef11Skaustubhprabhu tp->expired = timer_expired; 73c6ffef11Skaustubhprabhu } 74aa9ca268Skaustubhprabhu 750fdaab07SJon Dugan struct timer * 760fdaab07SJon Dugan new_timer(time_t sec, suseconds_t usec) 770fdaab07SJon Dugan { 780fdaab07SJon Dugan struct timer *tp; 790fdaab07SJon Dugan tp = (struct timer *) malloc(sizeof(struct timer)); 800fdaab07SJon Dugan 81*e434aab6SBrian Tierney if (gettimeofday(&tp->begin, NULL) < 0) 82*e434aab6SBrian Tierney { 830fdaab07SJon Dugan perror("gettimeofday"); 840fdaab07SJon Dugan return NULL; 850fdaab07SJon Dugan } 860fdaab07SJon Dugan memcpy(&tp->end, &tp->begin, sizeof(struct timer)); 870fdaab07SJon Dugan tp->end.tv_sec = tp->begin.tv_sec + (time_t) sec; 880fdaab07SJon Dugan tp->end.tv_usec = tp->begin.tv_usec + (time_t) usec; 890fdaab07SJon Dugan 900fdaab07SJon Dugan tp->expired = timer_expired; 910fdaab07SJon Dugan 920fdaab07SJon Dugan return tp; 930fdaab07SJon Dugan } 940fdaab07SJon Dugan 950fdaab07SJon Dugan void 960fdaab07SJon Dugan free_timer(struct timer * tp) 970fdaab07SJon Dugan { 980fdaab07SJon Dugan free(tp); 990fdaab07SJon Dugan } 1000fdaab07SJon Dugan 1010fdaab07SJon Dugan int 1020fdaab07SJon Dugan delay(int64_t ns) 1030fdaab07SJon Dugan { 1040fdaab07SJon Dugan struct timespec req, rem; 1050fdaab07SJon Dugan 1060fdaab07SJon Dugan req.tv_sec = 0; 1070fdaab07SJon Dugan 1080fdaab07SJon Dugan while (ns >= 1000000000L) 1090fdaab07SJon Dugan { 1100fdaab07SJon Dugan ns -= 1000000000L; 1110fdaab07SJon Dugan req.tv_sec += 1; 1120fdaab07SJon Dugan } 1130fdaab07SJon Dugan 1140fdaab07SJon Dugan req.tv_nsec = ns; 1150fdaab07SJon Dugan 1160fdaab07SJon Dugan while (nanosleep(&req, &rem) == -1) 1170fdaab07SJon Dugan if (EINTR == errno) 1180fdaab07SJon Dugan memcpy(&req, &rem, sizeof rem); 1190fdaab07SJon Dugan else 1200fdaab07SJon Dugan return -1; 1210fdaab07SJon Dugan 1220fdaab07SJon Dugan return 0; 1230fdaab07SJon Dugan } 1240fdaab07SJon Dugan 125c6ffef11Skaustubhprabhu int64_t 126c6ffef11Skaustubhprabhu timer_remaining(struct timer * tp) 127c6ffef11Skaustubhprabhu { 128c6ffef11Skaustubhprabhu struct timeval now; 1297dd1f0cdSkaustubhprabhu long int end_time = 0, current_time = 0, diff = 0; 130*e434aab6SBrian Tierney if (gettimeofday(&now, NULL) < 0) 131*e434aab6SBrian Tierney { 132c6ffef11Skaustubhprabhu perror("gettimeofday"); 133c6ffef11Skaustubhprabhu return -1; 134c6ffef11Skaustubhprabhu } 1357dd1f0cdSkaustubhprabhu end_time += tp->end.tv_sec * 1000000; 1367dd1f0cdSkaustubhprabhu end_time += tp->end.tv_usec; 137c6ffef11Skaustubhprabhu 1387dd1f0cdSkaustubhprabhu current_time += now.tv_sec * 1000000; 1397dd1f0cdSkaustubhprabhu current_time += now.tv_usec; 140c6ffef11Skaustubhprabhu 1417dd1f0cdSkaustubhprabhu diff = end_time - current_time; 142c6ffef11Skaustubhprabhu if (diff > 0) 143c6ffef11Skaustubhprabhu return diff; 144c6ffef11Skaustubhprabhu else 145c6ffef11Skaustubhprabhu return 0; 146c6ffef11Skaustubhprabhu } 147