From: Thomas Gleixner <tglx@linutronix.de>
To: LKML <linux-kernel@vger.kernel.org>
Cc: John Stultz <john.stultz@linaro.org>,
Peter Zijlstra <peterz@infradead.org>
Subject: [patch 07/55] time64: Add time64.h header and define struct timespec64
Date: Fri, 11 Jul 2014 13:44:08 -0000 [thread overview]
Message-ID: <20140711133705.830480055@linutronix.de> (raw)
In-Reply-To: 20140711133623.530368377@linutronix.de
[-- Attachment #1: jstultz-tk-d8e0c56.patch --]
[-- Type: text/plain, Size: 6131 bytes --]
From: John Stultz <john.stultz@linaro.org>
Define the timespec64 structure and standard helper functions.
[ tglx: Make it 32bit only. 64bit really can map timespec to timespec64 ]
Signed-off-by: John Stultz <john.stultz@linaro.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
include/linux/time.h | 15 ----
include/linux/time64.h | 163 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 164 insertions(+), 14 deletions(-)
Index: tip/include/linux/time.h
===================================================================
--- tip.orig/include/linux/time.h
+++ tip/include/linux/time.h
@@ -4,25 +4,12 @@
# include <linux/cache.h>
# include <linux/seqlock.h>
# include <linux/math64.h>
-#include <uapi/linux/time.h>
+# include <linux/time64.h>
extern struct timezone sys_tz;
-/* Parameters used to convert the timespec values: */
-#define MSEC_PER_SEC 1000L
-#define USEC_PER_MSEC 1000L
-#define NSEC_PER_USEC 1000L
-#define NSEC_PER_MSEC 1000000L
-#define USEC_PER_SEC 1000000L
-#define NSEC_PER_SEC 1000000000L
-#define FSEC_PER_SEC 1000000000000000LL
-
#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
-/* Located here for timespec_valid_strict */
-#define KTIME_MAX ((s64)~((u64)1 << 63))
-#define KTIME_SEC_MAX (KTIME_MAX / NSEC_PER_SEC)
-
static inline int timespec_equal(const struct timespec *a,
const struct timespec *b)
{
Index: tip/include/linux/time64.h
===================================================================
--- /dev/null
+++ tip/include/linux/time64.h
@@ -0,0 +1,163 @@
+#ifndef _LINUX_TIME64_H
+#define _LINUX_TIME64_H
+
+#include <uapi/linux/time.h>
+
+typedef __s64 time64_t;
+
+/*
+ * This wants to go into uapi/linux/time.h once we agreed about the
+ * userspace interfaces.
+ */
+#if __BITS_PER_LONG == 64
+# define timespec64 timespec
+#else
+struct timespec64 {
+ time64_t tv_sec; /* seconds */
+ long tv_nsec; /* nanoseconds */
+};
+#endif
+
+/* Parameters used to convert the timespec values: */
+#define MSEC_PER_SEC 1000L
+#define USEC_PER_MSEC 1000L
+#define NSEC_PER_USEC 1000L
+#define NSEC_PER_MSEC 1000000L
+#define USEC_PER_SEC 1000000L
+#define NSEC_PER_SEC 1000000000L
+#define FSEC_PER_SEC 1000000000000000LL
+
+/* Located here for timespec[64]_valid_strict */
+#define KTIME_MAX ((s64)~((u64)1 << 63))
+#define KTIME_SEC_MAX (KTIME_MAX / NSEC_PER_SEC)
+
+#if __BITS_PER_LONG == 64
+
+# define timespec64_equal timespec_equal
+# define timespec64_compare timespec_compare
+# define set_normalized_timespec64 set_normalized_timespec
+# define timespec64_add_safe timespec_add_safe
+# define timespec64_add timespec_add
+# define timespec64_sub timespec_sub
+# define timespec64_valid timespec_valid
+# define timespec64_valid_strict timespec_valid_strict
+# define timespec64_to_ns timespec_to_ns
+# define ns_to_timespec64 ns_to_timespec
+# define timespec64_add_ns timespec_add_ns
+
+#else
+
+static inline int timespec64_equal(const struct timespec64 *a,
+ const struct timespec64 *b)
+{
+ return (a->tv_sec == b->tv_sec) && (a->tv_nsec == b->tv_nsec);
+}
+
+/*
+ * lhs < rhs: return <0
+ * lhs == rhs: return 0
+ * lhs > rhs: return >0
+ */
+static inline int timespec64_compare(const struct timespec64 *lhs, const struct timespec64 *rhs)
+{
+ if (lhs->tv_sec < rhs->tv_sec)
+ return -1;
+ if (lhs->tv_sec > rhs->tv_sec)
+ return 1;
+ return lhs->tv_nsec - rhs->tv_nsec;
+}
+
+extern void set_normalized_timespec64(struct timespec64 *ts, time64_t sec, s64 nsec);
+
+/*
+ * timespec64_add_safe assumes both values are positive and checks
+ * for overflow. It will return TIME_T_MAX if the reutrn would be
+ * smaller then either of the arguments.
+ */
+extern struct timespec64 timespec64_add_safe(const struct timespec64 lhs,
+ const struct timespec64 rhs);
+
+
+static inline struct timespec64 timespec64_add(struct timespec64 lhs,
+ struct timespec64 rhs)
+{
+ struct timespec64 ts_delta;
+ set_normalized_timespec64(&ts_delta, lhs.tv_sec + rhs.tv_sec,
+ lhs.tv_nsec + rhs.tv_nsec);
+ return ts_delta;
+}
+
+/*
+ * sub = lhs - rhs, in normalized form
+ */
+static inline struct timespec64 timespec64_sub(struct timespec64 lhs,
+ struct timespec64 rhs)
+{
+ struct timespec64 ts_delta;
+ set_normalized_timespec64(&ts_delta, lhs.tv_sec - rhs.tv_sec,
+ lhs.tv_nsec - rhs.tv_nsec);
+ return ts_delta;
+}
+
+/*
+ * Returns true if the timespec64 is norm, false if denorm:
+ */
+static inline bool timespec64_valid(const struct timespec64 *ts)
+{
+ /* Dates before 1970 are bogus */
+ if (ts->tv_sec < 0)
+ return false;
+ /* Can't have more nanoseconds then a second */
+ if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC)
+ return false;
+ return true;
+}
+
+static inline bool timespec64_valid_strict(const struct timespec64 *ts)
+{
+ if (!timespec64_valid(ts))
+ return false;
+ /* Disallow values that could overflow ktime_t */
+ if ((unsigned long long)ts->tv_sec >= KTIME_SEC_MAX)
+ return false;
+ return true;
+}
+
+/**
+ * timespec64_to_ns - Convert timespec64 to nanoseconds
+ * @ts: pointer to the timespec64 variable to be converted
+ *
+ * Returns the scalar nanosecond representation of the timespec64
+ * parameter.
+ */
+static inline s64 timespec64_to_ns(const struct timespec64 *ts)
+{
+ return ((s64) ts->tv_sec * NSEC_PER_SEC) + ts->tv_nsec;
+}
+
+/**
+ * ns_to_timespec64 - Convert nanoseconds to timespec64
+ * @nsec: the nanoseconds value to be converted
+ *
+ * Returns the timespec64 representation of the nsec parameter.
+ */
+extern struct timespec64 ns_to_timespec64(const s64 nsec);
+
+/**
+ * timespec64_add_ns - Adds nanoseconds to a timespec64
+ * @a: pointer to timespec64 to be incremented
+ * @ns: unsigned nanoseconds value to be added
+ *
+ * This must always be inlined because its used from the x86-64 vdso,
+ * which cannot call other kernel functions.
+ */
+static __always_inline void timespec64_add_ns(struct timespec64 *a, u64 ns)
+{
+ a->tv_sec += __iter_div_u64_rem(a->tv_nsec + ns, NSEC_PER_SEC, &ns);
+ a->tv_nsec = ns;
+}
+
+#endif
+
+#endif /* _LINUX_TIME64_H */
+
next prev parent reply other threads:[~2014-07-11 14:00 UTC|newest]
Thread overview: 91+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-07-11 13:43 [patch 00/55] timekeeping: 2038, optimizations, NMI safe accessors Thomas Gleixner
2014-07-11 13:43 ` [patch 01/55] tile: Convert VDSO timekeeping to the precise mechanism Thomas Gleixner
2014-07-18 2:32 ` Chris Metcalf
2014-07-11 13:44 ` [patch 02/55] timekeeping: Simplify arch_gettimeoffset() Thomas Gleixner
2014-07-11 14:10 ` Geert Uytterhoeven
2014-07-11 13:44 ` [patch 03/55] hrtimer: Cleanup hrtimer accessors to the timekepeing state Thomas Gleixner
2014-07-11 13:44 ` [patch 04/55] ktime: Kill non-scalar ktime_t implementation for 2038 Thomas Gleixner
2014-07-11 13:44 ` [patch 05/55] ktime: Sanitize ktime_to_us/ms conversion Thomas Gleixner
2014-07-11 13:44 ` [patch 06/55] ktime: Change ktime_set() to take 64bit seconds value Thomas Gleixner
2014-07-11 13:44 ` Thomas Gleixner [this message]
2014-07-11 18:41 ` [patch 07/55] time64: Add time64.h header and define struct timespec64 Richard Cochran
2014-07-11 13:44 ` [patch 08/55] time: More core infrastructure for timespec64 Thomas Gleixner
2014-07-11 13:44 ` [patch 09/55] timekeeping: Convert timekeeping core to use timespec64s Thomas Gleixner
2014-07-11 13:44 ` [patch 10/55] time: Consolidate the time accessor prototypes Thomas Gleixner
2014-07-11 13:44 ` [patch 11/55] timekeeping: Provide timespec64 based interfaces Thomas Gleixner
2014-07-11 13:44 ` [patch 12/55] timekeeper: Move tk_xtime to core code Thomas Gleixner
2014-07-11 13:44 ` [patch 13/55] timekeeping: Cache optimize struct timekeeper Thomas Gleixner
2014-07-11 13:44 ` [patch 14/55] timekeeping: Provide internal ktime_t based data Thomas Gleixner
2014-07-16 3:29 ` John Stultz
2014-07-16 7:00 ` Thomas Gleixner
2014-07-16 7:12 ` Thomas Gleixner
2014-07-16 7:20 ` Peter Zijlstra
2014-07-11 13:44 ` [patch 15/55] timekeeping: Use ktime_t based data for ktime_get() Thomas Gleixner
2014-07-11 13:44 ` [patch 16/55] timekeeping: Provide ktime_get_with_offset() Thomas Gleixner
2014-07-11 13:44 ` [patch 17/55] timekeeping: Use ktime_t based data for ktime_get_real() Thomas Gleixner
2014-07-11 13:44 ` [patch 18/55] timekeeping; Use ktime_t based data for ktime_get_boottime() Thomas Gleixner
2014-07-11 13:44 ` [patch 19/55] timekeeping: Use ktime_t based data for ktime_get_clocktai() Thomas Gleixner
2014-07-11 13:44 ` [patch 20/55] timekeeping: Use ktime_t data for ktime_get_update_offsets_now() Thomas Gleixner
2014-07-11 13:44 ` [patch 21/55] timekeeping; Use ktime based data for ktime_get_update_offsets_tick() Thomas Gleixner
2014-07-11 13:44 ` [patch 22/55] timekeeping: Provide ktime_mono_to_any() Thomas Gleixner
2014-07-11 13:44 ` [patch 23/55] timerfd: Use ktime_mono_to_real() Thomas Gleixner
2014-07-11 13:44 ` [patch 24/55] input: evdev: " Thomas Gleixner
2014-07-11 13:44 ` [patch 25/55] drm: " Thomas Gleixner
2014-07-11 13:44 ` [patch 26/55] timekeeping: Remove ktime_get_monotonic_offset() Thomas Gleixner
2014-07-11 13:44 ` [patch 27/55] timekeeping: Provide ktime_get[*]_ns() helpers Thomas Gleixner
2014-07-11 13:44 ` [patch 28/55] time-export-nsecs-to-jiffies.patch Thomas Gleixner
2014-07-11 13:44 ` [patch 29/55] sched: Make task->real_start_time nanoseconds based Thomas Gleixner
2014-07-11 13:44 ` [patch 30/55] sched: Make task->start_time " Thomas Gleixner
2014-07-11 13:44 ` [patch 31/55] delayacct: Make accounting nanosecond based Thomas Gleixner
2014-07-11 13:44 ` [patch 32/55] delayacct: Remove braindamaged type conversions Thomas Gleixner
2014-07-11 13:44 ` [patch 33/55] powerpc: cell: Use ktime_get_ns() Thomas Gleixner
2014-07-11 17:02 ` Arnd Bergmann
2014-07-11 13:44 ` [patch 34/55] connector: " Thomas Gleixner
2014-07-11 13:44 ` [patch 35/55] mfd: cros_ec_spi: " Thomas Gleixner
2014-07-11 14:52 ` Lee Jones
2014-07-12 19:40 ` Thomas Gleixner
2014-07-14 7:07 ` Lee Jones
2014-07-11 13:44 ` [patch 36/55] misc: ioc4: " Thomas Gleixner
2014-07-11 17:03 ` Arnd Bergmann
2014-07-12 0:26 ` Greg Kroah-Hartman
2014-07-11 13:44 ` [patch 37/55] net: mlx5: " Thomas Gleixner
2014-07-11 13:44 ` [patch 38/55] fs: lockd: " Thomas Gleixner
2014-07-11 14:04 ` Trond Myklebust
2014-07-11 13:44 ` [patch 39/55] hwmon: ibmaem: " Thomas Gleixner
2014-07-11 13:44 ` [patch 40/55] iio: Use ktime_get_real_ns() Thomas Gleixner
2014-07-13 9:21 ` Jonathan Cameron
2014-07-11 13:44 ` [patch 41/55] arm: bL_switcher:k " Thomas Gleixner
2014-07-11 13:45 ` [patch 42/55] x86: kvm: Use ktime_get_boot_ns() Thomas Gleixner
2014-07-11 13:45 ` [patch 43/55] x86: kvm: Make kvm_get_time_and_clockread() nanoseconds based Thomas Gleixner
2014-07-11 13:45 ` [patch 44/55] timekeeping: Remove monotonic_to_bootbased Thomas Gleixner
2014-07-11 13:45 ` [patch 45/55] timekeeping: Use ktime_get_boottime() for get_monotonic_boottime() Thomas Gleixner
2014-07-11 13:45 ` [patch 46/55] timekeeping: Provide ktime_get_raw() Thomas Gleixner
2014-07-11 13:45 ` [patch 47/55] hangcheck-timer: Use ktime_get_raw_ns() Thomas Gleixner
2014-07-11 17:03 ` Arnd Bergmann
2014-07-12 0:27 ` Greg Kroah-Hartman
2014-07-11 13:45 ` [patch 48/55] drm: i915: Use nsec based interfaces Thomas Gleixner
2014-07-14 9:21 ` Daniel Vetter
2014-07-11 13:45 ` [patch 49/55] drm: vmwgfx: " Thomas Gleixner
2014-07-11 13:45 ` [patch 50/55] wireless: ath9k: Get rid of timespec conversions Thomas Gleixner
2014-07-11 13:45 ` [patch 51/55] clocksource: Make delta calculation a function Thomas Gleixner
2014-07-14 8:31 ` Peter Zijlstra
2014-07-16 3:50 ` John Stultz
2014-07-16 6:58 ` Thomas Gleixner
2014-07-11 13:45 ` [patch 52/55] clocksource: Move cycle_last validation to core code Thomas Gleixner
2014-07-11 13:45 ` [patch 53/55] seqcount: Provide raw_read_seqcount() Thomas Gleixner
2014-07-11 13:45 ` [patch 54/55] timekeeping: Provide fast and NMI safe access to CLOCK_MONOTONIC[_RAW] Thomas Gleixner
2014-07-11 20:04 ` Mathieu Desnoyers
2014-07-12 8:11 ` Thomas Gleixner
2014-07-12 13:59 ` Mathieu Desnoyers
2014-07-12 19:31 ` Thomas Gleixner
2014-07-12 14:53 ` Mathieu Desnoyers
2014-07-12 19:28 ` Thomas Gleixner
2014-07-12 20:04 ` Thomas Gleixner
2014-07-12 20:33 ` Mathieu Desnoyers
2014-07-14 8:37 ` Peter Zijlstra
2014-07-14 9:04 ` Thomas Gleixner
2014-07-14 9:45 ` Peter Zijlstra
2014-07-14 9:47 ` Peter Zijlstra
2014-07-14 12:39 ` Mathieu Desnoyers
2014-07-14 14:15 ` Thomas Gleixner
2014-07-11 13:45 ` [patch 55/55] ftrace: Provide trace clocks mono and mono_raw Thomas Gleixner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140711133705.830480055@linutronix.de \
--to=tglx@linutronix.de \
--cc=john.stultz@linaro.org \
--cc=linux-kernel@vger.kernel.org \
--cc=peterz@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).