174681b5dSFrançois Tigeot /*
2*3f2dd94aSFrançois Tigeot * Copyright (c) 2014-2020 François Tigeot <ftigeot@wolfpond.org>
374681b5dSFrançois Tigeot * All rights reserved.
474681b5dSFrançois Tigeot *
574681b5dSFrançois Tigeot * Redistribution and use in source and binary forms, with or without
674681b5dSFrançois Tigeot * modification, are permitted provided that the following conditions
774681b5dSFrançois Tigeot * are met:
874681b5dSFrançois Tigeot * 1. Redistributions of source code must retain the above copyright
974681b5dSFrançois Tigeot * notice unmodified, this list of conditions, and the following
1074681b5dSFrançois Tigeot * disclaimer.
1174681b5dSFrançois Tigeot * 2. Redistributions in binary form must reproduce the above copyright
1274681b5dSFrançois Tigeot * notice, this list of conditions and the following disclaimer in the
1374681b5dSFrançois Tigeot * documentation and/or other materials provided with the distribution.
1474681b5dSFrançois Tigeot *
1574681b5dSFrançois Tigeot * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1674681b5dSFrançois Tigeot * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1774681b5dSFrançois Tigeot * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1874681b5dSFrançois Tigeot * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1974681b5dSFrançois Tigeot * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2074681b5dSFrançois Tigeot * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2174681b5dSFrançois Tigeot * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2274681b5dSFrançois Tigeot * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2374681b5dSFrançois Tigeot * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2474681b5dSFrançois Tigeot * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2574681b5dSFrançois Tigeot */
2674681b5dSFrançois Tigeot
2774681b5dSFrançois Tigeot #ifndef _LINUX_TIME_H_
2874681b5dSFrançois Tigeot #define _LINUX_TIME_H_
2974681b5dSFrançois Tigeot
30c3c5b993SFrançois Tigeot #define USEC_PER_MSEC 1000L
314ab8b20fSFrançois Tigeot #define USEC_PER_SEC 1000000L
324ab8b20fSFrançois Tigeot
3374681b5dSFrançois Tigeot #define NSEC_PER_USEC 1000L
34788808afSFrançois Tigeot #define NSEC_PER_MSEC 1000000L
3574681b5dSFrançois Tigeot #define NSEC_PER_SEC 1000000000L
3674681b5dSFrançois Tigeot
37d998b496SFrançois Tigeot #include <linux/cache.h>
38*3f2dd94aSFrançois Tigeot #include <linux/seqlock.h>
39563a794dSFrançois Tigeot #include <linux/math64.h>
40*3f2dd94aSFrançois Tigeot #include <linux/time64.h>
4174681b5dSFrançois Tigeot
42d998b496SFrançois Tigeot #include <sys/time.h>
43d998b496SFrançois Tigeot
4474681b5dSFrançois Tigeot static inline struct timeval
ns_to_timeval(const int64_t nsec)4574681b5dSFrançois Tigeot ns_to_timeval(const int64_t nsec)
4674681b5dSFrançois Tigeot {
4774681b5dSFrançois Tigeot struct timeval tv;
4874681b5dSFrançois Tigeot long rem;
4974681b5dSFrançois Tigeot
5074681b5dSFrançois Tigeot if (nsec == 0) {
5174681b5dSFrançois Tigeot tv.tv_sec = 0;
5274681b5dSFrançois Tigeot tv.tv_usec = 0;
5374681b5dSFrançois Tigeot return (tv);
5474681b5dSFrançois Tigeot }
5574681b5dSFrançois Tigeot
5674681b5dSFrançois Tigeot tv.tv_sec = nsec / NSEC_PER_SEC;
5774681b5dSFrançois Tigeot rem = nsec % NSEC_PER_SEC;
5874681b5dSFrançois Tigeot if (rem < 0) {
5974681b5dSFrançois Tigeot tv.tv_sec--;
6074681b5dSFrançois Tigeot rem += NSEC_PER_SEC;
6174681b5dSFrançois Tigeot }
6274681b5dSFrançois Tigeot tv.tv_usec = rem / 1000;
6374681b5dSFrançois Tigeot return (tv);
6474681b5dSFrançois Tigeot }
6574681b5dSFrançois Tigeot
6674681b5dSFrançois Tigeot static inline int64_t
timeval_to_ns(const struct timeval * tv)6774681b5dSFrançois Tigeot timeval_to_ns(const struct timeval *tv)
6874681b5dSFrançois Tigeot {
6974681b5dSFrançois Tigeot return ((int64_t)tv->tv_sec * NSEC_PER_SEC) +
7074681b5dSFrançois Tigeot tv->tv_usec * NSEC_PER_USEC;
7174681b5dSFrançois Tigeot }
7274681b5dSFrançois Tigeot
7374681b5dSFrançois Tigeot #define getrawmonotonic(ts) nanouptime(ts)
7474681b5dSFrançois Tigeot
7574681b5dSFrançois Tigeot static inline struct timespec
timespec_sub(struct timespec lhs,struct timespec rhs)7674681b5dSFrançois Tigeot timespec_sub(struct timespec lhs, struct timespec rhs)
7774681b5dSFrançois Tigeot {
7874681b5dSFrançois Tigeot struct timespec ts;
7974681b5dSFrançois Tigeot
80944cd60cSSascha Wildner timespecsub(&lhs, &rhs, &ts);
8174681b5dSFrançois Tigeot
8274681b5dSFrançois Tigeot return ts;
8374681b5dSFrançois Tigeot }
8474681b5dSFrançois Tigeot
8574681b5dSFrançois Tigeot static inline void
set_normalized_timespec(struct timespec * ts,time_t sec,int64_t nsec)8674681b5dSFrançois Tigeot set_normalized_timespec(struct timespec *ts, time_t sec, int64_t nsec)
8774681b5dSFrançois Tigeot {
8874681b5dSFrançois Tigeot /* XXX: this doesn't actually normalize anything */
8974681b5dSFrançois Tigeot ts->tv_sec = sec;
9074681b5dSFrançois Tigeot ts->tv_nsec = nsec;
9174681b5dSFrançois Tigeot }
9274681b5dSFrançois Tigeot
9316ad3371SFrançois Tigeot static inline int64_t
timespec_to_ns(const struct timespec * ts)9416ad3371SFrançois Tigeot timespec_to_ns(const struct timespec *ts)
9516ad3371SFrançois Tigeot {
9616ad3371SFrançois Tigeot return ((ts->tv_sec * NSEC_PER_SEC) + ts->tv_nsec);
9716ad3371SFrançois Tigeot }
9816ad3371SFrançois Tigeot
9916ad3371SFrançois Tigeot static inline struct timespec
ns_to_timespec(const int64_t nsec)10016ad3371SFrançois Tigeot ns_to_timespec(const int64_t nsec)
10116ad3371SFrançois Tigeot {
10216ad3371SFrançois Tigeot struct timespec ts;
10316ad3371SFrançois Tigeot int32_t rem;
10416ad3371SFrançois Tigeot
10516ad3371SFrançois Tigeot if (nsec == 0) {
10616ad3371SFrançois Tigeot ts.tv_sec = 0;
10716ad3371SFrançois Tigeot ts.tv_nsec = 0;
10816ad3371SFrançois Tigeot return (ts);
10916ad3371SFrançois Tigeot }
11016ad3371SFrançois Tigeot
11116ad3371SFrançois Tigeot ts.tv_sec = nsec / NSEC_PER_SEC;
11216ad3371SFrançois Tigeot rem = nsec % NSEC_PER_SEC;
11316ad3371SFrançois Tigeot if (rem < 0) {
11416ad3371SFrançois Tigeot ts.tv_sec--;
11516ad3371SFrançois Tigeot rem += NSEC_PER_SEC;
11616ad3371SFrançois Tigeot }
11716ad3371SFrançois Tigeot ts.tv_nsec = rem;
11816ad3371SFrançois Tigeot return (ts);
11916ad3371SFrançois Tigeot }
12016ad3371SFrançois Tigeot
12116ad3371SFrançois Tigeot static inline int
timespec_valid(const struct timespec * ts)12216ad3371SFrançois Tigeot timespec_valid(const struct timespec *ts)
12316ad3371SFrançois Tigeot {
12416ad3371SFrançois Tigeot if (ts->tv_sec < 0 || ts->tv_sec > 100000000 ||
12516ad3371SFrançois Tigeot ts->tv_nsec < 0 || ts->tv_nsec >= 1000000000)
12616ad3371SFrançois Tigeot return (0);
12716ad3371SFrançois Tigeot return (1);
12816ad3371SFrançois Tigeot }
12916ad3371SFrançois Tigeot
13030c432c9SFrançois Tigeot static inline unsigned long
get_seconds(void)13130c432c9SFrançois Tigeot get_seconds(void)
13230c432c9SFrançois Tigeot {
13330c432c9SFrançois Tigeot return time_uptime;
13430c432c9SFrançois Tigeot }
13530c432c9SFrançois Tigeot
13674681b5dSFrançois Tigeot #endif /* _LINUX_TIME_H_ */
137