1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <sys/time.h> 5 #include <sys/errno.h> 6 #include <sys/types.h> 7 #include <stdint.h> 8 #include <time.h> 9 10 #include "timer.h" 11 12 13 14 double 15 timeval_to_double(struct timeval * tv) 16 { 17 double d; 18 19 d = tv->tv_sec + tv->tv_usec / 1000000; 20 21 return d; 22 } 23 24 double 25 timeval_diff(struct timeval * tv0, struct timeval * tv1) 26 { 27 //return timeval_to_double(tv1) - timeval_to_double(tv0); 28 return (tv1->tv_sec - tv0->tv_sec) + abs(tv1->tv_usec - tv0->tv_usec) / 1000000.0; 29 } 30 31 int 32 timer_expired(struct timer * tp) 33 { 34 /* for timer with zero time */ 35 if (tp->end.tv_sec == tp->begin.tv_sec && tp->end.tv_usec == tp->begin.tv_usec) 36 return 0; 37 38 struct timeval now; 39 int64_t end = 0, current = 0, diff = 0; 40 if (gettimeofday(&now, NULL) < 0) 41 { 42 perror("gettimeofday"); 43 return -1; 44 } 45 end += tp->end.tv_sec * 1000000; 46 end += tp->end.tv_usec; 47 48 current += now.tv_sec * 1000000; 49 current += now.tv_usec; 50 51 diff = end - current; 52 53 return diff <= 0; 54 55 /* 56 * currently using microsecond limit. Else we need to introduce timespec 57 * instread of timeval 58 */ 59 } 60 61 void 62 update_timer(struct timer * tp, time_t sec, suseconds_t usec) 63 { 64 if (gettimeofday(&tp->begin, NULL) < 0) 65 { 66 perror("gettimeofday"); 67 } 68 memcpy(&tp->end, &tp->begin, sizeof(struct timer)); 69 tp->end.tv_sec = tp->begin.tv_sec + (time_t) sec; 70 tp->end.tv_usec = tp->begin.tv_usec + (time_t) usec; 71 72 tp->expired = timer_expired; 73 } 74 75 struct timer * 76 new_timer(time_t sec, suseconds_t usec) 77 { 78 struct timer *tp; 79 tp = (struct timer *) malloc(sizeof(struct timer)); 80 81 if (gettimeofday(&tp->begin, NULL) < 0) 82 { 83 perror("gettimeofday"); 84 return NULL; 85 } 86 memcpy(&tp->end, &tp->begin, sizeof(struct timer)); 87 tp->end.tv_sec = tp->begin.tv_sec + (time_t) sec; 88 tp->end.tv_usec = tp->begin.tv_usec + (time_t) usec; 89 90 tp->expired = timer_expired; 91 92 return tp; 93 } 94 95 void 96 free_timer(struct timer * tp) 97 { 98 free(tp); 99 } 100 101 int 102 delay(int64_t ns) 103 { 104 struct timespec req, rem; 105 106 req.tv_sec = 0; 107 108 while (ns >= 1000000000L) 109 { 110 ns -= 1000000000L; 111 req.tv_sec += 1; 112 } 113 114 req.tv_nsec = ns; 115 116 while (nanosleep(&req, &rem) == -1) 117 if (EINTR == errno) 118 memcpy(&req, &rem, sizeof rem); 119 else 120 return -1; 121 122 return 0; 123 } 124 125 int64_t 126 timer_remaining(struct timer * tp) 127 { 128 struct timeval now; 129 long int end_time = 0, current_time = 0, diff = 0; 130 if (gettimeofday(&now, NULL) < 0) 131 { 132 perror("gettimeofday"); 133 return -1; 134 } 135 end_time += tp->end.tv_sec * 1000000; 136 end_time += tp->end.tv_usec; 137 138 current_time += now.tv_sec * 1000000; 139 current_time += now.tv_usec; 140 141 diff = end_time - current_time; 142 if (diff > 0) 143 return diff; 144 else 145 return 0; 146 } 147