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