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 12c6ffef11Skaustubhprabhu double 13c6ffef11Skaustubhprabhu timeval_to_double(struct timeval * tv) 1481a2df59Skaustubhprabhu { 1581a2df59Skaustubhprabhu double d; 1681a2df59Skaustubhprabhu 1781a2df59Skaustubhprabhu d = tv->tv_sec + tv->tv_usec / 1000000; 1881a2df59Skaustubhprabhu 1981a2df59Skaustubhprabhu return d; 2081a2df59Skaustubhprabhu } 2181a2df59Skaustubhprabhu 22c6ffef11Skaustubhprabhu double 23c6ffef11Skaustubhprabhu timeval_diff(struct timeval * tv0, struct timeval * tv1) 2481a2df59Skaustubhprabhu { 25*ff385f98Ssethdelliott return ((abs(tv1->tv_sec - tv0->tv_sec)) + (abs(tv1->tv_usec - tv0->tv_usec) / 1000000.0)); 2681a2df59Skaustubhprabhu } 2781a2df59Skaustubhprabhu 280fdaab07SJon Dugan int 290fdaab07SJon Dugan timer_expired(struct timer * tp) 300fdaab07SJon Dugan { 31e434aab6SBrian Tierney /* for timer with zero time */ 32*ff385f98Ssethdelliott if (tp->end.tv_sec == tp->begin.tv_sec && tp->end.tv_usec == tp->begin.tv_usec) { 33c5038eeaSkaustubhprabhu return 0; 3497887027SBrian Tierney } 35c5038eeaSkaustubhprabhu 360fdaab07SJon Dugan struct timeval now; 37*ff385f98Ssethdelliott int64_t end = 0, current = 0; 38da54a271SBrian Tierney 39*ff385f98Ssethdelliott if (gettimeofday(&now, NULL) < 0) { 40aa9ca268Skaustubhprabhu perror("gettimeofday"); 41aa9ca268Skaustubhprabhu return -1; 42aa9ca268Skaustubhprabhu } 43*ff385f98Ssethdelliott 4481a2df59Skaustubhprabhu end += tp->end.tv_sec * 1000000; 4581a2df59Skaustubhprabhu end += tp->end.tv_usec; 46aa9ca268Skaustubhprabhu 47aa9ca268Skaustubhprabhu current += now.tv_sec * 1000000; 48aa9ca268Skaustubhprabhu current += now.tv_usec; 49aa9ca268Skaustubhprabhu 50*ff385f98Ssethdelliott return current > end; 51aa9ca268Skaustubhprabhu } 52aa9ca268Skaustubhprabhu 53c6ffef11Skaustubhprabhu void 54c6ffef11Skaustubhprabhu update_timer(struct timer * tp, time_t sec, suseconds_t usec) 55c6ffef11Skaustubhprabhu { 56*ff385f98Ssethdelliott if (gettimeofday(&tp->begin, NULL) < 0) { 57c6ffef11Skaustubhprabhu perror("gettimeofday"); 58c6ffef11Skaustubhprabhu } 59*ff385f98Ssethdelliott 60c6ffef11Skaustubhprabhu tp->end.tv_sec = tp->begin.tv_sec + (time_t) sec; 61c6ffef11Skaustubhprabhu tp->end.tv_usec = tp->begin.tv_usec + (time_t) usec; 62c6ffef11Skaustubhprabhu 63c6ffef11Skaustubhprabhu tp->expired = timer_expired; 64c6ffef11Skaustubhprabhu } 65aa9ca268Skaustubhprabhu 660fdaab07SJon Dugan struct timer * 670fdaab07SJon Dugan new_timer(time_t sec, suseconds_t usec) 680fdaab07SJon Dugan { 69dfb2d9d4SBrian Tierney struct timer *tp = NULL; 70dfb2d9d4SBrian Tierney tp = (struct timer *) calloc(1, sizeof(struct timer)); 71*ff385f98Ssethdelliott if (tp == NULL) { 72f4e1c1d4SBrian Tierney perror("malloc"); 73f4e1c1d4SBrian Tierney return NULL; 74f4e1c1d4SBrian Tierney } 750fdaab07SJon Dugan 76*ff385f98Ssethdelliott if (gettimeofday(&tp->begin, NULL) < 0) { 770fdaab07SJon Dugan perror("gettimeofday"); 780fdaab07SJon Dugan return NULL; 790fdaab07SJon Dugan } 80dfb2d9d4SBrian Tierney 810fdaab07SJon Dugan tp->end.tv_sec = tp->begin.tv_sec + (time_t) sec; 820fdaab07SJon Dugan tp->end.tv_usec = tp->begin.tv_usec + (time_t) usec; 830fdaab07SJon Dugan 840fdaab07SJon Dugan tp->expired = timer_expired; 850fdaab07SJon Dugan 860fdaab07SJon Dugan return tp; 870fdaab07SJon Dugan } 880fdaab07SJon Dugan 890fdaab07SJon Dugan void 900fdaab07SJon Dugan free_timer(struct timer * tp) 910fdaab07SJon Dugan { 920fdaab07SJon Dugan free(tp); 930fdaab07SJon Dugan } 940fdaab07SJon Dugan 950fdaab07SJon Dugan int 960fdaab07SJon Dugan delay(int64_t ns) 970fdaab07SJon Dugan { 980fdaab07SJon Dugan struct timespec req, rem; 990fdaab07SJon Dugan 1000fdaab07SJon Dugan req.tv_sec = 0; 1010fdaab07SJon Dugan 102*ff385f98Ssethdelliott while (ns >= 1000000000L) { 1030fdaab07SJon Dugan ns -= 1000000000L; 1040fdaab07SJon Dugan req.tv_sec += 1; 1050fdaab07SJon Dugan } 1060fdaab07SJon Dugan 1070fdaab07SJon Dugan req.tv_nsec = ns; 1080fdaab07SJon Dugan 1090fdaab07SJon Dugan while (nanosleep(&req, &rem) == -1) 1100fdaab07SJon Dugan if (EINTR == errno) 1110fdaab07SJon Dugan memcpy(&req, &rem, sizeof rem); 1120fdaab07SJon Dugan else 1130fdaab07SJon Dugan return -1; 1140fdaab07SJon Dugan return 0; 1150fdaab07SJon Dugan } 1160fdaab07SJon Dugan 117a7253334SBrian Tierney # ifdef DELAY_SELECT_METHOD 118a7253334SBrian Tierney int 119a7253334SBrian Tierney delay(int us) 120a7253334SBrian Tierney { 121a7253334SBrian Tierney struct timeval tv; 122a7253334SBrian Tierney 123a7253334SBrian Tierney tv.tv_sec = 0; 124a7253334SBrian Tierney tv.tv_usec = us; 125a7253334SBrian Tierney (void) select(1, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &tv); 126a7253334SBrian Tierney return (1); 127a7253334SBrian Tierney } 128a7253334SBrian Tierney #endif 129a7253334SBrian Tierney 130c6ffef11Skaustubhprabhu int64_t 131c6ffef11Skaustubhprabhu timer_remaining(struct timer * tp) 132c6ffef11Skaustubhprabhu { 133c6ffef11Skaustubhprabhu struct timeval now; 1347dd1f0cdSkaustubhprabhu long int end_time = 0, current_time = 0, diff = 0; 135*ff385f98Ssethdelliott 136*ff385f98Ssethdelliott if (gettimeofday(&now, NULL) < 0) { 137c6ffef11Skaustubhprabhu perror("gettimeofday"); 138c6ffef11Skaustubhprabhu return -1; 139c6ffef11Skaustubhprabhu } 140*ff385f98Ssethdelliott 1417dd1f0cdSkaustubhprabhu end_time += tp->end.tv_sec * 1000000; 1427dd1f0cdSkaustubhprabhu end_time += tp->end.tv_usec; 143c6ffef11Skaustubhprabhu 1447dd1f0cdSkaustubhprabhu current_time += now.tv_sec * 1000000; 1457dd1f0cdSkaustubhprabhu current_time += now.tv_usec; 146c6ffef11Skaustubhprabhu 1477dd1f0cdSkaustubhprabhu diff = end_time - current_time; 148c6ffef11Skaustubhprabhu if (diff > 0) 149c6ffef11Skaustubhprabhu return diff; 150c6ffef11Skaustubhprabhu else 151c6ffef11Skaustubhprabhu return 0; 152c6ffef11Skaustubhprabhu } 153