Home | History | Annotate | Download | only in linux
      1 /*
      2  *  include/linux/ktime.h
      3  *
      4  *  ktime_t - nanosecond-resolution time format.
      5  *
      6  *   Copyright(C) 2005, Thomas Gleixner <tglx (at) linutronix.de>
      7  *   Copyright(C) 2005, Red Hat, Inc., Ingo Molnar
      8  *
      9  *  data type definitions, declarations, prototypes and macros.
     10  *
     11  *  Started by: Thomas Gleixner and Ingo Molnar
     12  *
     13  *  Credits:
     14  *
     15  *  	Roman Zippel provided the ideas and primary code snippets of
     16  *  	the ktime_t union and further simplifications of the original
     17  *  	code.
     18  *
     19  *  For licencing details see kernel-base/COPYING
     20  */
     21 #ifndef _LINUX_KTIME_H
     22 #define _LINUX_KTIME_H
     23 
     24 #include <linux/time.h>
     25 #include <linux/jiffies.h>
     26 
     27 /*
     28  * ktime_t:
     29  *
     30  * On 64-bit CPUs a single 64-bit variable is used to store the hrtimers
     31  * internal representation of time values in scalar nanoseconds. The
     32  * design plays out best on 64-bit CPUs, where most conversions are
     33  * NOPs and most arithmetic ktime_t operations are plain arithmetic
     34  * operations.
     35  *
     36  * On 32-bit CPUs an optimized representation of the timespec structure
     37  * is used to avoid expensive conversions from and to timespecs. The
     38  * endian-aware order of the tv struct members is choosen to allow
     39  * mathematical operations on the tv64 member of the union too, which
     40  * for certain operations produces better code.
     41  *
     42  * For architectures with efficient support for 64/32-bit conversions the
     43  * plain scalar nanosecond based representation can be selected by the
     44  * config switch CONFIG_KTIME_SCALAR.
     45  */
     46 typedef union {
     47 	s64	tv64;
     48 #if BITS_PER_LONG != 64 && !defined(CONFIG_KTIME_SCALAR)
     49 	struct {
     50 # ifdef __BIG_ENDIAN
     51 	s32	sec, nsec;
     52 # else
     53 	s32	nsec, sec;
     54 # endif
     55 	} tv;
     56 #endif
     57 } ktime_t;
     58 
     59 #define KTIME_MAX			((s64)~((u64)1 << 63))
     60 #define KTIME_SEC_MAX			(KTIME_MAX / NSEC_PER_SEC)
     61 
     62 /*
     63  * ktime_t definitions when using the 64-bit scalar representation:
     64  */
     65 
     66 #if (BITS_PER_LONG == 64) || defined(CONFIG_KTIME_SCALAR)
     67 
     68 /**
     69  * ktime_set - Set a ktime_t variable from a seconds/nanoseconds value
     70  * @secs:	seconds to set
     71  * @nsecs:	nanoseconds to set
     72  *
     73  * Return the ktime_t representation of the value
     74  */
     75 static inline ktime_t ktime_set(const long secs, const unsigned long nsecs)
     76 {
     77 #if (BITS_PER_LONG == 64)
     78 	if (unlikely(secs >= KTIME_SEC_MAX))
     79 		return (ktime_t){ .tv64 = KTIME_MAX };
     80 #endif
     81 	return (ktime_t) { .tv64 = (s64)secs * NSEC_PER_SEC + (s64)nsecs };
     82 }
     83 
     84 /* Subtract two ktime_t variables. rem = lhs -rhs: */
     85 #define ktime_sub(lhs, rhs) \
     86 		({ (ktime_t){ .tv64 = (lhs).tv64 - (rhs).tv64 }; })
     87 
     88 /* Add two ktime_t variables. res = lhs + rhs: */
     89 #define ktime_add(lhs, rhs) \
     90 		({ (ktime_t){ .tv64 = (lhs).tv64 + (rhs).tv64 }; })
     91 
     92 /*
     93  * Add a ktime_t variable and a scalar nanosecond value.
     94  * res = kt + nsval:
     95  */
     96 #define ktime_add_ns(kt, nsval) \
     97 		({ (ktime_t){ .tv64 = (kt).tv64 + (nsval) }; })
     98 
     99 /* convert a timespec to ktime_t format: */
    100 static inline ktime_t timespec_to_ktime(struct timespec ts)
    101 {
    102 	return ktime_set(ts.tv_sec, ts.tv_nsec);
    103 }
    104 
    105 /* convert a timeval to ktime_t format: */
    106 static inline ktime_t timeval_to_ktime(struct timeval tv)
    107 {
    108 	return ktime_set(tv.tv_sec, tv.tv_usec * NSEC_PER_USEC);
    109 }
    110 
    111 /* Map the ktime_t to timespec conversion to ns_to_timespec function */
    112 #define ktime_to_timespec(kt)		ns_to_timespec((kt).tv64)
    113 
    114 /* Map the ktime_t to timeval conversion to ns_to_timeval function */
    115 #define ktime_to_timeval(kt)		ns_to_timeval((kt).tv64)
    116 
    117 /* Convert ktime_t to nanoseconds - NOP in the scalar storage format: */
    118 #define ktime_to_ns(kt)			((kt).tv64)
    119 
    120 #else
    121 
    122 /*
    123  * Helper macros/inlines to get the ktime_t math right in the timespec
    124  * representation. The macros are sometimes ugly - their actual use is
    125  * pretty okay-ish, given the circumstances. We do all this for
    126  * performance reasons. The pure scalar nsec_t based code was nice and
    127  * simple, but created too many 64-bit / 32-bit conversions and divisions.
    128  *
    129  * Be especially aware that negative values are represented in a way
    130  * that the tv.sec field is negative and the tv.nsec field is greater
    131  * or equal to zero but less than nanoseconds per second. This is the
    132  * same representation which is used by timespecs.
    133  *
    134  *   tv.sec < 0 and 0 >= tv.nsec < NSEC_PER_SEC
    135  */
    136 
    137 /* Set a ktime_t variable to a value in sec/nsec representation: */
    138 static inline ktime_t ktime_set(const long secs, const unsigned long nsecs)
    139 {
    140 	return (ktime_t) { .tv = { .sec = secs, .nsec = nsecs } };
    141 }
    142 
    143 /**
    144  * ktime_sub - subtract two ktime_t variables
    145  * @lhs:	minuend
    146  * @rhs:	subtrahend
    147  *
    148  * Returns the remainder of the substraction
    149  */
    150 static inline ktime_t ktime_sub(const ktime_t lhs, const ktime_t rhs)
    151 {
    152 	ktime_t res;
    153 
    154 	res.tv64 = lhs.tv64 - rhs.tv64;
    155 	if (res.tv.nsec < 0)
    156 		res.tv.nsec += NSEC_PER_SEC;
    157 
    158 	return res;
    159 }
    160 
    161 /**
    162  * ktime_add - add two ktime_t variables
    163  * @add1:	addend1
    164  * @add2:	addend2
    165  *
    166  * Returns the sum of addend1 and addend2
    167  */
    168 static inline ktime_t ktime_add(const ktime_t add1, const ktime_t add2)
    169 {
    170 	ktime_t res;
    171 
    172 	res.tv64 = add1.tv64 + add2.tv64;
    173 	/*
    174 	 * performance trick: the (u32) -NSEC gives 0x00000000Fxxxxxxx
    175 	 * so we subtract NSEC_PER_SEC and add 1 to the upper 32 bit.
    176 	 *
    177 	 * it's equivalent to:
    178 	 *   tv.nsec -= NSEC_PER_SEC
    179 	 *   tv.sec ++;
    180 	 */
    181 	if (res.tv.nsec >= NSEC_PER_SEC)
    182 		res.tv64 += (u32)-NSEC_PER_SEC;
    183 
    184 	return res;
    185 }
    186 
    187 /**
    188  * ktime_add_ns - Add a scalar nanoseconds value to a ktime_t variable
    189  * @kt:		addend
    190  * @nsec:	the scalar nsec value to add
    191  *
    192  * Returns the sum of kt and nsec in ktime_t format
    193  */
    194 extern ktime_t ktime_add_ns(const ktime_t kt, u64 nsec);
    195 
    196 /**
    197  * timespec_to_ktime - convert a timespec to ktime_t format
    198  * @ts:		the timespec variable to convert
    199  *
    200  * Returns a ktime_t variable with the converted timespec value
    201  */
    202 static inline ktime_t timespec_to_ktime(const struct timespec ts)
    203 {
    204 	return (ktime_t) { .tv = { .sec = (s32)ts.tv_sec,
    205 			   	   .nsec = (s32)ts.tv_nsec } };
    206 }
    207 
    208 /**
    209  * timeval_to_ktime - convert a timeval to ktime_t format
    210  * @tv:		the timeval variable to convert
    211  *
    212  * Returns a ktime_t variable with the converted timeval value
    213  */
    214 static inline ktime_t timeval_to_ktime(const struct timeval tv)
    215 {
    216 	return (ktime_t) { .tv = { .sec = (s32)tv.tv_sec,
    217 				   .nsec = (s32)tv.tv_usec * 1000 } };
    218 }
    219 
    220 /**
    221  * ktime_to_timespec - convert a ktime_t variable to timespec format
    222  * @kt:		the ktime_t variable to convert
    223  *
    224  * Returns the timespec representation of the ktime value
    225  */
    226 static inline struct timespec ktime_to_timespec(const ktime_t kt)
    227 {
    228 	return (struct timespec) { .tv_sec = (time_t) kt.tv.sec,
    229 				   .tv_nsec = (long) kt.tv.nsec };
    230 }
    231 
    232 /**
    233  * ktime_to_timeval - convert a ktime_t variable to timeval format
    234  * @kt:		the ktime_t variable to convert
    235  *
    236  * Returns the timeval representation of the ktime value
    237  */
    238 static inline struct timeval ktime_to_timeval(const ktime_t kt)
    239 {
    240 	return (struct timeval) {
    241 		.tv_sec = (time_t) kt.tv.sec,
    242 		.tv_usec = (suseconds_t) (kt.tv.nsec / NSEC_PER_USEC) };
    243 }
    244 
    245 /**
    246  * ktime_to_ns - convert a ktime_t variable to scalar nanoseconds
    247  * @kt:		the ktime_t variable to convert
    248  *
    249  * Returns the scalar nanoseconds representation of kt
    250  */
    251 static inline u64 ktime_to_ns(const ktime_t kt)
    252 {
    253 	return (u64) kt.tv.sec * NSEC_PER_SEC + kt.tv.nsec;
    254 }
    255 
    256 #endif
    257 
    258 /*
    259  * The resolution of the clocks. The resolution value is returned in
    260  * the clock_getres() system call to give application programmers an
    261  * idea of the (in)accuracy of timers. Timer values are rounded up to
    262  * this resolution values.
    263  */
    264 #define KTIME_REALTIME_RES	(ktime_t){ .tv64 = TICK_NSEC }
    265 #define KTIME_MONOTONIC_RES	(ktime_t){ .tv64 = TICK_NSEC }
    266 
    267 /* Get the monotonic time in timespec format: */
    268 extern void ktime_get_ts(struct timespec *ts);
    269 
    270 /* Get the real (wall-) time in timespec format: */
    271 #define ktime_get_real_ts(ts)	getnstimeofday(ts)
    272 
    273 #endif
    274