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 return 0; 122 } 123 124 # ifdef DELAY_SELECT_METHOD 125 int 126 delay(int us) 127 { 128 struct timeval tv; 129 130 tv.tv_sec = 0; 131 tv.tv_usec = us; 132 (void) select(1, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &tv); 133 return (1); 134 } 135 #endif 136 137 int64_t 138 timer_remaining(struct timer * tp) 139 { 140 struct timeval now; 141 long int end_time = 0, current_time = 0, diff = 0; 142 if (gettimeofday(&now, NULL) < 0) 143 { 144 perror("gettimeofday"); 145 return -1; 146 } 147 end_time += tp->end.tv_sec * 1000000; 148 end_time += tp->end.tv_usec; 149 150 current_time += now.tv_sec * 1000000; 151 current_time += now.tv_usec; 152 153 diff = end_time - current_time; 154 if (diff > 0) 155 return diff; 156 else 157 return 0; 158 } 159