]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
Use GetSystemTimePreciseAsFileTime() on Windows 8.
authorDave Hart <hart@ntp.org>
Tue, 13 Mar 2012 09:02:35 +0000 (09:02 +0000)
committerDave Hart <hart@ntp.org>
Tue, 13 Mar 2012 09:02:35 +0000 (09:02 +0000)
bk: 4f5f0d2bmWTxvKgcxQTYTtlfDp3j8g

ChangeLog
include/ntp_fp.h
libntp/systime.c
ports/winnt/include/clockstuff.h
ports/winnt/include/sys/time.h
ports/winnt/libntp/getclock.c
ports/winnt/ntpd/nt_clockstuff.c
util/ntp-keygen.c

index 9b0dda79ea52ddd3fbf136cc57f8dda778b10c34..78cd74ef88b59722de8f94adfe889068d6dee283 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,4 @@
+* Use GetSystemTimePreciseAsFileTime() on Windows 8.
 (4.2.7p263) 2012/03/13 Released by Harlan Stenn <stenn@ntp.org>
 * [Bug 2156] clock instability with LOCAL driver, from Miroslav Lichvar.
 * [Bug 2159] Windows ntpd using leapfile erroneous leap second 20120401.
index bb58bf1f86bd30657c28b589c56585b5f841e3c5..aca5d3498601db6b8e30822aa84c479524005563 100644 (file)
@@ -404,6 +404,8 @@ extern CRITICAL_SECTION get_systime_cs;
                EnterCriticalSection(&get_systime_cs)
 # define LEAVE_GET_SYSTIME_CRITSEC()                           \
                LeaveCriticalSection(&get_systime_cs)
+# define INIT_WIN_PRECISE_TIME()                               \
+               init_win_precise_time()
 #else  /* !SYS_WINNT follows */
 # define INIT_GET_SYSTIME_CRITSEC()                    \
                do {} while (FALSE)
@@ -411,6 +413,8 @@ extern CRITICAL_SECTION get_systime_cs;
                do {} while (FALSE)
 # define LEAVE_GET_SYSTIME_CRITSEC()                   \
                do {} while (FALSE)
+# define INIT_WIN_PRECISE_TIME()                       \
+               do {} while (FALSE)
 #endif
 
 #endif /* NTP_FP_H */
index fbe403b98105e9bc76cb5a1805828d5a4a0c993c..b98bb7258d908d7d38ba55683c8c3ab6a1590014 100644 (file)
@@ -105,6 +105,7 @@ void
 init_systime(void)
 {
        INIT_GET_SYSTIME_CRITSEC();
+       INIT_WIN_PRECISE_TIME();
        DONE_SYSTIME_INIT();
 }
 
index 1feffe49354d083ea2c67ab03aed1faab77bf0c1..3c1100b4969f1f3a6bdcf4504ada6cc716cc72ce 100644 (file)
@@ -35,8 +35,9 @@ enum {
  * either GetSystemTimeAsFileTime provided by Windows
  * or ntpd's interpolating replacement.
  */
-typedef void (WINAPI *PGSTAFT)(LPFILETIME pft);
+typedef void (WINAPI *PGSTAFT)(LPFILETIME pftResult);
 extern PGSTAFT get_sys_time_as_filetime;
+extern PGSTAFT pGetSystemTimePreciseAsFileTime;
 
 void lock_thread_to_processor(HANDLE);
 
index 3d7cadc05ebcca0d26de6329767186e18d621c9c..b4489170bea08eef6fbe3d6a5ea9b33ef73a2e54 100644 (file)
@@ -20,5 +20,6 @@ typedef struct timespec {
 extern int getclock(int, struct timespec *ts);
 extern int gettimeofday(struct timeval *, void *);
 extern int settimeofday(struct timeval *);
+extern void init_win_precise_time(void);
 
 #endif /* SYS_TIME_H */
index c5666dfc36ec136c0ca5f3829e4dce004cb9c0b3..68496bd530782331c57c179c2577ddfaebf2a38b 100644 (file)
@@ -13,6 +13,8 @@
  * via the pointer get_sys_time_as_filetime.
  */
 PGSTAFT get_sys_time_as_filetime;
+PGSTAFT pGetSystemTimePreciseAsFileTime;
+
 
 int
 getclock(
@@ -26,18 +28,11 @@ getclock(
        } uNow;
 
        if (clktyp != TIMEOFDAY) {
-#ifdef DEBUG
-               if (debug) {
-                       printf("getclock() supports only TIMEOFDAY clktyp\n");
-               }
-#endif
+               TRACE(1, ("getclock() supports only TIMEOFDAY clktyp\n"));
                errno = EINVAL;
                return -1;
        }
 
-       if (! get_sys_time_as_filetime)
-               get_sys_time_as_filetime = GetSystemTimeAsFileTime;
-
        (*get_sys_time_as_filetime)(&uNow.ft);
 
        /* 
@@ -49,3 +44,20 @@ getclock(
 
        return 0;
 }
+
+
+void
+init_win_precise_time(void)
+{
+       HANDLE  hDll;
+       FARPROC pfn;
+
+       hDll = LoadLibrary("kernel32");
+       pfn = GetProcAddress(hDll, "GetSystemTimePreciseAsFileTime");
+       if (NULL != pfn) {
+               pGetSystemTimePreciseAsFileTime = (PGSTAFT)pfn;
+               get_sys_time_as_filetime = pGetSystemTimePreciseAsFileTime;
+       } else {
+               get_sys_time_as_filetime = &GetSystemTimeAsFileTime;
+       }
+}
index f52d0e1fb2a30f177ffb609b69b8728e54cccfc4..fd6f6c35e79205590fedb24b4215e706b1f330c9 100644 (file)
@@ -189,7 +189,7 @@ static int lock_interp_threads = -1;
  * ppm_per_adjust_unit is parts per million effect on the OS
  * clock per slewing adjustment unit per second.  Per haps.
  */
-static DOUBLE ppm_per_adjust_unit = 0.0;
+static DOUBLE ppm_per_adjust_unit;
 
 /*
  * wintickadj emulates the functionality provided by unix tickadj,
@@ -689,34 +689,6 @@ init_winnt_time(void)
        if (-1 == setpriority(PRIO_PROCESS, 0, NTP_PRIO))
                exit(-1);
 
-       /* 
-        * before we start looking at clock period, do any multimedia
-        * timer manipulation requested via -M option.
-        */
-       if (modify_mm_timer) {
-               if (timeGetDevCaps(&tc, sizeof(tc)) == TIMERR_NOERROR) {
-                       wTimerRes = min(max(tc.wPeriodMin, MM_TIMER_INTV), tc.wPeriodMax);
-                       timeBeginPeriod(wTimerRes);
-                       atexit(atexit_revert_mm_timer);
-                       
-                       msyslog(LOG_INFO, "MM timer resolution: %u..%u msec, set to %u msec",
-                               tc.wPeriodMin, tc.wPeriodMax, wTimerRes );
-               } else {
-                       msyslog(LOG_ERR, "Multimedia timer unavailable");
-               }
-       }
-       
-       /* get the performance counter ticks per second */
-       if (!QueryPerformanceFrequency(&Freq) || !Freq.QuadPart) {
-               msyslog(LOG_ERR, "QueryPerformanceFrequency failed: %m\n");
-               exit(-1);
-       }
-
-       NomPerfCtrFreq = PerfCtrFreq = Freq.QuadPart;
-       msyslog(LOG_INFO, 
-               "Performance counter frequency %.3f MHz",
-               PerfCtrFreq / 1e6);
-
        /* Determine the existing system time slewing */
        if (!GetSystemTimeAdjustment(&adjclockperiod, &clockperiod, &noslew)) {
                msyslog(LOG_ERR, "GetSystemTimeAdjustment failed: %m\n");
@@ -747,6 +719,58 @@ init_winnt_time(void)
         */
        ppm_per_adjust_unit = 1e6 / clockperiod;
 
+       pch = getenv("NTPD_TICKADJ_PPM");
+       if (pch != NULL && 1 == sscanf(pch, "%lf", &adjppm)) {
+               rawadj = adjppm / ppm_per_adjust_unit;
+               rawadj += (rawadj < 0)
+                             ? -0.5
+                             : 0.5;
+               wintickadj = (long)rawadj;
+               msyslog(LOG_INFO,
+                       "Using NTPD_TICKADJ_PPM %+g ppm (%+ld)",
+                       adjppm, wintickadj);
+       }
+
+       /* get the performance counter ticks per second */
+       if (!QueryPerformanceFrequency(&Freq) || !Freq.QuadPart) {
+               msyslog(LOG_ERR, "QueryPerformanceFrequency failed: %m\n");
+               exit(-1);
+       }
+
+       NomPerfCtrFreq = PerfCtrFreq = Freq.QuadPart;
+       msyslog(LOG_INFO, 
+               "Performance counter frequency %.3f MHz",
+               PerfCtrFreq / 1e6);
+
+       /*
+        * With a precise system clock, our interpolation decision is
+        * a slam dunk.
+        */
+       if (NULL != pGetSystemTimePreciseAsFileTime) {
+               winnt_use_interpolation = FALSE;
+               winnt_time_initialized = TRUE;
+
+               return;
+       }
+
+       /* 
+        * Implement any multimedia timer manipulation requested via -M
+        * option.  This is rumored to be unneeded on Win8 with the
+        * introduction of the precise (interpolated) system clock.
+        */
+       if (modify_mm_timer) {
+               if (timeGetDevCaps(&tc, sizeof(tc)) == TIMERR_NOERROR) {
+                       wTimerRes = min(max(tc.wPeriodMin, MM_TIMER_INTV), tc.wPeriodMax);
+                       timeBeginPeriod(wTimerRes);
+                       atexit(atexit_revert_mm_timer);
+                       
+                       msyslog(LOG_INFO, "MM timer resolution: %u..%u msec, set to %u msec",
+                               tc.wPeriodMin, tc.wPeriodMax, wTimerRes );
+               } else {
+                       msyslog(LOG_ERR, "Multimedia timer unavailable");
+               }
+       }
+       
        /*
         * Spin on GetSystemTimeAsFileTime to determine its
         * granularity.  Prior to Windows Vista this is 
@@ -764,18 +788,6 @@ init_winnt_time(void)
                "Windows clock precision %.3f msec, min. slew %.3f ppm/s",
                os_clock_precision / 1e4, ppm_per_adjust_unit);
 
-       pch = getenv("NTPD_TICKADJ_PPM");
-       if (pch != NULL && 1 == sscanf(pch, "%lf", &adjppm)) {
-               rawadj = adjppm / ppm_per_adjust_unit;
-               rawadj += (rawadj < 0)
-                             ? -0.5
-                             : 0.5;
-               wintickadj = (long)rawadj;
-               msyslog(LOG_INFO,
-                       "Using NTPD_TICKADJ_PPM %+g ppm (%+ld)",
-                       adjppm, wintickadj);
-       }
-
        winnt_time_initialized = TRUE;
 
        choose_interp_counter();
@@ -1199,9 +1211,10 @@ ntp_timestamp_from_counter(
        ULONGLONG Counterstamp
        )
 {
-#ifdef DEBUG
        FT_ULL          Now;
-#endif
+       FT_ULL          Ctr;
+       LONGLONG        CtrDelta;
+       double          seconds;
        ULONGLONG       InterpTimestamp;
 
        if (winnt_use_interpolation) {
@@ -1216,7 +1229,7 @@ ntp_timestamp_from_counter(
 #ifdef DEBUG
                /* sanity check timestamp is within 1 minute of now */
                GetSystemTimeAsFileTime(&Now.ft);
-               Now.ll -= InterpTimestamp;
+               Now.ull -= InterpTimestamp;
                if (debug &&
                    Now.ll > 60 * HECTONANOSECONDS || 
                    Now.ll < -60 * HECTONANOSECONDS) {
@@ -1232,16 +1245,28 @@ ntp_timestamp_from_counter(
                }
 #endif
        } else {  /* ! winnt_use_interpolation */
-               /* have to simply use the driver's system time timestamp */
-               InterpTimestamp = Timestamp;
+               if (NULL != pGetSystemTimePreciseAsFileTime) {
+                       QueryPerformanceCounter(&Ctr.li);
+                       (*pGetSystemTimePreciseAsFileTime)(&Now.ft);
+                       CtrDelta = Ctr.ull - Counterstamp;
+                       seconds = (double)CtrDelta / PerfCtrFreq;
+                       InterpTimestamp = Now.ull -
+                           (ULONGLONG)(seconds * HECTONANOSECONDS);
+               } else {
+                       /* have to simply use the driver's system time timestamp */
+                       InterpTimestamp = Timestamp;
+                       GetSystemTimeAsFileTime(&Now.ft);
+               }
 #ifdef DEBUG
                /* sanity check timestamp is within 1 minute of now */
-               GetSystemTimeAsFileTime(&Now.ft);
-               Now.ll -= InterpTimestamp;
+               Now.ull -= InterpTimestamp;
                if (debug &&
                    Now.ll > 60 * HECTONANOSECONDS || 
                    Now.ll < -60 * HECTONANOSECONDS) {
-                       DPRINTF(1, ("ntp_timestamp_from_counter serial driver system time %.6fs from current\n",
+                       DPRINTF(1, ("ntp_timestamp_from_counter serial driver %s time %.6fs from current\n",
+                                   (NULL == pGetSystemTimePreciseAsFileTime)
+                                       ? "system"
+                                       : "counter",
                                    Now.ll / (double)HECTONANOSECONDS));
                        msyslog(LOG_ERR,
                                "ntp_timestamp_from_counter serial driver system time %.6fs from current\n",
index 2772707ae7eb76a675feb1fe372794c59f614a6a..65e2d9ac311ed41fc315a86189899de0477b507d 100644 (file)
@@ -219,7 +219,7 @@ symlink(
 
        if (!tried) {
                tried = TRUE;
-               hDll = LoadLibrary("kernel32.dll");
+               hDll = LoadLibrary("kernel32");
                pfn = GetProcAddress(hDll, "CreateHardLinkA");
                pCreateHardLinkA = (PCREATEHARDLINKA)pfn;
        }