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