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 14*c6ffef11Skaustubhprabhu double 15*c6ffef11Skaustubhprabhu 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 24*c6ffef11Skaustubhprabhu double 25*c6ffef11Skaustubhprabhu timeval_diff(struct timeval *tv0, struct timeval *tv1) 2681a2df59Skaustubhprabhu { 2781a2df59Skaustubhprabhu return timeval_to_double(tv1) - timeval_to_double(tv0); 2881a2df59Skaustubhprabhu } 2981a2df59Skaustubhprabhu 300fdaab07SJon Dugan int 310fdaab07SJon Dugan timer_expired(struct timer *tp) 320fdaab07SJon Dugan { 330fdaab07SJon Dugan struct timeval now; 3481a2df59Skaustubhprabhu int64_t end = 0, current= 0, diff= 0; 35aa9ca268Skaustubhprabhu if(gettimeofday(&now, NULL) < 0) { 36aa9ca268Skaustubhprabhu perror("gettimeofday"); 37aa9ca268Skaustubhprabhu return -1; 38aa9ca268Skaustubhprabhu } 39aa9ca268Skaustubhprabhu 4081a2df59Skaustubhprabhu end+= tp->end.tv_sec * 1000000 ; 4181a2df59Skaustubhprabhu end+= tp->end.tv_usec; 42aa9ca268Skaustubhprabhu 43aa9ca268Skaustubhprabhu current+= now.tv_sec * 1000000 ; 44aa9ca268Skaustubhprabhu current+= now.tv_usec; 45aa9ca268Skaustubhprabhu 4681a2df59Skaustubhprabhu diff = end - current; 47aa9ca268Skaustubhprabhu 4881a2df59Skaustubhprabhu return diff <= 0; 49aa9ca268Skaustubhprabhu 50*c6ffef11Skaustubhprabhu // currently using microsecond limit. Else we need to introduce timespec instread of timeval 51aa9ca268Skaustubhprabhu } 52aa9ca268Skaustubhprabhu 53*c6ffef11Skaustubhprabhu void 54*c6ffef11Skaustubhprabhu update_timer(struct timer *tp, time_t sec, suseconds_t usec) 55*c6ffef11Skaustubhprabhu { 56*c6ffef11Skaustubhprabhu if(gettimeofday(&tp->begin, NULL) < 0) { 57*c6ffef11Skaustubhprabhu perror("gettimeofday"); 58*c6ffef11Skaustubhprabhu } 59*c6ffef11Skaustubhprabhu 60*c6ffef11Skaustubhprabhu memcpy(&tp->end, &tp->begin, sizeof(struct timer)); 61*c6ffef11Skaustubhprabhu tp->end.tv_sec = tp->begin.tv_sec + (time_t) sec; 62*c6ffef11Skaustubhprabhu tp->end.tv_usec = tp->begin.tv_usec + (time_t) usec; 63*c6ffef11Skaustubhprabhu 64*c6ffef11Skaustubhprabhu tp->expired = timer_expired; 65*c6ffef11Skaustubhprabhu } 66aa9ca268Skaustubhprabhu 670fdaab07SJon Dugan struct timer * 680fdaab07SJon Dugan new_timer(time_t sec, suseconds_t usec) 690fdaab07SJon Dugan { 700fdaab07SJon Dugan struct timer *tp; 710fdaab07SJon Dugan tp = (struct timer *) malloc(sizeof(struct timer)); 720fdaab07SJon Dugan 730fdaab07SJon Dugan if(gettimeofday(&tp->begin, NULL) < 0) { 740fdaab07SJon Dugan perror("gettimeofday"); 750fdaab07SJon Dugan return NULL; 760fdaab07SJon Dugan } 770fdaab07SJon Dugan 780fdaab07SJon Dugan memcpy(&tp->end, &tp->begin, sizeof(struct timer)); 790fdaab07SJon Dugan tp->end.tv_sec = tp->begin.tv_sec + (time_t) sec; 800fdaab07SJon Dugan tp->end.tv_usec = tp->begin.tv_usec + (time_t) usec; 810fdaab07SJon Dugan 820fdaab07SJon Dugan tp->expired = timer_expired; 830fdaab07SJon Dugan 840fdaab07SJon Dugan return tp; 850fdaab07SJon Dugan } 860fdaab07SJon Dugan 870fdaab07SJon Dugan void 880fdaab07SJon Dugan free_timer(struct timer *tp) 890fdaab07SJon Dugan { 900fdaab07SJon Dugan free(tp); 910fdaab07SJon Dugan } 920fdaab07SJon Dugan 930fdaab07SJon Dugan int 940fdaab07SJon Dugan delay(int64_t ns) 950fdaab07SJon Dugan { 960fdaab07SJon Dugan struct timespec req, rem; 970fdaab07SJon Dugan 980fdaab07SJon Dugan req.tv_sec = 0; 990fdaab07SJon Dugan 1000fdaab07SJon Dugan while(ns >= 1000000000L) 1010fdaab07SJon Dugan { 1020fdaab07SJon Dugan ns -= 1000000000L; 1030fdaab07SJon Dugan req.tv_sec += 1; 1040fdaab07SJon Dugan } 1050fdaab07SJon Dugan 1060fdaab07SJon Dugan req.tv_nsec = ns; 1070fdaab07SJon Dugan 1080fdaab07SJon Dugan while(nanosleep(&req, &rem) == -1 ) 1090fdaab07SJon Dugan if (EINTR == errno) 1100fdaab07SJon Dugan memcpy(&req, &rem, sizeof rem); 1110fdaab07SJon Dugan else 1120fdaab07SJon Dugan return -1; 1130fdaab07SJon Dugan 1140fdaab07SJon Dugan return 0; 1150fdaab07SJon Dugan } 1160fdaab07SJon Dugan 117*c6ffef11Skaustubhprabhu int64_t 118*c6ffef11Skaustubhprabhu timer_remaining(struct timer *tp) 119*c6ffef11Skaustubhprabhu { 120*c6ffef11Skaustubhprabhu struct timeval now; 121*c6ffef11Skaustubhprabhu int64_t end = 0, current= 0, diff= 0; 122*c6ffef11Skaustubhprabhu if(gettimeofday(&now, NULL) < 0) { 123*c6ffef11Skaustubhprabhu perror("gettimeofday"); 124*c6ffef11Skaustubhprabhu return -1; 125*c6ffef11Skaustubhprabhu } 126*c6ffef11Skaustubhprabhu 127*c6ffef11Skaustubhprabhu end+= tp->end.tv_sec * 1000000 ; 128*c6ffef11Skaustubhprabhu end+= tp->end.tv_usec; 129*c6ffef11Skaustubhprabhu 130*c6ffef11Skaustubhprabhu current+= now.tv_sec * 1000000 ; 131*c6ffef11Skaustubhprabhu current+= now.tv_usec; 132*c6ffef11Skaustubhprabhu 133*c6ffef11Skaustubhprabhu diff = end - current; 134*c6ffef11Skaustubhprabhu if(diff > 0) 135*c6ffef11Skaustubhprabhu return diff; 136*c6ffef11Skaustubhprabhu else 137*c6ffef11Skaustubhprabhu return 0; 138*c6ffef11Skaustubhprabhu } 139*c6ffef11Skaustubhprabhu 1405f0a15f9Skaustubhprabhu 141