xref: /iperf/src/timer.c (revision b60a49dd)
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 #include "iperf_error.h"
12 
13 double
14 timeval_to_double(struct timeval * tv)
15 {
16     double d;
17 
18     d = tv->tv_sec + tv->tv_usec / 1000000;
19 
20     return d;
21 }
22 
23 double
24 timeval_diff(struct timeval * tv0, struct timeval * tv1)
25 {
26     return ((abs(tv1->tv_sec - tv0->tv_sec)) + (abs(tv1->tv_usec - tv0->tv_usec) / 1000000.0));
27 }
28 
29 int
30 timer_expired(struct timer * tp)
31 {
32     if (tp == NULL)
33         return 0;
34 
35     struct timeval now;
36     int64_t end = 0, current = 0;
37 
38     gettimeofday(&now, NULL);
39 
40     end += tp->end.tv_sec * 1000000;
41     end += tp->end.tv_usec;
42 
43     current += now.tv_sec * 1000000;
44     current += now.tv_usec;
45 
46     return current > end;
47 }
48 
49 int
50 update_timer(struct timer * tp, time_t sec, suseconds_t usec)
51 {
52     if (gettimeofday(&tp->begin, NULL) < 0) {
53         i_errno = IEUPDATETIMER;
54         return (-1);
55     }
56 
57     tp->end.tv_sec = tp->begin.tv_sec + (time_t) sec;
58     tp->end.tv_usec = tp->begin.tv_usec + (time_t) usec;
59 
60     tp->expired = timer_expired;
61     return (0);
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         i_errno = IENEWTIMER;
71         return (NULL);
72     }
73 
74     if (gettimeofday(&tp->begin, NULL) < 0) {
75         i_errno = IENEWTIMER;
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     gettimeofday(&now, NULL);
135 
136     end_time += tp->end.tv_sec * 1000000;
137     end_time += tp->end.tv_usec;
138 
139     current_time += now.tv_sec * 1000000;
140     current_time += now.tv_usec;
141 
142     diff = end_time - current_time;
143     if (diff > 0)
144         return diff;
145     else
146         return 0;
147 }
148