This source file includes following definitions.
- ComputeCurrentTicks
 
- ComputeThreadTicks
 
- Now
 
- FromCFAbsoluteTime
 
- ToCFAbsoluteTime
 
- NowFromSystemTime
 
- FromExploded
 
- Explode
 
- Now
 
- HighResNow
 
- IsHighResNowFastAndReliable
 
- ThreadNow
 
- NowFromSystemTraceTime
 
#include "base/time/time.h"
#include <CoreFoundation/CFDate.h>
#include <CoreFoundation/CFTimeZone.h>
#include <mach/mach.h>
#include <mach/mach_time.h>
#include <sys/sysctl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/mac/scoped_mach_port.h"
namespace {
uint64_t ComputeCurrentTicks() {
#if defined(OS_IOS)
  
  
  
  
  struct timeval boottime;
  int mib[2] = {CTL_KERN, KERN_BOOTTIME};
  size_t size = sizeof(boottime);
  int kr = sysctl(mib, arraysize(mib), &boottime, &size, NULL, 0);
  DCHECK_EQ(KERN_SUCCESS, kr);
  base::TimeDelta time_difference = base::Time::Now() -
      (base::Time::FromTimeT(boottime.tv_sec) +
       base::TimeDelta::FromMicroseconds(boottime.tv_usec));
  return time_difference.InMicroseconds();
#else
  uint64_t absolute_micro;
  static mach_timebase_info_data_t timebase_info;
  if (timebase_info.denom == 0) {
    
    
    
    
    
    kern_return_t kr = mach_timebase_info(&timebase_info);
    DCHECK_EQ(KERN_SUCCESS, kr);
  }
  
  
  
  
  
  absolute_micro =
      mach_absolute_time() / base::Time::kNanosecondsPerMicrosecond *
      timebase_info.numer / timebase_info.denom;
  
  
  
  return absolute_micro;
#endif  
}
uint64_t ComputeThreadTicks() {
#if defined(OS_IOS)
  NOTREACHED();
  return 0;
#else
  base::mac::ScopedMachPort thread(mach_thread_self());
  mach_msg_type_number_t thread_info_count = THREAD_BASIC_INFO_COUNT;
  thread_basic_info_data_t thread_info_data;
  if (thread == MACH_PORT_NULL) {
    DLOG(ERROR) << "Failed to get mach_thread_self()";
    return 0;
  }
  kern_return_t kr = thread_info(
      thread,
      THREAD_BASIC_INFO,
      reinterpret_cast<thread_info_t>(&thread_info_data),
      &thread_info_count);
  DCHECK_EQ(KERN_SUCCESS, kr);
  return (thread_info_data.user_time.seconds *
              base::Time::kMicrosecondsPerSecond) +
         thread_info_data.user_time.microseconds;
#endif  
}
}  
namespace base {
static const int64 kWindowsEpochDeltaSeconds = GG_INT64_C(11644473600);
const int64 Time::kWindowsEpochDeltaMicroseconds =
    kWindowsEpochDeltaSeconds * Time::kMicrosecondsPerSecond;
const int64 Time::kTimeTToMicrosecondsOffset = kWindowsEpochDeltaMicroseconds;
Time Time::Now() {
  return FromCFAbsoluteTime(CFAbsoluteTimeGetCurrent());
}
Time Time::FromCFAbsoluteTime(CFAbsoluteTime t) {
  COMPILE_ASSERT(std::numeric_limits<CFAbsoluteTime>::has_infinity,
                 numeric_limits_infinity_is_undefined_when_not_has_infinity);
  if (t == 0)
    return Time();  
  if (t == std::numeric_limits<CFAbsoluteTime>::infinity())
    return Max();
  return Time(static_cast<int64>(
      (t + kCFAbsoluteTimeIntervalSince1970) * kMicrosecondsPerSecond) +
      kWindowsEpochDeltaMicroseconds);
}
CFAbsoluteTime Time::ToCFAbsoluteTime() const {
  COMPILE_ASSERT(std::numeric_limits<CFAbsoluteTime>::has_infinity,
                 numeric_limits_infinity_is_undefined_when_not_has_infinity);
  if (is_null())
    return 0;  
  if (is_max())
    return std::numeric_limits<CFAbsoluteTime>::infinity();
  return (static_cast<CFAbsoluteTime>(us_ - kWindowsEpochDeltaMicroseconds) /
      kMicrosecondsPerSecond) - kCFAbsoluteTimeIntervalSince1970;
}
Time Time::NowFromSystemTime() {
  
  return Now();
}
Time Time::FromExploded(bool is_local, const Exploded& exploded) {
  CFGregorianDate date;
  date.second = exploded.second +
      exploded.millisecond / static_cast<double>(kMillisecondsPerSecond);
  date.minute = exploded.minute;
  date.hour = exploded.hour;
  date.day = exploded.day_of_month;
  date.month = exploded.month;
  date.year = exploded.year;
  base::ScopedCFTypeRef<CFTimeZoneRef> time_zone(
      is_local ? CFTimeZoneCopySystem() : NULL);
  CFAbsoluteTime seconds = CFGregorianDateGetAbsoluteTime(date, time_zone) +
      kCFAbsoluteTimeIntervalSince1970;
  return Time(static_cast<int64>(seconds * kMicrosecondsPerSecond) +
      kWindowsEpochDeltaMicroseconds);
}
void Time::Explode(bool is_local, Exploded* exploded) const {
  
  
  int64 microsecond = us_ % kMicrosecondsPerSecond;
  if (microsecond < 0)
    microsecond += kMicrosecondsPerSecond;
  CFAbsoluteTime seconds = ((us_ - microsecond) / kMicrosecondsPerSecond) -
                           kWindowsEpochDeltaSeconds -
                           kCFAbsoluteTimeIntervalSince1970;
  base::ScopedCFTypeRef<CFTimeZoneRef> time_zone(
      is_local ? CFTimeZoneCopySystem() : NULL);
  CFGregorianDate date = CFAbsoluteTimeGetGregorianDate(seconds, time_zone);
  
  int cf_day_of_week = CFAbsoluteTimeGetDayOfWeek(seconds, time_zone);
  exploded->year = date.year;
  exploded->month = date.month;
  exploded->day_of_week = cf_day_of_week % 7;
  exploded->day_of_month = date.day;
  exploded->hour = date.hour;
  exploded->minute = date.minute;
  
  exploded->second = floor(date.second);
  
  
  exploded->millisecond =
      (microsecond >= 0) ? microsecond / kMicrosecondsPerMillisecond :
                           (microsecond - kMicrosecondsPerMillisecond + 1) /
                               kMicrosecondsPerMillisecond;
}
TimeTicks TimeTicks::Now() {
  return TimeTicks(ComputeCurrentTicks());
}
TimeTicks TimeTicks::HighResNow() {
  return Now();
}
bool TimeTicks::IsHighResNowFastAndReliable() {
  return true;
}
TimeTicks TimeTicks::ThreadNow() {
  return TimeTicks(ComputeThreadTicks());
}
TimeTicks TimeTicks::NowFromSystemTraceTime() {
  return HighResNow();
}
}