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 return diff <= 0; 53 54 /* 55 * currently using microsecond limit. Else we need to introduce timespec 56 * instread of timeval 57 */ 58 } 59 60 void 61 update_timer(struct timer * tp, time_t sec, suseconds_t usec) 62 { 63 if (gettimeofday(&tp->begin, NULL) < 0) 64 { 65 perror("gettimeofday"); 66 } 67 memcpy(&tp->end, &tp->begin, sizeof(struct timer)); 68 tp->end.tv_sec = tp->begin.tv_sec + (time_t) sec; 69 tp->end.tv_usec = tp->begin.tv_usec + (time_t) usec; 70 71 tp->expired = timer_expired; 72 } 73 74 struct timer * 75 new_timer(time_t sec, suseconds_t usec) 76 { 77 struct timer *tp; 78 tp = (struct timer *) malloc(sizeof(struct timer)); 79 80 if (gettimeofday(&tp->begin, NULL) < 0) 81 { 82 perror("gettimeofday"); 83 return NULL; 84 } 85 memcpy(&tp->end, &tp->begin, sizeof(struct timer)); 86 tp->end.tv_sec = tp->begin.tv_sec + (time_t) sec; 87 tp->end.tv_usec = tp->begin.tv_usec + (time_t) usec; 88 89 tp->expired = timer_expired; 90 91 return tp; 92 } 93 94 void 95 free_timer(struct timer * tp) 96 { 97 free(tp); 98 } 99 100 int 101 delay(int64_t ns) 102 { 103 struct timespec req, rem; 104 105 req.tv_sec = 0; 106 107 while (ns >= 1000000000L) 108 { 109 ns -= 1000000000L; 110 req.tv_sec += 1; 111 } 112 113 req.tv_nsec = ns; 114 115 while (nanosleep(&req, &rem) == -1) 116 if (EINTR == errno) 117 memcpy(&req, &rem, sizeof rem); 118 else 119 return -1; 120 return 0; 121 } 122 123 # ifdef DELAY_SELECT_METHOD 124 int 125 delay(int us) 126 { 127 struct timeval tv; 128 129 tv.tv_sec = 0; 130 tv.tv_usec = us; 131 (void) select(1, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &tv); 132 return (1); 133 } 134 #endif 135 136 int64_t 137 timer_remaining(struct timer * tp) 138 { 139 struct timeval now; 140 long int end_time = 0, current_time = 0, diff = 0; 141 if (gettimeofday(&now, NULL) < 0) 142 { 143 perror("gettimeofday"); 144 return -1; 145 } 146 end_time += tp->end.tv_sec * 1000000; 147 end_time += tp->end.tv_usec; 148 149 current_time += now.tv_sec * 1000000; 150 current_time += now.tv_usec; 151 152 diff = end_time - current_time; 153 if (diff > 0) 154 return diff; 155 else 156 return 0; 157 } 158