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