xref: /iperf/src/timer.c (revision ff385f98)
10fdaab07SJon Dugan #include <stdio.h>
20fdaab07SJon Dugan #include <stdlib.h>
30fdaab07SJon Dugan #include <string.h>
40fdaab07SJon Dugan #include <sys/time.h>
50fdaab07SJon Dugan #include <sys/errno.h>
60fdaab07SJon Dugan #include <sys/types.h>
70fdaab07SJon Dugan #include <stdint.h>
80fdaab07SJon Dugan #include <time.h>
90fdaab07SJon Dugan 
100fdaab07SJon Dugan #include "timer.h"
110fdaab07SJon Dugan 
12c6ffef11Skaustubhprabhu double
13c6ffef11Skaustubhprabhu timeval_to_double(struct timeval * tv)
1481a2df59Skaustubhprabhu {
1581a2df59Skaustubhprabhu     double d;
1681a2df59Skaustubhprabhu 
1781a2df59Skaustubhprabhu     d = tv->tv_sec + tv->tv_usec / 1000000;
1881a2df59Skaustubhprabhu 
1981a2df59Skaustubhprabhu     return d;
2081a2df59Skaustubhprabhu }
2181a2df59Skaustubhprabhu 
22c6ffef11Skaustubhprabhu double
23c6ffef11Skaustubhprabhu timeval_diff(struct timeval * tv0, struct timeval * tv1)
2481a2df59Skaustubhprabhu {
25*ff385f98Ssethdelliott     return ((abs(tv1->tv_sec - tv0->tv_sec)) + (abs(tv1->tv_usec - tv0->tv_usec) / 1000000.0));
2681a2df59Skaustubhprabhu }
2781a2df59Skaustubhprabhu 
280fdaab07SJon Dugan int
290fdaab07SJon Dugan timer_expired(struct timer * tp)
300fdaab07SJon Dugan {
31e434aab6SBrian Tierney     /* for timer with zero time */
32*ff385f98Ssethdelliott     if (tp->end.tv_sec == tp->begin.tv_sec && tp->end.tv_usec == tp->begin.tv_usec) {
33c5038eeaSkaustubhprabhu         return 0;
3497887027SBrian Tierney     }
35c5038eeaSkaustubhprabhu 
360fdaab07SJon Dugan     struct timeval now;
37*ff385f98Ssethdelliott     int64_t end = 0, current = 0;
38da54a271SBrian Tierney 
39*ff385f98Ssethdelliott     if (gettimeofday(&now, NULL) < 0) {
40aa9ca268Skaustubhprabhu         perror("gettimeofday");
41aa9ca268Skaustubhprabhu         return -1;
42aa9ca268Skaustubhprabhu     }
43*ff385f98Ssethdelliott 
4481a2df59Skaustubhprabhu     end += tp->end.tv_sec * 1000000;
4581a2df59Skaustubhprabhu     end += tp->end.tv_usec;
46aa9ca268Skaustubhprabhu 
47aa9ca268Skaustubhprabhu     current += now.tv_sec * 1000000;
48aa9ca268Skaustubhprabhu     current += now.tv_usec;
49aa9ca268Skaustubhprabhu 
50*ff385f98Ssethdelliott     return current > end;
51aa9ca268Skaustubhprabhu }
52aa9ca268Skaustubhprabhu 
53c6ffef11Skaustubhprabhu void
54c6ffef11Skaustubhprabhu update_timer(struct timer * tp, time_t sec, suseconds_t usec)
55c6ffef11Skaustubhprabhu {
56*ff385f98Ssethdelliott     if (gettimeofday(&tp->begin, NULL) < 0) {
57c6ffef11Skaustubhprabhu         perror("gettimeofday");
58c6ffef11Skaustubhprabhu     }
59*ff385f98Ssethdelliott 
60c6ffef11Skaustubhprabhu     tp->end.tv_sec = tp->begin.tv_sec + (time_t) sec;
61c6ffef11Skaustubhprabhu     tp->end.tv_usec = tp->begin.tv_usec + (time_t) usec;
62c6ffef11Skaustubhprabhu 
63c6ffef11Skaustubhprabhu     tp->expired = timer_expired;
64c6ffef11Skaustubhprabhu }
65aa9ca268Skaustubhprabhu 
660fdaab07SJon Dugan struct timer *
670fdaab07SJon Dugan new_timer(time_t sec, suseconds_t usec)
680fdaab07SJon Dugan {
69dfb2d9d4SBrian Tierney     struct timer *tp = NULL;
70dfb2d9d4SBrian Tierney     tp = (struct timer *) calloc(1, sizeof(struct timer));
71*ff385f98Ssethdelliott     if (tp == NULL) {
72f4e1c1d4SBrian Tierney         perror("malloc");
73f4e1c1d4SBrian Tierney         return NULL;
74f4e1c1d4SBrian Tierney     }
750fdaab07SJon Dugan 
76*ff385f98Ssethdelliott     if (gettimeofday(&tp->begin, NULL) < 0) {
770fdaab07SJon Dugan         perror("gettimeofday");
780fdaab07SJon Dugan         return NULL;
790fdaab07SJon Dugan     }
80dfb2d9d4SBrian Tierney 
810fdaab07SJon Dugan     tp->end.tv_sec = tp->begin.tv_sec + (time_t) sec;
820fdaab07SJon Dugan     tp->end.tv_usec = tp->begin.tv_usec + (time_t) usec;
830fdaab07SJon Dugan 
840fdaab07SJon Dugan     tp->expired = timer_expired;
850fdaab07SJon Dugan 
860fdaab07SJon Dugan     return tp;
870fdaab07SJon Dugan }
880fdaab07SJon Dugan 
890fdaab07SJon Dugan void
900fdaab07SJon Dugan free_timer(struct timer * tp)
910fdaab07SJon Dugan {
920fdaab07SJon Dugan     free(tp);
930fdaab07SJon Dugan }
940fdaab07SJon Dugan 
950fdaab07SJon Dugan int
960fdaab07SJon Dugan delay(int64_t ns)
970fdaab07SJon Dugan {
980fdaab07SJon Dugan     struct timespec req, rem;
990fdaab07SJon Dugan 
1000fdaab07SJon Dugan     req.tv_sec = 0;
1010fdaab07SJon Dugan 
102*ff385f98Ssethdelliott     while (ns >= 1000000000L) {
1030fdaab07SJon Dugan         ns -= 1000000000L;
1040fdaab07SJon Dugan         req.tv_sec += 1;
1050fdaab07SJon Dugan     }
1060fdaab07SJon Dugan 
1070fdaab07SJon Dugan     req.tv_nsec = ns;
1080fdaab07SJon Dugan 
1090fdaab07SJon Dugan     while (nanosleep(&req, &rem) == -1)
1100fdaab07SJon Dugan         if (EINTR == errno)
1110fdaab07SJon Dugan             memcpy(&req, &rem, sizeof rem);
1120fdaab07SJon Dugan         else
1130fdaab07SJon Dugan             return -1;
1140fdaab07SJon Dugan     return 0;
1150fdaab07SJon Dugan }
1160fdaab07SJon Dugan 
117a7253334SBrian Tierney # ifdef DELAY_SELECT_METHOD
118a7253334SBrian Tierney int
119a7253334SBrian Tierney delay(int us)
120a7253334SBrian Tierney {
121a7253334SBrian Tierney     struct timeval tv;
122a7253334SBrian Tierney 
123a7253334SBrian Tierney     tv.tv_sec = 0;
124a7253334SBrian Tierney     tv.tv_usec = us;
125a7253334SBrian Tierney     (void) select(1, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &tv);
126a7253334SBrian Tierney     return (1);
127a7253334SBrian Tierney }
128a7253334SBrian Tierney #endif
129a7253334SBrian Tierney 
130c6ffef11Skaustubhprabhu int64_t
131c6ffef11Skaustubhprabhu timer_remaining(struct timer * tp)
132c6ffef11Skaustubhprabhu {
133c6ffef11Skaustubhprabhu     struct timeval now;
1347dd1f0cdSkaustubhprabhu     long int  end_time = 0, current_time = 0, diff = 0;
135*ff385f98Ssethdelliott 
136*ff385f98Ssethdelliott     if (gettimeofday(&now, NULL) < 0) {
137c6ffef11Skaustubhprabhu         perror("gettimeofday");
138c6ffef11Skaustubhprabhu         return -1;
139c6ffef11Skaustubhprabhu     }
140*ff385f98Ssethdelliott 
1417dd1f0cdSkaustubhprabhu     end_time += tp->end.tv_sec * 1000000;
1427dd1f0cdSkaustubhprabhu     end_time += tp->end.tv_usec;
143c6ffef11Skaustubhprabhu 
1447dd1f0cdSkaustubhprabhu     current_time += now.tv_sec * 1000000;
1457dd1f0cdSkaustubhprabhu     current_time += now.tv_usec;
146c6ffef11Skaustubhprabhu 
1477dd1f0cdSkaustubhprabhu     diff = end_time - current_time;
148c6ffef11Skaustubhprabhu     if (diff > 0)
149c6ffef11Skaustubhprabhu         return diff;
150c6ffef11Skaustubhprabhu     else
151c6ffef11Skaustubhprabhu         return 0;
152c6ffef11Skaustubhprabhu }
153