xref: /iperf/src/timer.c (revision 56a97f93)
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_error.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 double
34 timeval_diff(struct timeval * tv0, struct timeval * tv1)
35 {
36     double time1, time2;
37 
38     time1 = tv0->tv_sec + (tv0->tv_usec / 1000000.0);
39     time2 = tv1->tv_sec + (tv1->tv_usec / 1000000.0);
40 
41     time1 = time1 - time2;
42     if (time1 < 0)
43         time1 = -time1;
44     return (time1);
45 }
46 
47 int
48 timer_expired(struct timer * tp)
49 {
50     if (tp == NULL)
51         return 0;
52 
53     struct timeval now;
54     int64_t end = 0, current = 0;
55 
56     gettimeofday(&now, NULL);
57 
58     end += tp->end.tv_sec * 1000000;
59     end += tp->end.tv_usec;
60 
61     current += now.tv_sec * 1000000;
62     current += now.tv_usec;
63 
64     return current > end;
65 }
66 
67 int
68 update_timer(struct timer * tp, time_t sec, suseconds_t usec)
69 {
70     if (gettimeofday(&tp->begin, NULL) < 0) {
71         i_errno = IEUPDATETIMER;
72         return (-1);
73     }
74 
75     tp->end.tv_sec = tp->begin.tv_sec + (time_t) sec;
76     tp->end.tv_usec = tp->begin.tv_usec + (time_t) usec;
77 
78     tp->expired = timer_expired;
79     return (0);
80 }
81 
82 struct timer *
83 new_timer(time_t sec, suseconds_t usec)
84 {
85     struct timer *tp = NULL;
86     tp = (struct timer *) calloc(1, sizeof(struct timer));
87     if (tp == NULL) {
88         i_errno = IENEWTIMER;
89         return (NULL);
90     }
91 
92     if (gettimeofday(&tp->begin, NULL) < 0) {
93         i_errno = IENEWTIMER;
94         return (NULL);
95     }
96 
97     tp->end.tv_sec = tp->begin.tv_sec + (time_t) sec;
98     tp->end.tv_usec = tp->begin.tv_usec + (time_t) usec;
99 
100     tp->expired = timer_expired;
101 
102     return tp;
103 }
104 
105 void
106 free_timer(struct timer * tp)
107 {
108     free(tp);
109 }
110 
111 int
112 delay(int64_t ns)
113 {
114     struct timespec req, rem;
115 
116     req.tv_sec = 0;
117 
118     while (ns >= 1000000000L) {
119         ns -= 1000000000L;
120         req.tv_sec += 1;
121     }
122 
123     req.tv_nsec = ns;
124 
125     while (nanosleep(&req, &rem) == -1)
126         if (EINTR == errno)
127             memcpy(&req, &rem, sizeof rem);
128         else
129             return -1;
130     return 0;
131 }
132 
133 # ifdef DELAY_SELECT_METHOD
134 int
135 delay(int us)
136 {
137     struct timeval tv;
138 
139     tv.tv_sec = 0;
140     tv.tv_usec = us;
141     (void) select(1, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &tv);
142     return (1);
143 }
144 #endif
145 
146 int64_t
147 timer_remaining(struct timer * tp)
148 {
149     struct timeval now;
150     long int  end_time = 0, current_time = 0, diff = 0;
151 
152     gettimeofday(&now, NULL);
153 
154     end_time += tp->end.tv_sec * 1000000;
155     end_time += tp->end.tv_usec;
156 
157     current_time += now.tv_sec * 1000000;
158     current_time += now.tv_usec;
159 
160     diff = end_time - current_time;
161     if (diff > 0)
162         return diff;
163     else
164         return 0;
165 }
166 
167 void
168 cpu_util(double *pcpu)
169 {
170     static struct timeval last;
171     static clock_t clast;
172     struct timeval temp;
173     clock_t ctemp;
174     double timediff;
175 
176     if (pcpu == NULL) {
177         gettimeofday(&last, NULL);
178         clast = clock();
179         return;
180     }
181 
182     gettimeofday(&temp, NULL);
183     ctemp = clock();
184 
185     timediff = ((temp.tv_sec * 1000000.0 + temp.tv_usec) -
186             (last.tv_sec * 1000000.0 + last.tv_usec));
187 
188     *pcpu = ((ctemp - clast) / timediff) * 100;
189 }
190 
191