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();
}
}