1 /* 2 * Copyright (c) 2009-2011, The Regents of the University of California, 3 * through Lawrence Berkeley National Laboratory (subject to receipt of any 4 * required approvals from the U.S. Dept. of Energy). All rights reserved. 5 * 6 * This code is distributed under a BSD style license, see the LICENSE file 7 * for complete information. 8 */ 9 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <string.h> 13 #include <errno.h> 14 #include <sys/time.h> 15 #include <sys/errno.h> 16 #include <sys/types.h> 17 #include <stdint.h> 18 #include <time.h> 19 20 #include "timer.h" 21 #include "iperf_api.h" 22 23 double 24 timeval_to_double(struct timeval * tv) 25 { 26 double d; 27 28 d = tv->tv_sec + tv->tv_usec / 1000000; 29 30 return d; 31 } 32 33 int 34 timeval_equals(struct timeval * tv0, struct timeval * tv1) 35 { 36 if ( tv0->tv_sec == tv1->tv_sec && tv0->tv_usec == tv1->tv_usec ) 37 return 1; 38 else 39 return 0; 40 } 41 42 double 43 timeval_diff(struct timeval * tv0, struct timeval * tv1) 44 { 45 double time1, time2; 46 47 time1 = tv0->tv_sec + (tv0->tv_usec / 1000000.0); 48 time2 = tv1->tv_sec + (tv1->tv_usec / 1000000.0); 49 50 time1 = time1 - time2; 51 if (time1 < 0) 52 time1 = -time1; 53 return (time1); 54 } 55 56 int 57 timer_expired(struct timer * tp) 58 { 59 if (tp == NULL) 60 return 0; 61 62 struct timeval now; 63 int64_t end = 0, current = 0; 64 65 gettimeofday(&now, NULL); 66 67 end += tp->end.tv_sec * 1000000; 68 end += tp->end.tv_usec; 69 70 current += now.tv_sec * 1000000; 71 current += now.tv_usec; 72 73 return current > end; 74 } 75 76 int 77 update_timer(struct timer * tp, time_t sec, suseconds_t usec) 78 { 79 if (gettimeofday(&tp->begin, NULL) < 0) { 80 i_errno = IEUPDATETIMER; 81 return (-1); 82 } 83 84 tp->end.tv_sec = tp->begin.tv_sec + (time_t) sec; 85 tp->end.tv_usec = tp->begin.tv_usec + (time_t) usec; 86 87 tp->expired = timer_expired; 88 return (0); 89 } 90 91 struct timer * 92 new_timer(time_t sec, suseconds_t usec) 93 { 94 struct timer *tp = NULL; 95 tp = (struct timer *) calloc(1, sizeof(struct timer)); 96 if (tp == NULL) { 97 i_errno = IENEWTIMER; 98 return (NULL); 99 } 100 101 if (gettimeofday(&tp->begin, NULL) < 0) { 102 i_errno = IENEWTIMER; 103 return (NULL); 104 } 105 106 tp->end.tv_sec = tp->begin.tv_sec + (time_t) sec; 107 tp->end.tv_usec = tp->begin.tv_usec + (time_t) usec; 108 109 tp->expired = timer_expired; 110 111 return tp; 112 } 113 114 void 115 free_timer(struct timer * tp) 116 { 117 free(tp); 118 } 119 120 int 121 delay(int64_t ns) 122 { 123 struct timespec req, rem; 124 125 req.tv_sec = 0; 126 127 while (ns >= 1000000000L) { 128 ns -= 1000000000L; 129 req.tv_sec += 1; 130 } 131 132 req.tv_nsec = ns; 133 134 while (nanosleep(&req, &rem) == -1) 135 if (EINTR == errno) 136 memcpy(&req, &rem, sizeof rem); 137 else 138 return -1; 139 return 0; 140 } 141 142 # ifdef DELAY_SELECT_METHOD 143 int 144 delay(int us) 145 { 146 struct timeval tv; 147 148 tv.tv_sec = 0; 149 tv.tv_usec = us; 150 (void) select(1, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &tv); 151 return (1); 152 } 153 #endif 154 155 int64_t 156 timer_remaining(struct timer * tp) 157 { 158 struct timeval now; 159 long int end_time = 0, current_time = 0, diff = 0; 160 161 gettimeofday(&now, NULL); 162 163 end_time += tp->end.tv_sec * 1000000; 164 end_time += tp->end.tv_usec; 165 166 current_time += now.tv_sec * 1000000; 167 current_time += now.tv_usec; 168 169 diff = end_time - current_time; 170 if (diff > 0) 171 return diff; 172 else 173 return 0; 174 } 175 176 void 177 cpu_util(double *pcpu) 178 { 179 static struct timeval last; 180 static clock_t clast; 181 struct timeval temp; 182 clock_t ctemp; 183 double timediff; 184 185 if (pcpu == NULL) { 186 gettimeofday(&last, NULL); 187 clast = clock(); 188 return; 189 } 190 191 gettimeofday(&temp, NULL); 192 ctemp = clock(); 193 194 timediff = ((temp.tv_sec * 1000000.0 + temp.tv_usec) - 195 (last.tv_sec * 1000000.0 + last.tv_usec)); 196 197 *pcpu = ((ctemp - clast) / timediff) * 100; 198 } 199 200