LCOV - app.info - ipc/chromium/src/base/time_posix.cc

LCOV - code coverage report
| Current view: | directory - ipc/chromium/src/base - time_posix.cc (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 53 | 4 | 7.5 %
| Date: | 2012-06-02 | Functions: | 6 | 1 | 16.7 %

           1                 : // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
           2                 : // Use of this source code is governed by a BSD-style license that can be
           3                 : // found in the LICENSE file.
           4                 :
           5                 : #include "base/time.h"
           6                 :
           7                 : #ifdef OS_MACOSX
           8                 : #include <mach/mach_time.h>
           9                 : #endif
          10                 : #include <sys/time.h>
          11                 : #ifdef ANDROID
          12                 : #include <time64.h>
          13                 : #else
          14                 : #include <time.h>
          15                 : #endif
          16                 : #if defined(ANDROID) || defined(OS_POSIX)
          17                 : #include <unistd.h>
          18                 : #endif
          19                 :
          20                 : #include <limits>
          21                 :
          22                 : #include "base/basictypes.h"
          23                 : #include "base/logging.h"
          24                 :
          25                 : namespace base {
          26                 :
          27                 : // The Time routines in this file use standard POSIX routines, or almost-
          28                 : // standard routines in the case of timegm.  We need to use a Mach-specific
          29                 : // function for TimeTicks::Now() on Mac OS X.
          30                 :
          31                 : // Time -----------------------------------------------------------------------
          32                 :
          33                 : // Some functions in time.cc use time_t directly, so we provide a zero offset
          34                 : // for them.  The epoch is 1970-01-01 00:00:00 UTC.
          35                 : // static
          36                 : const int64 Time::kTimeTToMicrosecondsOffset = GG_INT64_C(0);
          37                 :
          38                 : // static
          39            5676 : Time Time::Now() {
          40                 :   struct timeval tv;
          41            5676 :   struct timezone tz = { 0, 0 };  // UTC
          42            5676 :   if (gettimeofday(&tv, &tz) != 0) {
          43               0 :     DCHECK(0) << "Could not determine time of day";
          44                 :   }
          45                 :   // Combine seconds and microseconds in a 64-bit field containing microseconds
          46                 :   // since the epoch.  That's enough for nearly 600 centuries.
          47            5676 :   return tv.tv_sec * kMicrosecondsPerSecond + tv.tv_usec;
          48                 : }
          49                 :
          50                 : // static
          51               0 : Time Time::NowFromSystemTime() {
          52                 :   // Just use Now() because Now() returns the system time.
          53               0 :   return Now();
          54                 : }
          55                 :
          56                 : // static
          57               0 : Time Time::FromExploded(bool is_local, const Exploded& exploded) {
          58                 :   struct tm timestruct;
          59               0 :   timestruct.tm_sec    = exploded.second;
          60               0 :   timestruct.tm_min    = exploded.minute;
          61               0 :   timestruct.tm_hour   = exploded.hour;
          62               0 :   timestruct.tm_mday   = exploded.day_of_month;
          63               0 :   timestruct.tm_mon    = exploded.month - 1;
          64               0 :   timestruct.tm_year   = exploded.year - 1900;
          65               0 :   timestruct.tm_wday   = exploded.day_of_week;  // mktime/timegm ignore this
          66               0 :   timestruct.tm_yday   = 0;     // mktime/timegm ignore this
          67               0 :   timestruct.tm_isdst  = -1;    // attempt to figure it out
          68               0 :   timestruct.tm_gmtoff = 0;     // not a POSIX field, so mktime/timegm ignore
          69               0 :   timestruct.tm_zone   = NULL;  // not a POSIX field, so mktime/timegm ignore
          70                 :
          71                 :   time_t seconds;
          72                 : #ifdef ANDROID
          73                 :     seconds = mktime(&timestruct);
          74                 : #else
          75               0 :   if (is_local)
          76               0 :     seconds = mktime(&timestruct);
          77                 :   else
          78               0 :     seconds = timegm(&timestruct);
          79                 : #endif
          80                 :
          81                 :   int64 milliseconds;
          82                 :   // Handle overflow.  Clamping the range to what mktime and timegm might
          83                 :   // return is the best that can be done here.  It's not ideal, but it's better
          84                 :   // than failing here or ignoring the overflow case and treating each time
          85                 :   // overflow as one second prior to the epoch.
          86               0 :   if (seconds == -1 &&
          87                 :       (exploded.year < 1969 || exploded.year > 1970)) {
          88                 :     // If exploded.year is 1969 or 1970, take -1 as correct, with the
          89                 :     // time indicating 1 second prior to the epoch.  (1970 is allowed to handle
          90                 :     // time zone and DST offsets.)  Otherwise, return the most future or past
          91                 :     // time representable.  Assumes the time_t epoch is 1970-01-01 00:00:00 UTC.
          92                 :     //
          93                 :     // The minimum and maximum representible times that mktime and timegm could
          94                 :     // return are used here instead of values outside that range to allow for
          95                 :     // proper round-tripping between exploded and counter-type time
          96                 :     // representations in the presence of possible truncation to time_t by
          97                 :     // division and use with other functions that accept time_t.
          98                 :     //
          99                 :     // When representing the most distant time in the future, add in an extra
         100                 :     // 999ms to avoid the time being less than any other possible value that
         101                 :     // this function can return.
         102               0 :     if (exploded.year < 1969) {
         103               0 :       milliseconds = std::numeric_limits<time_t>::min() *
         104               0 :                      kMillisecondsPerSecond;
         105                 :     } else {
         106               0 :       milliseconds = (std::numeric_limits<time_t>::max() *
         107                 :                       kMillisecondsPerSecond) +
         108               0 :                      kMillisecondsPerSecond - 1;
         109                 :     }
         110                 :   } else {
         111               0 :     milliseconds = seconds * kMillisecondsPerSecond + exploded.millisecond;
         112                 :   }
         113                 :
         114               0 :   return Time(milliseconds * kMicrosecondsPerMillisecond);
         115                 : }
         116                 :
         117               0 : void Time::Explode(bool is_local, Exploded* exploded) const {
         118                 :   // Time stores times with microsecond resolution, but Exploded only carries
         119                 :   // millisecond resolution, so begin by being lossy.
         120               0 :   int64 milliseconds = us_ / kMicrosecondsPerMillisecond;
         121               0 :   time_t seconds = milliseconds / kMillisecondsPerSecond;
         122                 :
         123                 :   struct tm timestruct;
         124               0 :   if (is_local)
         125               0 :     localtime_r(&seconds, &timestruct);
         126                 :   else
         127               0 :     gmtime_r(&seconds, &timestruct);
         128                 :
         129               0 :   exploded->year         = timestruct.tm_year + 1900;
         130               0 :   exploded->month        = timestruct.tm_mon + 1;
         131               0 :   exploded->day_of_week  = timestruct.tm_wday;
         132               0 :   exploded->day_of_month = timestruct.tm_mday;
         133               0 :   exploded->hour         = timestruct.tm_hour;
         134               0 :   exploded->minute       = timestruct.tm_min;
         135               0 :   exploded->second       = timestruct.tm_sec;
         136               0 :   exploded->millisecond  = milliseconds % kMillisecondsPerSecond;
         137               0 : }
         138                 :
         139                 : // TimeTicks ------------------------------------------------------------------
         140                 :
         141                 : // static
         142               0 : TimeTicks TimeTicks::Now() {
         143                 :   uint64_t absolute_micro;
         144                 :
         145                 : #if defined(OS_MACOSX)
         146                 :   static mach_timebase_info_data_t timebase_info;
         147                 :   if (timebase_info.denom == 0) {
         148                 :     // Zero-initialization of statics guarantees that denom will be 0 before
         149                 :     // calling mach_timebase_info.  mach_timebase_info will never set denom to
         150                 :     // 0 as that would be invalid, so the zero-check can be used to determine
         151                 :     // whether mach_timebase_info has already been called.  This is
         152                 :     // recommended by Apple's QA1398.
         153                 :     kern_return_t kr = mach_timebase_info(&timebase_info);
         154                 :     DCHECK(kr == KERN_SUCCESS);
         155                 :   }
         156                 :
         157                 :   // mach_absolute_time is it when it comes to ticks on the Mac.  Other calls
         158                 :   // with less precision (such as TickCount) just call through to
         159                 :   // mach_absolute_time.
         160                 :
         161                 :   // timebase_info converts absolute time tick units into nanoseconds.  Convert
         162                 :   // to microseconds up front to stave off overflows.
         163                 :   absolute_micro = mach_absolute_time() / Time::kNanosecondsPerMicrosecond *
         164                 :                    timebase_info.numer / timebase_info.denom;
         165                 :
         166                 :   // Don't bother with the rollover handling that the Windows version does.
         167                 :   // With numer and denom = 1 (the expected case), the 64-bit absolute time
         168                 :   // reported in nanoseconds is enough to last nearly 585 years.
         169                 :
         170                 : #elif defined(__OpenBSD__) || defined(OS_POSIX) && \
         171                 :       defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0
         172                 :
         173                 :   struct timespec ts;
         174               0 :   if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
         175               0 :     NOTREACHED() << "clock_gettime(CLOCK_MONOTONIC) failed.";
         176               0 :     return TimeTicks();
         177                 :   }
         178                 :
         179                 :   absolute_micro =
         180                 :       (static_cast<int64>(ts.tv_sec) * Time::kMicrosecondsPerSecond) +
         181               0 :       (static_cast<int64>(ts.tv_nsec) / Time::kNanosecondsPerMicrosecond);
         182                 :
         183                 : #else  // _POSIX_MONOTONIC_CLOCK
         184                 : #error No usable tick clock function on this platform.
         185                 : #endif  // _POSIX_MONOTONIC_CLOCK
         186                 :
         187               0 :   return TimeTicks(absolute_micro);
         188                 : }
         189                 :
         190                 : // static
         191               0 : TimeTicks TimeTicks::HighResNow() {
         192               0 :   return Now();
         193                 : }
         194                 :
         195                 : }  // namespace base

Generated by: LCOV version 1.7