2 /** \file time.c helper functions for dealing with timeouts */
5 * convert struct timeval to milliseconds
7 * \param tv the value to convert
9 * \return The number off milliseconds in \a tv
11 long unsigned tv2ms(const struct timeval *tv)
13 return tv->tv_sec * 1000 + (tv->tv_usec + 500)/ 1000;
17 * convert milliseconds to struct timeval
19 * \param n the number of milliseconds
20 * \param tv will be filled in by the function
22 void ms2tv(long unsigned n, struct timeval *tv)
24 tv->tv_sec = n / 1000;
25 tv->tv_usec = (n % 1000) * 1000;
29 * convert double to struct timeval
31 * \param x the value to convert
32 * \param tv converted value is stored here
34 void d2tv(double x, struct timeval *tv)
37 tv->tv_usec = (x - (double)tv->tv_sec) * 1000.0 * 1000.0 + 0.5;
41 * compute the difference of two time values
45 * \param diff difference is stored here
47 * \return If b > a, compute b - a and return 1. if b < a
48 * compute a - b and return -1. If \a diff is not \p NULL, \a diff gets
49 * filled in with the absolute value |b - a|.
51 int tv_diff(const struct timeval *b, const struct timeval *a, struct timeval *diff)
55 if ((b->tv_sec < a->tv_sec) ||
56 ((b->tv_sec == a->tv_sec) && (b->tv_usec < a->tv_usec))) {
57 const struct timeval *tmp = a;
64 diff->tv_sec = b->tv_sec - a->tv_sec;
65 if (b->tv_usec < a->tv_usec) {
67 diff->tv_usec = 1000 * 1000 - a->tv_usec + b->tv_usec;
69 diff->tv_usec = b->tv_usec - a->tv_usec;
74 * add two structs of type timeval
76 * \param a first addend
77 * \param b second addend
78 * \param sum holds the sum upon return
80 void tv_add(const struct timeval *a, const struct timeval *b,
83 sum->tv_sec = a->tv_sec + b->tv_sec;
84 if (a->tv_usec + b->tv_usec >= 1000 * 1000) {
86 sum->tv_usec = a->tv_usec + b->tv_usec - 1000 * 1000;
88 sum->tv_usec = a->tv_usec + b->tv_usec;
92 * compute integer multiple of given struct timeval
94 * \param mult the integer value to multiply with
95 * \param tv the timevalue to multiply
96 * \param result holds mult * tv upon return
98 void tv_scale(const unsigned long mult, const struct timeval *tv,
99 struct timeval *result)
101 result->tv_sec = mult * tv->tv_sec;
102 result->tv_sec += tv->tv_usec * mult / 1000 / 1000;
103 result->tv_usec = tv->tv_usec * mult % (1000 * 1000);
107 * compute fraction of given struct timeval
109 * \param divisor the integer value to divide by
110 * \param tv the timevalue to divide
111 * \param result holds (1 / mult) * tv upon return
113 void tv_divide(const unsigned long divisor, const struct timeval *tv,
114 struct timeval *result)
119 PARA_EMERG_LOG("%s\n", "division by zero");
122 q = tv->tv_usec / divisor;
123 result->tv_sec = tv->tv_sec / divisor;
124 result->tv_usec = (tv->tv_sec - result->tv_sec * divisor)
125 * 1000 * 1000 / divisor;
126 if (result->tv_usec + q >= 1000 * 1000) {
128 result->tv_usec = 1000 * 1000 - result->tv_usec - q;
130 result->tv_usec += q;
134 * compute a convex combination of two time values
136 * \param a the first coefiicent
137 * \param tv1 the first time value
138 * \param b the second coefiicent
139 * \param tv2 the second time value
140 * \param result holds the convex combination upon return
142 * compute x := (a * tv1 + b * tv2) / (|a| + |b|). a, b may be negative.
143 * returns sign(x) and stores |x| in the result pointer.
145 int tv_convex_combination(const long a, const struct timeval *tv1,
146 const long b, const struct timeval *tv2,
147 struct timeval *result)
149 struct timeval tmp1, tmp2, tmp3;
150 int ret = 1, subtract = ((a > 0 && b < 0) || (a < 0 && b > 0));
151 unsigned long a1 = PARA_ABS(a), b1 = PARA_ABS(b);
153 tv_scale(a1, tv1, &tmp1);
154 tv_scale(b1, tv2, &tmp2);
156 ret = tv_diff(&tmp1, &tmp2, &tmp3);
158 tv_add(&tmp1, &tmp2, &tmp3);
160 tv_divide(a1 + b1, &tmp3, result);