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 { 27*f4ca73a1Skaustubhprabhu //return timeval_to_double(tv1) - timeval_to_double(tv0); 28*f4ca73a1Skaustubhprabhu 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 { 340fdaab07SJon Dugan struct timeval now; 3581a2df59Skaustubhprabhu int64_t end = 0, current= 0, diff= 0; 36aa9ca268Skaustubhprabhu if(gettimeofday(&now, NULL) < 0) { 37aa9ca268Skaustubhprabhu perror("gettimeofday"); 38aa9ca268Skaustubhprabhu return -1; 39aa9ca268Skaustubhprabhu } 40aa9ca268Skaustubhprabhu 4181a2df59Skaustubhprabhu end+= tp->end.tv_sec * 1000000 ; 4281a2df59Skaustubhprabhu end+= tp->end.tv_usec; 43aa9ca268Skaustubhprabhu 44aa9ca268Skaustubhprabhu current+= now.tv_sec * 1000000 ; 45aa9ca268Skaustubhprabhu current+= now.tv_usec; 46aa9ca268Skaustubhprabhu 4781a2df59Skaustubhprabhu diff = end - current; 48aa9ca268Skaustubhprabhu 4981a2df59Skaustubhprabhu return diff <= 0; 50aa9ca268Skaustubhprabhu 51c6ffef11Skaustubhprabhu // currently using microsecond limit. Else we need to introduce timespec instread of timeval 52aa9ca268Skaustubhprabhu } 53aa9ca268Skaustubhprabhu 54c6ffef11Skaustubhprabhu void 55c6ffef11Skaustubhprabhu update_timer(struct timer *tp, time_t sec, suseconds_t usec) 56c6ffef11Skaustubhprabhu { 57c6ffef11Skaustubhprabhu if(gettimeofday(&tp->begin, NULL) < 0) { 58c6ffef11Skaustubhprabhu perror("gettimeofday"); 59c6ffef11Skaustubhprabhu } 60c6ffef11Skaustubhprabhu 61c6ffef11Skaustubhprabhu memcpy(&tp->end, &tp->begin, sizeof(struct timer)); 62c6ffef11Skaustubhprabhu tp->end.tv_sec = tp->begin.tv_sec + (time_t) sec; 63c6ffef11Skaustubhprabhu tp->end.tv_usec = tp->begin.tv_usec + (time_t) usec; 64c6ffef11Skaustubhprabhu 65c6ffef11Skaustubhprabhu tp->expired = timer_expired; 66c6ffef11Skaustubhprabhu } 67aa9ca268Skaustubhprabhu 680fdaab07SJon Dugan struct timer * 690fdaab07SJon Dugan new_timer(time_t sec, suseconds_t usec) 700fdaab07SJon Dugan { 710fdaab07SJon Dugan struct timer *tp; 720fdaab07SJon Dugan tp = (struct timer *) malloc(sizeof(struct timer)); 730fdaab07SJon Dugan 740fdaab07SJon Dugan if(gettimeofday(&tp->begin, NULL) < 0) { 750fdaab07SJon Dugan perror("gettimeofday"); 760fdaab07SJon Dugan return NULL; 770fdaab07SJon Dugan } 780fdaab07SJon Dugan 790fdaab07SJon Dugan memcpy(&tp->end, &tp->begin, sizeof(struct timer)); 800fdaab07SJon Dugan tp->end.tv_sec = tp->begin.tv_sec + (time_t) sec; 810fdaab07SJon Dugan tp->end.tv_usec = tp->begin.tv_usec + (time_t) usec; 820fdaab07SJon Dugan 830fdaab07SJon Dugan tp->expired = timer_expired; 840fdaab07SJon Dugan 850fdaab07SJon Dugan return tp; 860fdaab07SJon Dugan } 870fdaab07SJon Dugan 880fdaab07SJon Dugan void 890fdaab07SJon Dugan free_timer(struct timer *tp) 900fdaab07SJon Dugan { 910fdaab07SJon Dugan free(tp); 920fdaab07SJon Dugan } 930fdaab07SJon Dugan 940fdaab07SJon Dugan int 950fdaab07SJon Dugan delay(int64_t ns) 960fdaab07SJon Dugan { 970fdaab07SJon Dugan struct timespec req, rem; 980fdaab07SJon Dugan 990fdaab07SJon Dugan req.tv_sec = 0; 1000fdaab07SJon Dugan 1010fdaab07SJon Dugan while(ns >= 1000000000L) 1020fdaab07SJon Dugan { 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 1150fdaab07SJon Dugan return 0; 1160fdaab07SJon Dugan } 1170fdaab07SJon Dugan 118c6ffef11Skaustubhprabhu int64_t 119c6ffef11Skaustubhprabhu timer_remaining(struct timer *tp) 120c6ffef11Skaustubhprabhu { 121c6ffef11Skaustubhprabhu struct timeval now; 1227dd1f0cdSkaustubhprabhu long int end_time = 0, current_time= 0, diff= 0; 123c6ffef11Skaustubhprabhu if(gettimeofday(&now, NULL) < 0) { 124c6ffef11Skaustubhprabhu perror("gettimeofday"); 125c6ffef11Skaustubhprabhu return -1; 126c6ffef11Skaustubhprabhu } 127c6ffef11Skaustubhprabhu 1287dd1f0cdSkaustubhprabhu end_time+= tp->end.tv_sec * 1000000 ; 1297dd1f0cdSkaustubhprabhu end_time+= tp->end.tv_usec; 130c6ffef11Skaustubhprabhu 1317dd1f0cdSkaustubhprabhu current_time+= now.tv_sec * 1000000 ; 1327dd1f0cdSkaustubhprabhu current_time+= now.tv_usec; 133c6ffef11Skaustubhprabhu 1347dd1f0cdSkaustubhprabhu diff = end_time - current_time; 135c6ffef11Skaustubhprabhu if(diff > 0) 136c6ffef11Skaustubhprabhu return diff; 137c6ffef11Skaustubhprabhu else 138c6ffef11Skaustubhprabhu return 0; 139c6ffef11Skaustubhprabhu } 140c6ffef11Skaustubhprabhu 1415f0a15f9Skaustubhprabhu 142