xref: /iperf/src/timer.c (revision f1b3bd81)
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 double
13 timeval_to_double(struct timeval * tv)
14 {
15     double d;
16 
17     d = tv->tv_sec + tv->tv_usec / 1000000;
18 
19     return d;
20 }
21 
22 double
23 timeval_diff(struct timeval * tv0, struct timeval * tv1)
24 {
25     return ((abs(tv1->tv_sec - tv0->tv_sec)) + (abs(tv1->tv_usec - tv0->tv_usec) / 1000000.0));
26 }
27 
28 int
29 timer_expired(struct timer * tp)
30 {
31     if (tp == NULL)
32         return 0;
33 
34     struct timeval now;
35     int64_t end = 0, current = 0;
36 
37     if (gettimeofday(&now, NULL) < 0) {
38         perror("gettimeofday");
39         return -1;
40     }
41 
42     end += tp->end.tv_sec * 1000000;
43     end += tp->end.tv_usec;
44 
45     current += now.tv_sec * 1000000;
46     current += now.tv_usec;
47 
48     return current > end;
49 }
50 
51 void
52 update_timer(struct timer * tp, time_t sec, suseconds_t usec)
53 {
54     if (gettimeofday(&tp->begin, NULL) < 0) {
55         perror("gettimeofday");
56     }
57 
58     tp->end.tv_sec = tp->begin.tv_sec + (time_t) sec;
59     tp->end.tv_usec = tp->begin.tv_usec + (time_t) usec;
60 
61     tp->expired = timer_expired;
62 }
63 
64 struct timer *
65 new_timer(time_t sec, suseconds_t usec)
66 {
67     struct timer *tp = NULL;
68     tp = (struct timer *) calloc(1, sizeof(struct timer));
69     if (tp == NULL) {
70         perror("malloc");
71         return NULL;
72     }
73 
74     if (gettimeofday(&tp->begin, NULL) < 0) {
75         perror("gettimeofday");
76         return NULL;
77     }
78 
79     tp->end.tv_sec = tp->begin.tv_sec + (time_t) sec;
80     tp->end.tv_usec = tp->begin.tv_usec + (time_t) usec;
81 
82     tp->expired = timer_expired;
83 
84     return tp;
85 }
86 
87 void
88 free_timer(struct timer * tp)
89 {
90     free(tp);
91 }
92 
93 int
94 delay(int64_t ns)
95 {
96     struct timespec req, rem;
97 
98     req.tv_sec = 0;
99 
100     while (ns >= 1000000000L) {
101         ns -= 1000000000L;
102         req.tv_sec += 1;
103     }
104 
105     req.tv_nsec = ns;
106 
107     while (nanosleep(&req, &rem) == -1)
108         if (EINTR == errno)
109             memcpy(&req, &rem, sizeof rem);
110         else
111             return -1;
112     return 0;
113 }
114 
115 # ifdef DELAY_SELECT_METHOD
116 int
117 delay(int us)
118 {
119     struct timeval tv;
120 
121     tv.tv_sec = 0;
122     tv.tv_usec = us;
123     (void) select(1, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &tv);
124     return (1);
125 }
126 #endif
127 
128 int64_t
129 timer_remaining(struct timer * tp)
130 {
131     struct timeval now;
132     long int  end_time = 0, current_time = 0, diff = 0;
133 
134     if (gettimeofday(&now, NULL) < 0) {
135         perror("gettimeofday");
136         return -1;
137     }
138 
139     end_time += tp->end.tv_sec * 1000000;
140     end_time += tp->end.tv_usec;
141 
142     current_time += now.tv_sec * 1000000;
143     current_time += now.tv_usec;
144 
145     diff = end_time - current_time;
146     if (diff > 0)
147         return diff;
148     else
149         return 0;
150 }
151