1 /*
2  * Time operation macros based on sys/time.h
3  * Copyright 2013 Balint Reczey <balint@balintreczey.hu>
4  *
5  * This file is part of libfaketime.
6  *
7  * libfaketime is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License v2 as published by the Free
9  * Software Foundation.
10  *
11  * libfaketime is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License v2 along
17  * with libfaketime; if not, write to the Free Software Foundation, Inc.,
18  * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 
21 #ifndef TIME_OPS_H
22 #define TIME_OPS_H
23 #include <time.h>
24 
25 #define SEC_TO_uSEC 1000000
26 #define SEC_TO_nSEC 1000000000
27 
28 /* Convenience macros for operations on timevals.
29    NOTE: `timercmp' does not work for >= or <=.  */
30 #define timerisset2(tvp, prefix) ((tvp)->tv_sec || (tvp)->tv_##prefix##sec)
31 #define timerclear2(tvp, prefix) ((tvp)->tv_sec = (tvp)->tv_##prefix##sec = 0)
32 #define timercmp2(a, b, CMP, prefix)                                \
33   (((a)->tv_sec == (b)->tv_sec) ?                                   \
34    ((a)->tv_##prefix##sec CMP (b)->tv_##prefix##sec) :              \
35    ((a)->tv_sec CMP (b)->tv_sec))
36 #define timeradd2(a, b, result, prefix)                             \
37   do                                                                \
38   {                                                                 \
39     (result)->tv_sec = (a)->tv_sec + (b)->tv_sec;                   \
40     (result)->tv_##prefix##sec = (a)->tv_##prefix##sec +            \
41       (b)->tv_##prefix##sec;                                        \
42     if ((result)->tv_##prefix##sec >= SEC_TO_##prefix##SEC)         \
43       {                                                             \
44         ++(result)->tv_sec;                                         \
45         (result)->tv_##prefix##sec -= SEC_TO_##prefix##SEC;         \
46       }                                                             \
47   } while (0)
48 #define timersub2(a, b, result, prefix)                             \
49   do                                                                \
50   {                                                                 \
51     (result)->tv_sec = (a)->tv_sec - (b)->tv_sec;                   \
52     (result)->tv_##prefix##sec = (a)->tv_##prefix##sec -            \
53       (b)->tv_##prefix##sec;                                        \
54     if ((result)->tv_##prefix##sec < 0)                             \
55     {                                                               \
56       --(result)->tv_sec;                                           \
57       (result)->tv_##prefix##sec += SEC_TO_##prefix##SEC;           \
58     }                                                               \
59   } while (0)
60 #define timermul2(tvp, c, result, prefix)                           \
61   do                                                                \
62   {                                                                 \
63     long long tmp_time;                                             \
64     tmp_time = (c) * ((tvp)->tv_sec * SEC_TO_##prefix##SEC +        \
65                (tvp)->tv_##prefix##sec);                            \
66     (result)->tv_##prefix##sec = tmp_time % SEC_TO_##prefix##SEC;   \
67     (result)->tv_sec = (tmp_time - (result)->tv_##prefix##sec) /    \
68       SEC_TO_##prefix##SEC;                                         \
69     if ((result)->tv_##prefix##sec < 0)                             \
70     {                                                               \
71       (result)->tv_##prefix##sec +=  SEC_TO_##prefix##SEC;          \
72       (result)->tv_sec -= 1;                                        \
73     }                                                               \
74   } while (0)
75 
76 /* ops for microsecs */
77 #ifndef timerisset
78 #define timerisset(tvp) timerisset2(tvp,u)
79 #endif
80 #ifndef timerclear
81 #define timerclear(tvp) timerclear2(tvp, u)
82 #endif
83 #ifndef timercmp
84 #define timercmp(a, b, CMP) timercmp2(a, b, CMP, u)
85 #endif
86 #ifndef timeradd
87 #define timeradd(a, b, result) timeradd2(a, b, result, u)
88 #endif
89 #ifndef timersub
90 #define timersub(a, b, result) timersub2(a, b, result, u)
91 #endif
92 #ifndef timersub
93 #define timermul(a, c, result) timermul2(a, c, result, u)
94 #endif
95 
96 /* ops for nanosecs */
97 #define timespecisset(tvp) timerisset2(tvp,n)
98 #define timespecclear(tvp) timerclear2(tvp, n)
99 #define timespeccmp(a, b, CMP) timercmp2(a, b, CMP, n)
100 #define timespecadd(a, b, result) timeradd2(a, b, result, n)
101 #define timespecsub(a, b, result) timersub2(a, b, result, n)
102 #define timespecmul(a, c, result) timermul2(a, c, result, n)
103 
104 #endif
105