1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
#ifndef TIME_UTIL_H
#define TIME_UTIL_H
#include <sys/time.h> /* for struct timeval */
/* Same as gettimeofday(), but call i_fatal() if the call fails. */
void i_gettimeofday(struct timeval *tv_r);
/* Return nanoseconds since UNIX epoch (1970-01-01). */
uint64_t i_nanoseconds(void);
/* Return microseconds since UNIX epoch (1970-01-01). */
static inline uint64_t i_microseconds(void) {
return i_nanoseconds() / 1000;
}
/* Returns -1 if tv1<tv2, 1 if tv1>tv2, 0 if they're equal. */
int timeval_cmp(const struct timeval *tv1, const struct timeval *tv2);
/* Same as timeval_cmp, but tv->usecs must differ by at least usec_margin */
int timeval_cmp_margin(const struct timeval *tv1, const struct timeval *tv2,
unsigned int usec_margin);
/* Returns tv1-tv2 in milliseconds. */
int timeval_diff_msecs(const struct timeval *tv1, const struct timeval *tv2);
/* Returns tv1-tv2 in microseconds. */
long long timeval_diff_usecs(const struct timeval *tv1,
const struct timeval *tv2);
static inline void
timeval_add_usecs(struct timeval *tv, long long usecs)
{
i_assert(usecs >= 0);
tv->tv_sec += usecs / 1000000;
tv->tv_usec += (usecs % 1000000);
if (tv->tv_usec >= 1000000) {
tv->tv_sec++;
tv->tv_usec -= 1000000;
}
}
static inline void
timeval_sub_usecs(struct timeval *tv, long long usecs)
{
i_assert(usecs >= 0);
tv->tv_sec -= usecs / 1000000;
tv->tv_usec -= (usecs % 1000000);
if (tv->tv_usec < 0) {
tv->tv_sec--;
tv->tv_usec += 1000000;
}
}
static inline void
timeval_add_msecs(struct timeval *tv, unsigned int msecs)
{
tv->tv_sec += msecs / 1000;
tv->tv_usec += (msecs % 1000) * 1000;
if (tv->tv_usec >= 1000000) {
tv->tv_sec++;
tv->tv_usec -= 1000000;
}
}
static inline void
timeval_sub_msecs(struct timeval *tv, unsigned int msecs)
{
tv->tv_sec -= msecs / 1000;
tv->tv_usec -= (msecs % 1000) * 1000;
if (tv->tv_usec < 0) {
tv->tv_sec--;
tv->tv_usec += 1000000;
}
}
static inline unsigned long long timeval_to_usecs(const struct timeval *tv)
{
return (tv->tv_sec * 1000000ULL + tv->tv_usec);
}
static inline void timeval_add(struct timeval *tv, const struct timeval *val)
{
i_assert(val->tv_usec < 1000000);
tv->tv_sec += val->tv_sec;
tv->tv_usec += val->tv_usec;
if (tv->tv_usec >= 1000000) {
tv->tv_sec++;
tv->tv_usec -= 1000000;
}
}
static inline time_t timeval_round(struct timeval *tv)
{
return (tv->tv_usec < 500000 ? tv->tv_sec : tv->tv_sec + 1);
}
/* Convert t to local time and return timestamp on that day at 00:00:00. */
time_t time_to_local_day_start(time_t t);
/* Wrappers to strftime() */
const char *t_strftime(const char *fmt, const struct tm *tm) ATTR_STRFTIME(1);
const char *t_strflocaltime(const char *fmt, time_t t) ATTR_STRFTIME(1);
const char *t_strfgmtime(const char *fmt, time_t t) ATTR_STRFTIME(1);
/* Parse string as <unix timestamp>[.<usecs>] into timeval. <usecs> must not
have higher precision time, i.e. a maximum of 6 digits is allowed. Note that
".1" is handled as ".1000000" so the string should have been written using
"%06u" printf format. */
int str_to_timeval(const char *str, struct timeval *tv_r)
ATTR_WARN_UNUSED_RESULT;
#endif
|