int NaClGetTimeOfDayIntern(struct nacl_abi_timeval *tv, struct NaClTimeState *ntsp) { FILETIME ft_now; DWORD ms_counter_now; uint64_t t_ms; DWORD ms_counter_at_ft_now; uint32_t ms_counter_diff; uint64_t unix_time_ms; if (ntsp->can_use_qpc) return NaClGetTimeOfDayInternQpc(tv, ntsp, 1); GetSystemTimeAsFileTime(&ft_now); ms_counter_now = timeGetTime(); t_ms = NaClFileTimeToMs(&ft_now); NaClXMutexLock(&ntsp->mu); if (!ntsp->allow_low_resolution) { NaClLog(5, "ms_counter_now %"NACL_PRIu32"\n", (uint32_t) ms_counter_now); NaClLog(5, "t_ms %"NACL_PRId64"\n", t_ms); NaClLog(5, "system_time_start_ms %"NACL_PRIu64"\n", ntsp->system_time_start_ms); ms_counter_at_ft_now = (DWORD) (ntsp->ms_counter_start + (uint32_t) (t_ms - ntsp->system_time_start_ms)); NaClLog(5, "ms_counter_at_ft_now %"NACL_PRIu32"\n", (uint32_t) ms_counter_at_ft_now); ms_counter_diff = ms_counter_now - (uint32_t) ms_counter_at_ft_now; NaClLog(5, "ms_counter_diff %"NACL_PRIu32"\n", ms_counter_diff); if (ms_counter_diff <= kMaxMillsecondDriftBeforeRecalibration) { t_ms = t_ms + ms_counter_diff; } else { NaClCalibrateWindowsClockMu(ntsp); t_ms = ntsp->system_time_start_ms; } NaClLog(5, "adjusted t_ms = %"NACL_PRIu64"\n", t_ms); } unix_time_ms = t_ms - ntsp->epoch_start_ms; NaClXMutexUnlock(&ntsp->mu); NaClLog(5, "unix_time_ms = %"NACL_PRId64"\n", unix_time_ms); /* * Unix time is measured relative to a different epoch, Jan 1, 1970. * See the module initialization for epoch_start_ms. */ tv->nacl_abi_tv_sec = (nacl_abi_time_t) (unix_time_ms / 1000); tv->nacl_abi_tv_usec = (nacl_abi_suseconds_t) ((unix_time_ms % 1000) * 1000); return 0; }
void NaClTimeInternalInit(struct NaClTimeState *ntsp) { TIMECAPS tc; SYSTEMTIME st; FILETIME ft; /* * Maximize timer/Sleep resolution. */ timeGetDevCaps(&tc, sizeof tc); ntsp->wPeriodMin = tc.wPeriodMin; ntsp->time_resolution_ns = tc.wPeriodMin * NACL_NANOS_PER_MILLI; NaClLog(0, "NaClTimeInternalInit: timeBeginPeriod(%u)\n", tc.wPeriodMin); timeBeginPeriod(ntsp->wPeriodMin); /* * Compute Unix epoch start; calibrate high resolution clock. */ st.wYear = 1970; st.wMonth = 1; st.wDay = 1; st.wHour = 0; st.wMinute = 0; st.wSecond = 0; st.wMilliseconds = 0; SystemTimeToFileTime(&st, &ft); ntsp->epoch_start_ms = NaClFileTimeToMs(&ft); ntsp->last_reported_time_ms = 0; NaClLog(0, "Unix epoch start is %"NACL_PRIu64"ms in Windows epoch time\n", ntsp->epoch_start_ms); NaClMutexCtor(&ntsp->mu); /* * We don't actually grab the lock, since the module initializer * should be called before going threaded. */ NaClCalibrateWindowsClockMu(ntsp); }
void NaClTimeInternalInit(struct NaClTimeState *ntsp) { TIMECAPS tc; SYSTEMTIME st; FILETIME ft; LARGE_INTEGER qpc_freq; /* * Maximize timer/Sleep resolution. */ timeGetDevCaps(&tc, sizeof tc); if (ntsp->allow_low_resolution) { /* Set resolution to max so we don't over-promise. */ ntsp->wPeriodMin = tc.wPeriodMax; } else { ntsp->wPeriodMin = tc.wPeriodMin; timeBeginPeriod(ntsp->wPeriodMin); NaClLog(4, "NaClTimeInternalInit: timeBeginPeriod(%u)\n", ntsp->wPeriodMin); } ntsp->time_resolution_ns = ntsp->wPeriodMin * NACL_NANOS_PER_MILLI; /* * Compute Unix epoch start; calibrate high resolution clock. */ st.wYear = 1970; st.wMonth = 1; st.wDay = 1; st.wHour = 0; st.wMinute = 0; st.wSecond = 0; st.wMilliseconds = 0; SystemTimeToFileTime(&st, &ft); ntsp->epoch_start_ms = NaClFileTimeToMs(&ft); NaClLog(4, "Unix epoch start is %"NACL_PRIu64"ms in Windows epoch time\n", ntsp->epoch_start_ms); NaClMutexCtor(&ntsp->mu); /* * We don't actually grab the lock, since the module initializer * should be called before going threaded. */ ntsp->can_use_qpc = 0; if (!ntsp->allow_low_resolution) { ntsp->can_use_qpc = QueryPerformanceFrequency(&qpc_freq); /* * On Athlon X2 CPUs (e.g. model 15) QueryPerformanceCounter is * unreliable. Fallback to low-res clock. */ if (strstr(CPU_GetBrandString(), "AuthenticAMD") && (CPU_GetFamily() == 15)) ntsp->can_use_qpc = 0; NaClLog(4, "CPU_GetBrandString->[%s] ntsp->can_use_qpc=%d\n", CPU_GetBrandString(), ntsp->can_use_qpc); if (ntsp->can_use_qpc) { ntsp->qpc_frequency = qpc_freq.QuadPart; NaClLog(4, "qpc_frequency = %"NACL_PRId64" (counts/s)\n", ntsp->qpc_frequency); if (!NaClCalibrateWindowsClockQpc(ntsp)) ntsp->can_use_qpc = 0; } if (!ntsp->can_use_qpc) NaClCalibrateWindowsClockMu(ntsp); } }