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