aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Stultz <john.stultz@linaro.org>2014-07-16 17:03:59 -0400
committerJohn Stultz <john.stultz@linaro.org>2014-07-23 13:17:53 -0400
commit49cd6f869984692547c57621bf42697aaa7f5622 (patch)
treef0bb760b91afa73f12f6f90db14b190728c0780b
parent361a3bf00582469877f8d18ff20f1efa6b781274 (diff)
time: More core infrastructure for timespec64
Helper and conversion functions for timespec64. Signed-off-by: John Stultz <john.stultz@linaro.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: John Stultz <john.stultz@linaro.org>
-rw-r--r--include/linux/ktime.h28
-rw-r--r--include/linux/time64.h28
-rw-r--r--kernel/time/time.c62
3 files changed, 118 insertions, 0 deletions
diff --git a/include/linux/ktime.h b/include/linux/ktime.h
index 538c283714e1..da6b680c252b 100644
--- a/include/linux/ktime.h
+++ b/include/linux/ktime.h
@@ -83,6 +83,12 @@ static inline ktime_t timespec_to_ktime(struct timespec ts)
83 return ktime_set(ts.tv_sec, ts.tv_nsec); 83 return ktime_set(ts.tv_sec, ts.tv_nsec);
84} 84}
85 85
86/* convert a timespec64 to ktime_t format: */
87static inline ktime_t timespec64_to_ktime(struct timespec64 ts)
88{
89 return ktime_set(ts.tv_sec, ts.tv_nsec);
90}
91
86/* convert a timeval to ktime_t format: */ 92/* convert a timeval to ktime_t format: */
87static inline ktime_t timeval_to_ktime(struct timeval tv) 93static inline ktime_t timeval_to_ktime(struct timeval tv)
88{ 94{
@@ -92,6 +98,9 @@ static inline ktime_t timeval_to_ktime(struct timeval tv)
92/* Map the ktime_t to timespec conversion to ns_to_timespec function */ 98/* Map the ktime_t to timespec conversion to ns_to_timespec function */
93#define ktime_to_timespec(kt) ns_to_timespec((kt).tv64) 99#define ktime_to_timespec(kt) ns_to_timespec((kt).tv64)
94 100
101/* Map the ktime_t to timespec conversion to ns_to_timespec function */
102#define ktime_to_timespec64(kt) ns_to_timespec64((kt).tv64)
103
95/* Map the ktime_t to timeval conversion to ns_to_timeval function */ 104/* Map the ktime_t to timeval conversion to ns_to_timeval function */
96#define ktime_to_timeval(kt) ns_to_timeval((kt).tv64) 105#define ktime_to_timeval(kt) ns_to_timeval((kt).tv64)
97 106
@@ -213,6 +222,25 @@ static inline __must_check bool ktime_to_timespec_cond(const ktime_t kt,
213 } 222 }
214} 223}
215 224
225/**
226 * ktime_to_timespec64_cond - convert a ktime_t variable to timespec64
227 * format only if the variable contains data
228 * @kt: the ktime_t variable to convert
229 * @ts: the timespec variable to store the result in
230 *
231 * Return: %true if there was a successful conversion, %false if kt was 0.
232 */
233static inline __must_check bool ktime_to_timespec64_cond(const ktime_t kt,
234 struct timespec64 *ts)
235{
236 if (kt.tv64) {
237 *ts = ktime_to_timespec64(kt);
238 return true;
239 } else {
240 return false;
241 }
242}
243
216/* 244/*
217 * The resolution of the clocks. The resolution value is returned in 245 * The resolution of the clocks. The resolution value is returned in
218 * the clock_getres() system call to give application programmers an 246 * the clock_getres() system call to give application programmers an
diff --git a/include/linux/time64.h b/include/linux/time64.h
index e7b499e1cd79..a3831478d9cf 100644
--- a/include/linux/time64.h
+++ b/include/linux/time64.h
@@ -33,6 +33,16 @@ struct timespec64 {
33 33
34#if __BITS_PER_LONG == 64 34#if __BITS_PER_LONG == 64
35 35
36static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64)
37{
38 return ts64;
39}
40
41static inline struct timespec64 timespec_to_timespec64(const struct timespec ts)
42{
43 return ts;
44}
45
36# define timespec64_equal timespec_equal 46# define timespec64_equal timespec_equal
37# define timespec64_compare timespec_compare 47# define timespec64_compare timespec_compare
38# define set_normalized_timespec64 set_normalized_timespec 48# define set_normalized_timespec64 set_normalized_timespec
@@ -47,6 +57,24 @@ struct timespec64 {
47 57
48#else 58#else
49 59
60static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64)
61{
62 struct timespec ret;
63
64 ret.tv_sec = (time_t)ts64.tv_sec;
65 ret.tv_nsec = ts64.tv_nsec;
66 return ret;
67}
68
69static inline struct timespec64 timespec_to_timespec64(const struct timespec ts)
70{
71 struct timespec64 ret;
72
73 ret.tv_sec = ts.tv_sec;
74 ret.tv_nsec = ts.tv_nsec;
75 return ret;
76}
77
50static inline int timespec64_equal(const struct timespec64 *a, 78static inline int timespec64_equal(const struct timespec64 *a,
51 const struct timespec64 *b) 79 const struct timespec64 *b)
52{ 80{
diff --git a/kernel/time/time.c b/kernel/time/time.c
index 7c7964c33ae7..e8121a67fd74 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -420,6 +420,68 @@ struct timeval ns_to_timeval(const s64 nsec)
420} 420}
421EXPORT_SYMBOL(ns_to_timeval); 421EXPORT_SYMBOL(ns_to_timeval);
422 422
423#if BITS_PER_LONG == 32
424/**
425 * set_normalized_timespec - set timespec sec and nsec parts and normalize
426 *
427 * @ts: pointer to timespec variable to be set
428 * @sec: seconds to set
429 * @nsec: nanoseconds to set
430 *
431 * Set seconds and nanoseconds field of a timespec variable and
432 * normalize to the timespec storage format
433 *
434 * Note: The tv_nsec part is always in the range of
435 * 0 <= tv_nsec < NSEC_PER_SEC
436 * For negative values only the tv_sec field is negative !
437 */
438void set_normalized_timespec64(struct timespec64 *ts, time64_t sec, s64 nsec)
439{
440 while (nsec >= NSEC_PER_SEC) {
441 /*
442 * The following asm() prevents the compiler from
443 * optimising this loop into a modulo operation. See
444 * also __iter_div_u64_rem() in include/linux/time.h
445 */
446 asm("" : "+rm"(nsec));
447 nsec -= NSEC_PER_SEC;
448 ++sec;
449 }
450 while (nsec < 0) {
451 asm("" : "+rm"(nsec));
452 nsec += NSEC_PER_SEC;
453 --sec;
454 }
455 ts->tv_sec = sec;
456 ts->tv_nsec = nsec;
457}
458EXPORT_SYMBOL(set_normalized_timespec64);
459
460/**
461 * ns_to_timespec64 - Convert nanoseconds to timespec64
462 * @nsec: the nanoseconds value to be converted
463 *
464 * Returns the timespec64 representation of the nsec parameter.
465 */
466struct timespec64 ns_to_timespec64(const s64 nsec)
467{
468 struct timespec64 ts;
469 s32 rem;
470
471 if (!nsec)
472 return (struct timespec64) {0, 0};
473
474 ts.tv_sec = div_s64_rem(nsec, NSEC_PER_SEC, &rem);
475 if (unlikely(rem < 0)) {
476 ts.tv_sec--;
477 rem += NSEC_PER_SEC;
478 }
479 ts.tv_nsec = rem;
480
481 return ts;
482}
483EXPORT_SYMBOL(ns_to_timespec64);
484#endif
423/* 485/*
424 * When we convert to jiffies then we interpret incoming values 486 * When we convert to jiffies then we interpret incoming values
425 * the following way: 487 * the following way: