xref: /iperf/src/timer.c (revision 8a0cc100)
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