LCOV - code coverage report
Current view: top level - include/linux - ktime.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 6 9 66.7 %
Date: 2014-02-18 Functions: 0 0 -
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  *  include/linux/ktime.h
       3                 :            :  *
       4                 :            :  *  ktime_t - nanosecond-resolution time format.
       5                 :            :  *
       6                 :            :  *   Copyright(C) 2005, Thomas Gleixner <tglx@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 chosen 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                 :            : union ktime {
      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                 :            : };
      58                 :            : 
      59                 :            : typedef union ktime ktime_t;            /* Kill this */
      60                 :            : 
      61                 :            : /*
      62                 :            :  * ktime_t definitions when using the 64-bit scalar representation:
      63                 :            :  */
      64                 :            : 
      65                 :            : #if (BITS_PER_LONG == 64) || defined(CONFIG_KTIME_SCALAR)
      66                 :            : 
      67                 :            : /**
      68                 :            :  * ktime_set - Set a ktime_t variable from a seconds/nanoseconds value
      69                 :            :  * @secs:       seconds to set
      70                 :            :  * @nsecs:      nanoseconds to set
      71                 :            :  *
      72                 :            :  * Return: The ktime_t representation of the value.
      73                 :            :  */
      74                 :            : static inline ktime_t ktime_set(const long secs, const unsigned long nsecs)
      75                 :            : {
      76                 :            : #if (BITS_PER_LONG == 64)
      77                 :            :         if (unlikely(secs >= KTIME_SEC_MAX))
      78                 :            :                 return (ktime_t){ .tv64 = KTIME_MAX };
      79                 :            : #endif
      80                 :   61704098 :         return (ktime_t) { .tv64 = (s64)secs * NSEC_PER_SEC + (s64)nsecs };
      81                 :            : }
      82                 :            : 
      83                 :            : /* Subtract two ktime_t variables. rem = lhs -rhs: */
      84                 :            : #define ktime_sub(lhs, rhs) \
      85                 :            :                 ({ (ktime_t){ .tv64 = (lhs).tv64 - (rhs).tv64 }; })
      86                 :            : 
      87                 :            : /* Add two ktime_t variables. res = lhs + rhs: */
      88                 :            : #define ktime_add(lhs, rhs) \
      89                 :            :                 ({ (ktime_t){ .tv64 = (lhs).tv64 + (rhs).tv64 }; })
      90                 :            : 
      91                 :            : /*
      92                 :            :  * Add a ktime_t variable and a scalar nanosecond value.
      93                 :            :  * res = kt + nsval:
      94                 :            :  */
      95                 :            : #define ktime_add_ns(kt, nsval) \
      96                 :            :                 ({ (ktime_t){ .tv64 = (kt).tv64 + (nsval) }; })
      97                 :            : 
      98                 :            : /*
      99                 :            :  * Subtract a scalar nanosecod from a ktime_t variable
     100                 :            :  * res = kt - nsval:
     101                 :            :  */
     102                 :            : #define ktime_sub_ns(kt, nsval) \
     103                 :            :                 ({ (ktime_t){ .tv64 = (kt).tv64 - (nsval) }; })
     104                 :            : 
     105                 :            : /* convert a timespec to ktime_t format: */
     106                 :            : static inline ktime_t timespec_to_ktime(struct timespec ts)
     107                 :            : {
     108                 :    1047381 :         return ktime_set(ts.tv_sec, ts.tv_nsec);
     109                 :            : }
     110                 :            : 
     111                 :            : /* convert a timeval to ktime_t format: */
     112                 :            : static inline ktime_t timeval_to_ktime(struct timeval tv)
     113                 :            : {
     114                 :       7174 :         return ktime_set(tv.tv_sec, tv.tv_usec * NSEC_PER_USEC);
     115                 :            : }
     116                 :            : 
     117                 :            : /* Map the ktime_t to timespec conversion to ns_to_timespec function */
     118                 :            : #define ktime_to_timespec(kt)           ns_to_timespec((kt).tv64)
     119                 :            : 
     120                 :            : /* Map the ktime_t to timeval conversion to ns_to_timeval function */
     121                 :            : #define ktime_to_timeval(kt)            ns_to_timeval((kt).tv64)
     122                 :            : 
     123                 :            : /* Convert ktime_t to nanoseconds - NOP in the scalar storage format: */
     124                 :            : #define ktime_to_ns(kt)                 ((kt).tv64)
     125                 :            : 
     126                 :            : #else   /* !((BITS_PER_LONG == 64) || defined(CONFIG_KTIME_SCALAR)) */
     127                 :            : 
     128                 :            : /*
     129                 :            :  * Helper macros/inlines to get the ktime_t math right in the timespec
     130                 :            :  * representation. The macros are sometimes ugly - their actual use is
     131                 :            :  * pretty okay-ish, given the circumstances. We do all this for
     132                 :            :  * performance reasons. The pure scalar nsec_t based code was nice and
     133                 :            :  * simple, but created too many 64-bit / 32-bit conversions and divisions.
     134                 :            :  *
     135                 :            :  * Be especially aware that negative values are represented in a way
     136                 :            :  * that the tv.sec field is negative and the tv.nsec field is greater
     137                 :            :  * or equal to zero but less than nanoseconds per second. This is the
     138                 :            :  * same representation which is used by timespecs.
     139                 :            :  *
     140                 :            :  *   tv.sec < 0 and 0 >= tv.nsec < NSEC_PER_SEC
     141                 :            :  */
     142                 :            : 
     143                 :            : /* Set a ktime_t variable to a value in sec/nsec representation: */
     144                 :            : static inline ktime_t ktime_set(const long secs, const unsigned long nsecs)
     145                 :            : {
     146                 :            :         return (ktime_t) { .tv = { .sec = secs, .nsec = nsecs } };
     147                 :            : }
     148                 :            : 
     149                 :            : /**
     150                 :            :  * ktime_sub - subtract two ktime_t variables
     151                 :            :  * @lhs:        minuend
     152                 :            :  * @rhs:        subtrahend
     153                 :            :  *
     154                 :            :  * Return: The remainder of the subtraction.
     155                 :            :  */
     156                 :            : static inline ktime_t ktime_sub(const ktime_t lhs, const ktime_t rhs)
     157                 :            : {
     158                 :            :         ktime_t res;
     159                 :            : 
     160                 :            :         res.tv64 = lhs.tv64 - rhs.tv64;
     161                 :            :         if (res.tv.nsec < 0)
     162                 :            :                 res.tv.nsec += NSEC_PER_SEC;
     163                 :            : 
     164                 :            :         return res;
     165                 :            : }
     166                 :            : 
     167                 :            : /**
     168                 :            :  * ktime_add - add two ktime_t variables
     169                 :            :  * @add1:       addend1
     170                 :            :  * @add2:       addend2
     171                 :            :  *
     172                 :            :  * Return: The sum of @add1 and @add2.
     173                 :            :  */
     174                 :            : static inline ktime_t ktime_add(const ktime_t add1, const ktime_t add2)
     175                 :            : {
     176                 :            :         ktime_t res;
     177                 :            : 
     178                 :            :         res.tv64 = add1.tv64 + add2.tv64;
     179                 :            :         /*
     180                 :            :          * performance trick: the (u32) -NSEC gives 0x00000000Fxxxxxxx
     181                 :            :          * so we subtract NSEC_PER_SEC and add 1 to the upper 32 bit.
     182                 :            :          *
     183                 :            :          * it's equivalent to:
     184                 :            :          *   tv.nsec -= NSEC_PER_SEC
     185                 :            :          *   tv.sec ++;
     186                 :            :          */
     187                 :            :         if (res.tv.nsec >= NSEC_PER_SEC)
     188                 :            :                 res.tv64 += (u32)-NSEC_PER_SEC;
     189                 :            : 
     190                 :            :         return res;
     191                 :            : }
     192                 :            : 
     193                 :            : /**
     194                 :            :  * ktime_add_ns - Add a scalar nanoseconds value to a ktime_t variable
     195                 :            :  * @kt:         addend
     196                 :            :  * @nsec:       the scalar nsec value to add
     197                 :            :  *
     198                 :            :  * Return: The sum of @kt and @nsec in ktime_t format.
     199                 :            :  */
     200                 :            : extern ktime_t ktime_add_ns(const ktime_t kt, u64 nsec);
     201                 :            : 
     202                 :            : /**
     203                 :            :  * ktime_sub_ns - Subtract a scalar nanoseconds value from a ktime_t variable
     204                 :            :  * @kt:         minuend
     205                 :            :  * @nsec:       the scalar nsec value to subtract
     206                 :            :  *
     207                 :            :  * Return: The subtraction of @nsec from @kt in ktime_t format.
     208                 :            :  */
     209                 :            : extern ktime_t ktime_sub_ns(const ktime_t kt, u64 nsec);
     210                 :            : 
     211                 :            : /**
     212                 :            :  * timespec_to_ktime - convert a timespec to ktime_t format
     213                 :            :  * @ts:         the timespec variable to convert
     214                 :            :  *
     215                 :            :  * Return: A ktime_t variable with the converted timespec value.
     216                 :            :  */
     217                 :            : static inline ktime_t timespec_to_ktime(const struct timespec ts)
     218                 :            : {
     219                 :            :         return (ktime_t) { .tv = { .sec = (s32)ts.tv_sec,
     220                 :            :                                    .nsec = (s32)ts.tv_nsec } };
     221                 :            : }
     222                 :            : 
     223                 :            : /**
     224                 :            :  * timeval_to_ktime - convert a timeval to ktime_t format
     225                 :            :  * @tv:         the timeval variable to convert
     226                 :            :  *
     227                 :            :  * Return: A ktime_t variable with the converted timeval value.
     228                 :            :  */
     229                 :            : static inline ktime_t timeval_to_ktime(const struct timeval tv)
     230                 :            : {
     231                 :            :         return (ktime_t) { .tv = { .sec = (s32)tv.tv_sec,
     232                 :            :                                    .nsec = (s32)(tv.tv_usec *
     233                 :            :                                                  NSEC_PER_USEC) } };
     234                 :            : }
     235                 :            : 
     236                 :            : /**
     237                 :            :  * ktime_to_timespec - convert a ktime_t variable to timespec format
     238                 :            :  * @kt:         the ktime_t variable to convert
     239                 :            :  *
     240                 :            :  * Return: The timespec representation of the ktime value.
     241                 :            :  */
     242                 :            : static inline struct timespec ktime_to_timespec(const ktime_t kt)
     243                 :            : {
     244                 :            :         return (struct timespec) { .tv_sec = (time_t) kt.tv.sec,
     245                 :            :                                    .tv_nsec = (long) kt.tv.nsec };
     246                 :            : }
     247                 :            : 
     248                 :            : /**
     249                 :            :  * ktime_to_timeval - convert a ktime_t variable to timeval format
     250                 :            :  * @kt:         the ktime_t variable to convert
     251                 :            :  *
     252                 :            :  * Return: The timeval representation of the ktime value.
     253                 :            :  */
     254                 :            : static inline struct timeval ktime_to_timeval(const ktime_t kt)
     255                 :            : {
     256                 :            :         return (struct timeval) {
     257                 :            :                 .tv_sec = (time_t) kt.tv.sec,
     258                 :            :                 .tv_usec = (suseconds_t) (kt.tv.nsec / NSEC_PER_USEC) };
     259                 :            : }
     260                 :            : 
     261                 :            : /**
     262                 :            :  * ktime_to_ns - convert a ktime_t variable to scalar nanoseconds
     263                 :            :  * @kt:         the ktime_t variable to convert
     264                 :            :  *
     265                 :            :  * Return: The scalar nanoseconds representation of @kt.
     266                 :            :  */
     267                 :            : static inline s64 ktime_to_ns(const ktime_t kt)
     268                 :            : {
     269                 :            :         return (s64) kt.tv.sec * NSEC_PER_SEC + kt.tv.nsec;
     270                 :            : }
     271                 :            : 
     272                 :            : #endif  /* !((BITS_PER_LONG == 64) || defined(CONFIG_KTIME_SCALAR)) */
     273                 :            : 
     274                 :            : /**
     275                 :            :  * ktime_equal - Compares two ktime_t variables to see if they are equal
     276                 :            :  * @cmp1:       comparable1
     277                 :            :  * @cmp2:       comparable2
     278                 :            :  *
     279                 :            :  * Compare two ktime_t variables.
     280                 :            :  *
     281                 :            :  * Return: 1 if equal.
     282                 :            :  */
     283                 :            : static inline int ktime_equal(const ktime_t cmp1, const ktime_t cmp2)
     284                 :            : {
     285                 :            :         return cmp1.tv64 == cmp2.tv64;
     286                 :            : }
     287                 :            : 
     288                 :            : /**
     289                 :            :  * ktime_compare - Compares two ktime_t variables for less, greater or equal
     290                 :            :  * @cmp1:       comparable1
     291                 :            :  * @cmp2:       comparable2
     292                 :            :  *
     293                 :            :  * Return: ...
     294                 :            :  *   cmp1  < cmp2: return <0
     295                 :            :  *   cmp1 == cmp2: return 0
     296                 :            :  *   cmp1  > cmp2: return >0
     297                 :            :  */
     298                 :            : static inline int ktime_compare(const ktime_t cmp1, const ktime_t cmp2)
     299                 :            : {
     300                 :            :         if (cmp1.tv64 < cmp2.tv64)
     301                 :            :                 return -1;
     302                 :            :         if (cmp1.tv64 > cmp2.tv64)
     303                 :            :                 return 1;
     304                 :            :         return 0;
     305                 :            : }
     306                 :            : 
     307                 :            : static inline s64 ktime_to_us(const ktime_t kt)
     308                 :            : {
     309                 :    6075107 :         struct timeval tv = ktime_to_timeval(kt);
     310                 :   11668297 :         return (s64) tv.tv_sec * USEC_PER_SEC + tv.tv_usec;
     311                 :            : }
     312                 :            : 
     313                 :            : static inline s64 ktime_to_ms(const ktime_t kt)
     314                 :            : {
     315                 :          0 :         struct timeval tv = ktime_to_timeval(kt);
     316                 :          0 :         return (s64) tv.tv_sec * MSEC_PER_SEC + tv.tv_usec / USEC_PER_MSEC;
     317                 :            : }
     318                 :            : 
     319                 :            : static inline s64 ktime_us_delta(const ktime_t later, const ktime_t earlier)
     320                 :            : {
     321                 :          0 :        return ktime_to_us(ktime_sub(later, earlier));
     322                 :            : }
     323                 :            : 
     324                 :            : static inline ktime_t ktime_add_us(const ktime_t kt, const u64 usec)
     325                 :            : {
     326                 :            :         return ktime_add_ns(kt, usec * NSEC_PER_USEC);
     327                 :            : }
     328                 :            : 
     329                 :            : static inline ktime_t ktime_add_ms(const ktime_t kt, const u64 msec)
     330                 :            : {
     331                 :            :         return ktime_add_ns(kt, msec * NSEC_PER_MSEC);
     332                 :            : }
     333                 :            : 
     334                 :            : static inline ktime_t ktime_sub_us(const ktime_t kt, const u64 usec)
     335                 :            : {
     336                 :            :         return ktime_sub_ns(kt, usec * NSEC_PER_USEC);
     337                 :            : }
     338                 :            : 
     339                 :            : extern ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs);
     340                 :            : 
     341                 :            : /**
     342                 :            :  * ktime_to_timespec_cond - convert a ktime_t variable to timespec
     343                 :            :  *                          format only if the variable contains data
     344                 :            :  * @kt:         the ktime_t variable to convert
     345                 :            :  * @ts:         the timespec variable to store the result in
     346                 :            :  *
     347                 :            :  * Return: %true if there was a successful conversion, %false if kt was 0.
     348                 :            :  */
     349                 :            : static inline __must_check bool ktime_to_timespec_cond(const ktime_t kt,
     350                 :            :                                                        struct timespec *ts)
     351                 :            : {
     352                 :            :         if (kt.tv64) {
     353                 :            :                 *ts = ktime_to_timespec(kt);
     354                 :            :                 return true;
     355                 :            :         } else {
     356                 :            :                 return false;
     357                 :            :         }
     358                 :            : }
     359                 :            : 
     360                 :            : /*
     361                 :            :  * The resolution of the clocks. The resolution value is returned in
     362                 :            :  * the clock_getres() system call to give application programmers an
     363                 :            :  * idea of the (in)accuracy of timers. Timer values are rounded up to
     364                 :            :  * this resolution values.
     365                 :            :  */
     366                 :            : #define LOW_RES_NSEC            TICK_NSEC
     367                 :            : #define KTIME_LOW_RES           (ktime_t){ .tv64 = LOW_RES_NSEC }
     368                 :            : 
     369                 :            : /* Get the monotonic time in timespec format: */
     370                 :            : extern void ktime_get_ts(struct timespec *ts);
     371                 :            : 
     372                 :            : /* Get the real (wall-) time in timespec format: */
     373                 :            : #define ktime_get_real_ts(ts)   getnstimeofday(ts)
     374                 :            : 
     375                 :            : static inline ktime_t ns_to_ktime(u64 ns)
     376                 :            : {
     377                 :            :         static const ktime_t ktime_zero = { .tv64 = 0 };
     378                 :            : 
     379                 :    5500906 :         return ktime_add_ns(ktime_zero, ns);
     380                 :            : }
     381                 :            : 
     382                 :            : static inline ktime_t ms_to_ktime(u64 ms)
     383                 :            : {
     384                 :            :         static const ktime_t ktime_zero = { .tv64 = 0 };
     385                 :            : 
     386                 :            :         return ktime_add_ms(ktime_zero, ms);
     387                 :            : }
     388                 :            : 
     389                 :            : #endif

Generated by: LCOV version 1.9