Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+118
+28
include/linux/ktime.h
··· 83 83 return ktime_set(ts.tv_sec, ts.tv_nsec); 84 84 } 85 85 86 + /* convert a timespec64 to ktime_t format: */ 87 + static inline ktime_t timespec64_to_ktime(struct timespec64 ts) 88 + { 89 + return ktime_set(ts.tv_sec, ts.tv_nsec); 90 + } 91 + 86 92 /* convert a timeval to ktime_t format: */ 87 93 static inline ktime_t timeval_to_ktime(struct timeval tv) 88 94 { ··· 97 91 98 92 /* Map the ktime_t to timespec conversion to ns_to_timespec function */ 99 93 #define ktime_to_timespec(kt) ns_to_timespec((kt).tv64) 94 + 95 + /* Map the ktime_t to timespec conversion to ns_to_timespec function */ 96 + #define ktime_to_timespec64(kt) ns_to_timespec64((kt).tv64) 100 97 101 98 /* Map the ktime_t to timeval conversion to ns_to_timeval function */ 102 99 #define ktime_to_timeval(kt) ns_to_timeval((kt).tv64) ··· 216 207 { 217 208 if (kt.tv64) { 218 209 *ts = ktime_to_timespec(kt); 210 + return true; 211 + } else { 212 + return false; 213 + } 214 + } 215 + 216 + /** 217 + * ktime_to_timespec64_cond - convert a ktime_t variable to timespec64 218 + * format only if the variable contains data 219 + * @kt: the ktime_t variable to convert 220 + * @ts: the timespec variable to store the result in 221 + * 222 + * Return: %true if there was a successful conversion, %false if kt was 0. 223 + */ 224 + static inline __must_check bool ktime_to_timespec64_cond(const ktime_t kt, 225 + struct timespec64 *ts) 226 + { 227 + if (kt.tv64) { 228 + *ts = ktime_to_timespec64(kt); 219 229 return true; 220 230 } else { 221 231 return false;
+28
include/linux/time64.h
··· 33 33 34 34 #if __BITS_PER_LONG == 64 35 35 36 + static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64) 37 + { 38 + return ts64; 39 + } 40 + 41 + static inline struct timespec64 timespec_to_timespec64(const struct timespec ts) 42 + { 43 + return ts; 44 + } 45 + 36 46 # define timespec64_equal timespec_equal 37 47 # define timespec64_compare timespec_compare 38 48 # define set_normalized_timespec64 set_normalized_timespec ··· 56 46 # define timespec64_add_ns timespec_add_ns 57 47 58 48 #else 49 + 50 + static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64) 51 + { 52 + struct timespec ret; 53 + 54 + ret.tv_sec = (time_t)ts64.tv_sec; 55 + ret.tv_nsec = ts64.tv_nsec; 56 + return ret; 57 + } 58 + 59 + static inline struct timespec64 timespec_to_timespec64(const struct timespec ts) 60 + { 61 + struct timespec64 ret; 62 + 63 + ret.tv_sec = ts.tv_sec; 64 + ret.tv_nsec = ts.tv_nsec; 65 + return ret; 66 + } 59 67 60 68 static inline int timespec64_equal(const struct timespec64 *a, 61 69 const struct timespec64 *b)
+62
kernel/time/time.c
··· 420 420 } 421 421 EXPORT_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 + */ 438 + void 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 + } 458 + EXPORT_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 + */ 466 + struct 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 + } 483 + EXPORT_SYMBOL(ns_to_timespec64); 484 + #endif 423 485 /* 424 486 * When we convert to jiffies then we interpret incoming values 425 487 * the following way: