LCOV - code coverage report
Current view: top level - src/core/support - time.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 143 165 86.7 %
Date: 2015-10-10 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    63432453 : int gpr_time_cmp(gpr_timespec a, gpr_timespec b) {
      43    63432453 :   int cmp = (a.tv_sec > b.tv_sec) - (a.tv_sec < b.tv_sec);
      44    63432453 :   GPR_ASSERT(a.clock_type == b.clock_type);
      45    63432453 :   if (cmp == 0) {
      46    23314376 :     cmp = (a.tv_nsec > b.tv_nsec) - (a.tv_nsec < b.tv_nsec);
      47             :   }
      48    63432453 :   return cmp;
      49             : }
      50             : 
      51     9057296 : gpr_timespec gpr_time_min(gpr_timespec a, gpr_timespec b) {
      52     9057296 :   return gpr_time_cmp(a, b) < 0 ? a : b;
      53             : }
      54             : 
      55      190963 : gpr_timespec gpr_time_max(gpr_timespec a, gpr_timespec b) {
      56      190963 :   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      101861 : gpr_timespec gpr_time_0(gpr_clock_type type) {
      76             :   gpr_timespec out;
      77      101861 :   out.tv_sec = 0;
      78      101861 :   out.tv_nsec = 0;
      79      101861 :   out.clock_type = type;
      80      101861 :   return out;
      81             : }
      82             : 
      83    51780478 : gpr_timespec gpr_inf_future(gpr_clock_type type) {
      84             :   gpr_timespec out;
      85    51780478 :   out.tv_sec = TYPE_MAX(time_t);
      86    51780478 :   out.tv_nsec = 0;
      87    51780478 :   out.clock_type = type;
      88    51780478 :   return out;
      89             : }
      90             : 
      91       51438 : gpr_timespec gpr_inf_past(gpr_clock_type type) {
      92             :   gpr_timespec out;
      93       51438 :   out.tv_sec = TYPE_MIN(time_t);
      94       51438 :   out.tv_nsec = 0;
      95       51438 :   out.clock_type = type;
      96       51438 :   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     2629632 : gpr_timespec gpr_time_from_nanos(long ns, gpr_clock_type type) {
     103             :   gpr_timespec result;
     104     2629632 :   result.clock_type = type;
     105     2629632 :   if (ns == LONG_MAX) {
     106           0 :     result = gpr_inf_future(type);
     107     2629632 :   } else if (ns == LONG_MIN) {
     108           0 :     result = gpr_inf_past(type);
     109     2629632 :   } else if (ns >= 0) {
     110     2629620 :     result.tv_sec = ns / GPR_NS_PER_SEC;
     111     2629620 :     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     2629645 :   return result;
     118             : }
     119             : 
     120     6322200 : gpr_timespec gpr_time_from_micros(long us, gpr_clock_type type) {
     121             :   gpr_timespec result;
     122     6322200 :   result.clock_type = type;
     123     6322200 :   if (us == LONG_MAX) {
     124           0 :     result = gpr_inf_future(type);
     125     6322200 :   } else if (us == LONG_MIN) {
     126           0 :     result = gpr_inf_past(type);
     127     6322200 :   } else if (us >= 0) {
     128     5678586 :     result.tv_sec = us / 1000000;
     129     5678586 :     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     6324683 :   return result;
     136             : }
     137             : 
     138      273233 : gpr_timespec gpr_time_from_millis(long ms, gpr_clock_type type) {
     139             :   gpr_timespec result;
     140      273233 :   result.clock_type = type;
     141      273233 :   if (ms == LONG_MAX) {
     142           0 :     result = gpr_inf_future(type);
     143      273233 :   } else if (ms == LONG_MIN) {
     144           0 :     result = gpr_inf_past(type);
     145      273233 :   } else if (ms >= 0) {
     146      273106 :     result.tv_sec = ms / 1000;
     147      273106 :     result.tv_nsec = (int)((ms - result.tv_sec * 1000) * 1000000);
     148             :   } else {
     149             :     /* Calculation carefully formulated to avoid any possible under/overflow. */
     150         127 :     result.tv_sec = (-(999 - (ms + 1000)) / 1000) - 1;
     151         127 :     result.tv_nsec = (int)((ms - result.tv_sec * 1000) * 1000000);
     152             :   }
     153      273233 :   return result;
     154             : }
     155             : 
     156       15425 : gpr_timespec gpr_time_from_seconds(long s, gpr_clock_type type) {
     157             :   gpr_timespec result;
     158       15425 :   result.clock_type = type;
     159       15425 :   if (s == LONG_MAX) {
     160           0 :     result = gpr_inf_future(type);
     161       15425 :   } else if (s == LONG_MIN) {
     162           0 :     result = gpr_inf_past(type);
     163             :   } else {
     164       15425 :     result.tv_sec = s;
     165       15425 :     result.tv_nsec = 0;
     166             :   }
     167       15425 :   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         150 : gpr_timespec gpr_time_from_hours(long h, gpr_clock_type type) {
     185             :   gpr_timespec result;
     186         150 :   result.clock_type = type;
     187         150 :   if (h >= LONG_MAX / 3600) {
     188           0 :     result = gpr_inf_future(type);
     189         150 :   } else if (h <= LONG_MIN / 3600) {
     190           0 :     result = gpr_inf_past(type);
     191             :   } else {
     192         150 :     result.tv_sec = h * 3600;
     193         150 :     result.tv_nsec = 0;
     194             :   }
     195         150 :   return result;
     196             : }
     197             : 
     198    13119724 : gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b) {
     199             :   gpr_timespec sum;
     200    13119724 :   int inc = 0;
     201    13119724 :   GPR_ASSERT(b.clock_type == GPR_TIMESPAN);
     202    13119724 :   sum.clock_type = a.clock_type;
     203    13119724 :   sum.tv_nsec = a.tv_nsec + b.tv_nsec;
     204    13119724 :   if (sum.tv_nsec >= GPR_NS_PER_SEC) {
     205     4591381 :     sum.tv_nsec -= GPR_NS_PER_SEC;
     206     4591381 :     inc++;
     207             :   }
     208    13119724 :   if (a.tv_sec == TYPE_MAX(time_t) || a.tv_sec == TYPE_MIN(time_t)) {
     209       81462 :     sum = a;
     210    26074174 :   } else if (b.tv_sec == TYPE_MAX(time_t) ||
     211    23072444 :              (b.tv_sec >= 0 && a.tv_sec >= TYPE_MAX(time_t) - b.tv_sec)) {
     212       18036 :     sum = gpr_inf_future(sum.clock_type);
     213    26040452 :   } else if (b.tv_sec == TYPE_MIN(time_t) ||
     214    25611306 :              (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    13041732 :     sum.tv_sec = a.tv_sec + b.tv_sec;
     218    13041732 :     if (inc != 0 && sum.tv_sec == TYPE_MAX(time_t) - 1) {
     219           0 :       sum = gpr_inf_future(sum.clock_type);
     220             :     } else {
     221    13041732 :       sum.tv_sec += inc;
     222             :     }
     223             :   }
     224    13122392 :   return sum;
     225             : }
     226             : 
     227     7648442 : gpr_timespec gpr_time_sub(gpr_timespec a, gpr_timespec b) {
     228             :   gpr_timespec diff;
     229     7648442 :   int dec = 0;
     230     7648442 :   if (b.clock_type == GPR_TIMESPAN) {
     231      331054 :     diff.clock_type = a.clock_type;
     232             :   } else {
     233     7317388 :     GPR_ASSERT(a.clock_type == b.clock_type);
     234     7317388 :     diff.clock_type = GPR_TIMESPAN;
     235             :   }
     236     7648442 :   diff.tv_nsec = a.tv_nsec - b.tv_nsec;
     237     7648442 :   if (diff.tv_nsec < 0) {
     238     4226349 :     diff.tv_nsec += GPR_NS_PER_SEC;
     239     4226349 :     dec++;
     240             :   }
     241     7648442 :   if (a.tv_sec == TYPE_MAX(time_t) || a.tv_sec == TYPE_MIN(time_t)) {
     242         814 :     diff = a;
     243    15297618 :   } else if (b.tv_sec == TYPE_MIN(time_t) ||
     244     7914515 :              (b.tv_sec <= 0 && a.tv_sec >= TYPE_MAX(time_t) + b.tv_sec)) {
     245           0 :     diff = gpr_inf_future(GPR_CLOCK_REALTIME);
     246    15298984 :   } else if (b.tv_sec == TYPE_MAX(time_t) ||
     247    15138351 :              (b.tv_sec >= 0 && a.tv_sec <= TYPE_MIN(time_t) + b.tv_sec)) {
     248        3085 :     diff = gpr_inf_past(GPR_CLOCK_REALTIME);
     249             :   } else {
     250     7646407 :     diff.tv_sec = a.tv_sec - b.tv_sec;
     251     7646407 :     if (dec != 0 && diff.tv_sec == TYPE_MIN(time_t) + 1) {
     252           0 :       diff = gpr_inf_past(GPR_CLOCK_REALTIME);
     253             :     } else {
     254     7646407 :       diff.tv_sec -= dec;
     255             :     }
     256             :   }
     257     7656897 :   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     2631055 : gpr_int32 gpr_time_to_millis(gpr_timespec t) {
     276     2631055 :   if (t.tv_sec >= 2147483) {
     277        1470 :     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        1470 :     return 2147483647;
     281     2629585 :   } 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     2629585 :     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     9840476 : gpr_timespec gpr_convert_clock_type(gpr_timespec t, gpr_clock_type clock_type) {
     295     9840476 :   if (t.clock_type == clock_type) {
     296      293020 :     return t;
     297             :   }
     298             : 
     299     9547456 :   if (t.tv_nsec == 0) {
     300     4987563 :     if (t.tv_sec == TYPE_MAX(time_t)) {
     301     4885446 :       t.clock_type = clock_type;
     302     4885446 :       return t;
     303             :     }
     304      102117 :     if (t.tv_sec == TYPE_MIN(time_t)) {
     305         262 :       t.clock_type = clock_type;
     306         262 :       return t;
     307             :     }
     308             :   }
     309             : 
     310     4661748 :   if (clock_type == GPR_TIMESPAN) {
     311           0 :     return gpr_time_sub(t, gpr_now(t.clock_type));
     312             :   }
     313             : 
     314     4661748 :   if (t.clock_type == GPR_TIMESPAN) {
     315           0 :     return gpr_time_add(gpr_now(clock_type), t);
     316             :   }
     317             : 
     318     4661748 :   return gpr_time_add(gpr_now(clock_type),
     319             :                       gpr_time_sub(t, gpr_now(t.clock_type)));
     320             : }

Generated by: LCOV version 1.10