LCOV - code coverage report
Current view: top level - core/support - time.c (source / functions) Hit Total Coverage
Test: tmp.CaZ6RjdVn2 Lines: 144 165 87.3 %
Date: 2015-12-10 22:15:08 Functions: 17 18 94.4 %

          Line data    Source code
       1             : /*
       2             :  *
       3             :  * Copyright 2015, Google Inc.
       4             :  * All rights reserved.
       5             :  *
       6             :  * Redistribution and use in source and binary forms, with or without
       7             :  * modification, are permitted provided that the following conditions are
       8             :  * met:
       9             :  *
      10             :  *     * Redistributions of source code must retain the above copyright
      11             :  * notice, this list of conditions and the following disclaimer.
      12             :  *     * Redistributions in binary form must reproduce the above
      13             :  * copyright notice, this list of conditions and the following disclaimer
      14             :  * in the documentation and/or other materials provided with the
      15             :  * distribution.
      16             :  *     * Neither the name of Google Inc. nor the names of its
      17             :  * contributors may be used to endorse or promote products derived from
      18             :  * this software without specific prior written permission.
      19             :  *
      20             :  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      21             :  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      22             :  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      23             :  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      24             :  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      25             :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      26             :  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      27             :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      28             :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      29             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      30             :  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      31             :  *
      32             :  */
      33             : 
      34             : /* Generic implementation of time calls. */
      35             : 
      36             : #include <grpc/support/time.h>
      37             : #include <limits.h>
      38             : #include <stdio.h>
      39             : #include <string.h>
      40             : #include <grpc/support/log.h>
      41             : 
      42    72060920 : int gpr_time_cmp(gpr_timespec a, gpr_timespec b) {
      43    72060920 :   int cmp = (a.tv_sec > b.tv_sec) - (a.tv_sec < b.tv_sec);
      44    72060920 :   GPR_ASSERT(a.clock_type == b.clock_type);
      45    72060920 :   if (cmp == 0) {
      46    24255484 :     cmp = (a.tv_nsec > b.tv_nsec) - (a.tv_nsec < b.tv_nsec);
      47             :   }
      48    72060920 :   return cmp;
      49             : }
      50             : 
      51     6929962 : gpr_timespec gpr_time_min(gpr_timespec a, gpr_timespec b) {
      52     6929962 :   return gpr_time_cmp(a, b) < 0 ? a : b;
      53             : }
      54             : 
      55      264050 : gpr_timespec gpr_time_max(gpr_timespec a, gpr_timespec b) {
      56      264050 :   return gpr_time_cmp(a, b) > 0 ? a : b;
      57             : }
      58             : 
      59             : /* There's no standard TIME_T_MIN and TIME_T_MAX, so we construct them.  The
      60             :    following assumes that signed types are two's-complement and that bytes are
      61             :    8 bits.  */
      62             : 
      63             : /* The top bit of integral type t. */
      64             : #define TOP_BIT_OF_TYPE(t) (((gpr_uintmax)1) << ((8 * sizeof(t)) - 1))
      65             : 
      66             : /* Return whether integral type t is signed. */
      67             : #define TYPE_IS_SIGNED(t) (((t)1) > (t) ~(t)0)
      68             : 
      69             : /* The minimum and maximum value of integral type t. */
      70             : #define TYPE_MIN(t) ((t)(TYPE_IS_SIGNED(t) ? TOP_BIT_OF_TYPE(t) : 0))
      71             : #define TYPE_MAX(t)                                 \
      72             :   ((t)(TYPE_IS_SIGNED(t) ? (TOP_BIT_OF_TYPE(t) - 1) \
      73             :                          : ((TOP_BIT_OF_TYPE(t) - 1) << 1) + 1))
      74             : 
      75      201226 : gpr_timespec gpr_time_0(gpr_clock_type type) {
      76             :   gpr_timespec out;
      77      201226 :   out.tv_sec = 0;
      78      201226 :   out.tv_nsec = 0;
      79      201226 :   out.clock_type = type;
      80      201226 :   return out;
      81             : }
      82             : 
      83    81972470 : gpr_timespec gpr_inf_future(gpr_clock_type type) {
      84             :   gpr_timespec out;
      85    81937874 :   out.tv_sec = TYPE_MAX(time_t);
      86    81937874 :   out.tv_nsec = 0;
      87    81937874 :   out.clock_type = type;
      88    81972470 :   return out;
      89             : }
      90             : 
      91      128017 : gpr_timespec gpr_inf_past(gpr_clock_type type) {
      92             :   gpr_timespec out;
      93      128011 :   out.tv_sec = TYPE_MIN(time_t);
      94      128011 :   out.tv_nsec = 0;
      95      128011 :   out.clock_type = type;
      96      128017 :   return out;
      97             : }
      98             : 
      99             : /* TODO(ctiller): consider merging _nanos, _micros, _millis into a single
     100             :    function for maintainability. Similarly for _seconds, _minutes, and _hours */
     101             : 
     102     3229243 : gpr_timespec gpr_time_from_nanos(long ns, gpr_clock_type type) {
     103             :   gpr_timespec result;
     104     3228076 :   result.clock_type = type;
     105     3229243 :   if (ns == LONG_MAX) {
     106           0 :     result = gpr_inf_future(type);
     107     3229243 :   } else if (ns == LONG_MIN) {
     108           0 :     result = gpr_inf_past(type);
     109     3229243 :   } else if (ns >= 0) {
     110     3229231 :     result.tv_sec = ns / GPR_NS_PER_SEC;
     111     3229231 :     result.tv_nsec = (int)(ns - result.tv_sec * GPR_NS_PER_SEC);
     112             :   } else {
     113             :     /* Calculation carefully formulated to avoid any possible under/overflow. */
     114          12 :     result.tv_sec = (-(999999999 - (ns + GPR_NS_PER_SEC)) / GPR_NS_PER_SEC) - 1;
     115          12 :     result.tv_nsec = (int)(ns - result.tv_sec * GPR_NS_PER_SEC);
     116             :   }
     117     3229247 :   return result;
     118             : }
     119             : 
     120     4842613 : gpr_timespec gpr_time_from_micros(long us, gpr_clock_type type) {
     121             :   gpr_timespec result;
     122     4841401 :   result.clock_type = type;
     123     4842613 :   if (us == LONG_MAX) {
     124           0 :     result = gpr_inf_future(type);
     125     4842613 :   } else if (us == LONG_MIN) {
     126           0 :     result = gpr_inf_past(type);
     127     4842613 :   } else if (us >= 0) {
     128     4198999 :     result.tv_sec = us / 1000000;
     129     4198999 :     result.tv_nsec = (int)((us - result.tv_sec * 1000000) * 1000);
     130             :   } else {
     131             :     /* Calculation carefully formulated to avoid any possible under/overflow. */
     132      643614 :     result.tv_sec = (-(999999 - (us + 1000000)) / 1000000) - 1;
     133      643614 :     result.tv_nsec = (int)((us - result.tv_sec * 1000000) * 1000);
     134             :   }
     135     4842759 :   return result;
     136             : }
     137             : 
     138     2394715 : gpr_timespec gpr_time_from_millis(long ms, gpr_clock_type type) {
     139             :   gpr_timespec result;
     140     2394714 :   result.clock_type = type;
     141     2394715 :   if (ms == LONG_MAX) {
     142           0 :     result = gpr_inf_future(type);
     143     2394715 :   } else if (ms == LONG_MIN) {
     144           0 :     result = gpr_inf_past(type);
     145     2394715 :   } else if (ms >= 0) {
     146     2394439 :     result.tv_sec = ms / 1000;
     147     2394439 :     result.tv_nsec = (int)((ms - result.tv_sec * 1000) * 1000000);
     148             :   } else {
     149             :     /* Calculation carefully formulated to avoid any possible under/overflow. */
     150         276 :     result.tv_sec = (-(999 - (ms + 1000)) / 1000) - 1;
     151         276 :     result.tv_nsec = (int)((ms - result.tv_sec * 1000) * 1000000);
     152             :   }
     153     2394715 :   return result;
     154             : }
     155             : 
     156       18996 : gpr_timespec gpr_time_from_seconds(long s, gpr_clock_type type) {
     157             :   gpr_timespec result;
     158       18750 :   result.clock_type = type;
     159       18996 :   if (s == LONG_MAX) {
     160           0 :     result = gpr_inf_future(type);
     161       18996 :   } else if (s == LONG_MIN) {
     162           0 :     result = gpr_inf_past(type);
     163             :   } else {
     164       18750 :     result.tv_sec = s;
     165       18750 :     result.tv_nsec = 0;
     166             :   }
     167       18996 :   return result;
     168             : }
     169             : 
     170         138 : gpr_timespec gpr_time_from_minutes(long m, gpr_clock_type type) {
     171             :   gpr_timespec result;
     172         138 :   result.clock_type = type;
     173         138 :   if (m >= LONG_MAX / 60) {
     174           0 :     result = gpr_inf_future(type);
     175         138 :   } else if (m <= LONG_MIN / 60) {
     176           0 :     result = gpr_inf_past(type);
     177             :   } else {
     178         138 :     result.tv_sec = m * 60;
     179         138 :     result.tv_nsec = 0;
     180             :   }
     181         138 :   return result;
     182             : }
     183             : 
     184         143 : gpr_timespec gpr_time_from_hours(long h, gpr_clock_type type) {
     185             :   gpr_timespec result;
     186         143 :   result.clock_type = type;
     187         143 :   if (h >= LONG_MAX / 3600) {
     188           0 :     result = gpr_inf_future(type);
     189         143 :   } else if (h <= LONG_MIN / 3600) {
     190           0 :     result = gpr_inf_past(type);
     191             :   } else {
     192         143 :     result.tv_sec = h * 3600;
     193         143 :     result.tv_nsec = 0;
     194             :   }
     195         143 :   return result;
     196             : }
     197             : 
     198    14137105 : gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b) {
     199             :   gpr_timespec sum;
     200    14134196 :   int inc = 0;
     201    14137105 :   GPR_ASSERT(b.clock_type == GPR_TIMESPAN);
     202    14134196 :   sum.clock_type = a.clock_type;
     203    14137105 :   sum.tv_nsec = a.tv_nsec + b.tv_nsec;
     204    14137105 :   if (sum.tv_nsec >= GPR_NS_PER_SEC) {
     205     3443429 :     sum.tv_nsec -= GPR_NS_PER_SEC;
     206     3443383 :     inc++;
     207             :   }
     208    14137105 :   if (a.tv_sec == TYPE_MAX(time_t) || a.tv_sec == TYPE_MIN(time_t)) {
     209      111959 :     sum = a;
     210    28047882 :   } else if (b.tv_sec == TYPE_MAX(time_t) ||
     211    27686172 :              (b.tv_sec >= 0 && a.tv_sec >= TYPE_MAX(time_t) - b.tv_sec)) {
     212        1652 :     sum = gpr_inf_future(sum.clock_type);
     213    28044079 :   } else if (b.tv_sec == TYPE_MIN(time_t) ||
     214    24390415 :              (b.tv_sec <= 0 && a.tv_sec <= TYPE_MIN(time_t) - b.tv_sec)) {
     215           0 :     sum = gpr_inf_past(sum.clock_type);
     216             :   } else {
     217    14024245 :     sum.tv_sec = a.tv_sec + b.tv_sec;
     218    14024245 :     if (inc != 0 && sum.tv_sec == TYPE_MAX(time_t) - 1) {
     219           0 :       sum = gpr_inf_future(sum.clock_type);
     220             :     } else {
     221    14024245 :       sum.tv_sec += inc;
     222             :     }
     223             :   }
     224    14135529 :   return sum;
     225             : }
     226             : 
     227     8985944 : gpr_timespec gpr_time_sub(gpr_timespec a, gpr_timespec b) {
     228             :   gpr_timespec diff;
     229     8984538 :   int dec = 0;
     230     8985944 :   if (b.clock_type == GPR_TIMESPAN) {
     231      325663 :     diff.clock_type = a.clock_type;
     232             :   } else {
     233     8660281 :     GPR_ASSERT(a.clock_type == b.clock_type);
     234     8658875 :     diff.clock_type = GPR_TIMESPAN;
     235             :   }
     236     8985944 :   diff.tv_nsec = a.tv_nsec - b.tv_nsec;
     237     8985944 :   if (diff.tv_nsec < 0) {
     238     7149568 :     diff.tv_nsec += GPR_NS_PER_SEC;
     239     7149338 :     dec++;
     240             :   }
     241     8985944 :   if (a.tv_sec == TYPE_MAX(time_t) || a.tv_sec == TYPE_MIN(time_t)) {
     242         937 :     diff = a;
     243    17968613 :   } else if (b.tv_sec == TYPE_MIN(time_t) ||
     244     9248140 :              (b.tv_sec <= 0 && a.tv_sec >= TYPE_MAX(time_t) + b.tv_sec)) {
     245         209 :     diff = gpr_inf_future(GPR_CLOCK_REALTIME);
     246    17968183 :   } else if (b.tv_sec == TYPE_MAX(time_t) ||
     247    17807717 :              (b.tv_sec >= 0 && a.tv_sec <= TYPE_MIN(time_t) + b.tv_sec)) {
     248        2888 :     diff = gpr_inf_past(GPR_CLOCK_REALTIME);
     249             :   } else {
     250     8981903 :     diff.tv_sec = a.tv_sec - b.tv_sec;
     251     8981903 :     if (dec != 0 && diff.tv_sec == TYPE_MIN(time_t) + 1) {
     252           0 :       diff = gpr_inf_past(GPR_CLOCK_REALTIME);
     253             :     } else {
     254     8981903 :       diff.tv_sec -= dec;
     255             :     }
     256             :   }
     257     8986891 :   return diff;
     258             : }
     259             : 
     260           9 : int gpr_time_similar(gpr_timespec a, gpr_timespec b, gpr_timespec threshold) {
     261             :   int cmp_ab;
     262             : 
     263           9 :   GPR_ASSERT(a.clock_type == b.clock_type);
     264           9 :   GPR_ASSERT(threshold.clock_type == GPR_TIMESPAN);
     265             : 
     266           9 :   cmp_ab = gpr_time_cmp(a, b);
     267           9 :   if (cmp_ab == 0) return 1;
     268           6 :   if (cmp_ab < 0) {
     269           3 :     return gpr_time_cmp(gpr_time_sub(b, a), threshold) <= 0;
     270             :   } else {
     271           3 :     return gpr_time_cmp(gpr_time_sub(a, b), threshold) <= 0;
     272             :   }
     273             : }
     274             : 
     275     3233226 : gpr_int32 gpr_time_to_millis(gpr_timespec t) {
     276     3233226 :   if (t.tv_sec >= 2147483) {
     277        3889 :     if (t.tv_sec == 2147483 && t.tv_nsec < 648 * GPR_NS_PER_MS) {
     278           0 :       return 2147483 * GPR_MS_PER_SEC + t.tv_nsec / GPR_NS_PER_MS;
     279             :     }
     280        3801 :     return 2147483647;
     281     3229337 :   } else if (t.tv_sec <= -2147483) {
     282             :     /* TODO(ctiller): correct handling here (it's so far in the past do we
     283             :        care?) */
     284           0 :     return -2147483647;
     285             :   } else {
     286     3229337 :     return (gpr_int32)(t.tv_sec * GPR_MS_PER_SEC + t.tv_nsec / GPR_NS_PER_MS);
     287             :   }
     288             : }
     289             : 
     290           0 : double gpr_timespec_to_micros(gpr_timespec t) {
     291           0 :   return (double)t.tv_sec * GPR_US_PER_SEC + t.tv_nsec * 1e-3;
     292             : }
     293             : 
     294    12547803 : gpr_timespec gpr_convert_clock_type(gpr_timespec t, gpr_clock_type clock_type) {
     295    12547803 :   if (t.clock_type == clock_type) {
     296     2909695 :     return t;
     297             :   }
     298             : 
     299     9638108 :   if (t.tv_nsec == 0) {
     300     6523787 :     if (t.tv_sec == TYPE_MAX(time_t)) {
     301     6321357 :       t.clock_type = clock_type;
     302     6322204 :       return t;
     303             :     }
     304      201583 :     if (t.tv_sec == TYPE_MIN(time_t)) {
     305         364 :       t.clock_type = clock_type;
     306         365 :       return t;
     307             :     }
     308             :   }
     309             : 
     310     3315539 :   if (clock_type == GPR_TIMESPAN) {
     311           0 :     return gpr_time_sub(t, gpr_now(t.clock_type));
     312             :   }
     313             : 
     314     3315539 :   if (t.clock_type == GPR_TIMESPAN) {
     315           0 :     return gpr_time_add(gpr_now(clock_type), t);
     316             :   }
     317             : 
     318     3315539 :   return gpr_time_add(gpr_now(clock_type),
     319             :                       gpr_time_sub(t, gpr_now(t.clock_type)));
     320             : }

Generated by: LCOV version 1.11