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