# This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2009/04/03 03:49:05+00:00 davehart@shiny.ad.hartbrothers.com # new Windows interpolation knocks out 1ms jitter in previous # remove dead code # thin #ifdef SYS_WINNT forest # 64-bit time_t truncation fixes, warnings silenced # do not set hardware clock on exit unless system is shutting down # # BitKeeper/deleted/.del-ntpkeygen.vcproj # 2009/04/02 15:21:07+00:00 davehart@shiny.ad.hartbrothers.com +0 -0 # Rename: ports/winnt/ntp-keygen/ntpkeygen.vcproj -> BitKeeper/deleted/.del-ntpkeygen.vcproj # # ChangeLog # 2009/04/03 03:48:51+00:00 davehart@shiny.ad.hartbrothers.com +5 -0 # [Bug 216] new interpolation, reduce #ifdef SYS_WINNT, 64-bit time_t cleanup, only set Windows CMOS clock at ntpd exit if the computer is shutting down # # include/ntp_machine.h # 2009/04/03 03:48:52+00:00 davehart@shiny.ad.hartbrothers.com +3 -46 # remove SYS_WINNT stuff (redundant with ports/winnt/config.h) # # include/ntp_stdlib.h # 2009/04/03 03:48:52+00:00 davehart@shiny.ad.hartbrothers.com +0 -1 # remove dead humandate() code # # include/ntp_types.h # 2009/04/03 03:48:52+00:00 davehart@shiny.ad.hartbrothers.com +18 -0 # UNUSED_ARG macro definition, used to quiet compiler warnings # --- # define sock_timeval for Windows 64-bit time_t compatibility # # include/ntp_unixtime.h # 2009/04/02 23:53:28+00:00 davehart@shiny.ad.hartbrothers.com +0 -3 # remove dead code: tvtoa(), utvtoa() declarations # # libntp/Makefile.am # 2009/04/03 03:48:52+00:00 davehart@shiny.ad.hartbrothers.com +2 -2 # remove dead tvtoa.c & utvtoa.c from libntp # # libntp/buftvtots.c # 2009/04/03 03:48:52+00:00 davehart@shiny.ad.hartbrothers.com +18 -0 # Windows has no tty_clock discipline, don't look for timestamp in refclock recvbuff # # libntp/humandate.c # 2009/04/03 03:48:52+00:00 davehart@shiny.ad.hartbrothers.com +1 -30 # remove dead humandate() code # # libntp/prettydate.c # 2009/04/03 03:48:52+00:00 davehart@shiny.ad.hartbrothers.com +17 -27 # fix compiler warning with 64-bit time_t, fold duplicate code into common helper # # libntp/systime.c # 2009/04/03 03:48:53+00:00 davehart@shiny.ad.hartbrothers.com +1 -1 # quiet compiler warning with 64-bit time_t # # ntpd/ntp_config.c # 2009/04/03 03:48:53+00:00 davehart@shiny.ad.hartbrothers.com +6 -6 # quiet compiler warnings about storing int into u_short with casts # # ntpd/ntp_crypto.c # 2009/04/03 03:48:53+00:00 davehart@shiny.ad.hartbrothers.com +1 -1 # quiet compiler warning with 64-bit time_t # # ntpd/ntp_intres.c # 2009/04/03 03:48:53+00:00 davehart@shiny.ad.hartbrothers.com +1 -1 # struct sock_timeval for 64-bit time_t compatibility on Windows # # ntpd/ntp_timer.c # 2009/04/03 03:48:53+00:00 davehart@shiny.ad.hartbrothers.com +0 -27 # remove redundant code, nt_clockstuff.c enables privs earlier # # ntpd/ntpd.c # 2009/04/03 03:48:54+00:00 davehart@shiny.ad.hartbrothers.com +0 -4 # chop down some #ifdef forest # # ntpd/refclock_dumbclock.c # 2009/04/03 03:48:54+00:00 davehart@shiny.ad.hartbrothers.com +1 -1 # 64-bit time_t compiler warning silenced # # ntpdate/ntpdate.c # 2009/04/03 03:48:54+00:00 davehart@shiny.ad.hartbrothers.com +5 -18 # struct sock_timeval for 64-bit time_t compatibility on Windows, more #ifdef SYS_WINNT deforestation # # ntpdc/ntpdc.c # 2009/04/03 03:48:54+00:00 davehart@shiny.ad.hartbrothers.com +4 -16 # struct sock_timeval for 64-bit time_t compatibility on Windows # # ntpq/ntpq.c # 2009/04/03 03:48:54+00:00 davehart@shiny.ad.hartbrothers.com +5 -5 # struct sock_timeval for 64-bit time_t compatibility on Windows # # ports/winnt/include/clockstuff.h # 2009/04/03 03:48:55+00:00 davehart@shiny.ad.hartbrothers.com +32 -7 # new interpolation scheme knocks out 1ms jitter inherent in previous # # ports/winnt/include/config.h # 2009/04/03 03:48:55+00:00 davehart@shiny.ad.hartbrothers.com +27 -5 # struct sock_timeval for 64-bit time_t compatibility on Windows, more #ifdef SYS_WINNT deforestation # # ports/winnt/include/ntservice.h # 2009/04/03 03:48:55+00:00 davehart@shiny.ad.hartbrothers.com +2 -1 # expose ntservice_systemisshuttingdown(), fix calling convention mismatch # # ports/winnt/include/sys/resource.h # 2009/04/03 03:48:55+00:00 davehart@shiny.ad.hartbrothers.com +10 -4 # emulate BSD setpriority() to reduce #ifdef SYS_WINNT # # ports/winnt/include/sys/time.h # 2009/04/03 03:48:55+00:00 davehart@shiny.ad.hartbrothers.com +14 -6 # new interpolation scheme knocks out 1ms jitter inherent in previous # # ports/winnt/libntp/SetSystemTime.c # 2009/04/03 03:48:55+00:00 davehart@shiny.ad.hartbrothers.com +18 -16 # new interpolation scheme knocks out 1ms jitter inherent in previous # do not mix C runtime and Windows Gregorian calendar routines # # ports/winnt/libntp/getclock.c # 2009/04/03 03:48:58+00:00 davehart@shiny.ad.hartbrothers.com +49 -0 # emulate BSD getclock() interface # # ports/winnt/libntp/getclock.c # 2009/04/03 03:48:58+00:00 davehart@shiny.ad.hartbrothers.com +0 -0 # # ports/winnt/libntp/libntp.dsp # 2009/04/03 03:48:55+00:00 davehart@shiny.ad.hartbrothers.com +8 -0 # add getclock.c setpriority.c # # ports/winnt/libntp/libntp.vcproj # 2009/04/03 03:48:56+00:00 davehart@shiny.ad.hartbrothers.com +13 -59 # remove dead tvtoa.c & utvtoa.c from libntp, add getclock.c setpriority.c and util_clockstuff.c # # ports/winnt/libntp/randfile.c # 2009/04/03 03:48:56+00:00 davehart@shiny.ad.hartbrothers.com +3 -2 # buffer overrun protection # # ports/winnt/libntp/setpriority.c # 2009/04/03 03:48:58+00:00 davehart@shiny.ad.hartbrothers.com +79 -0 # emulate BSD setpriority() to thin #ifdef forest in ntpd.c # # ports/winnt/libntp/setpriority.c # 2009/04/03 03:48:58+00:00 davehart@shiny.ad.hartbrothers.com +0 -0 # # ports/winnt/libntp/syslog.c # 2009/04/03 03:48:56+00:00 davehart@shiny.ad.hartbrothers.com +2 -1 # use strncpy instead of strcpy, force null termination as Windows strncpy doesn't when buffer exceeded # # ports/winnt/libntp/util_clockstuff.c # 2009/04/03 03:48:56+00:00 davehart@shiny.ad.hartbrothers.com +9 -17 # no longer conflicts with ports/winnt/ntpd/nt_clockstuff.c, can be added to libntp library. # # ports/winnt/ntp-keygen/ntp-keygen.vcproj # 2009/04/03 03:48:56+00:00 davehart@shiny.ad.hartbrothers.com +0 -22 # remove util_clockstuff.c from individual projects, it's now in libntp library # # ports/winnt/ntpd/nt_clockstuff.c # 2009/04/03 03:48:56+00:00 davehart@shiny.ad.hartbrothers.com +1180 -332 # new interpolation scheme knocks out 1ms jitter inherent in previous # # ports/winnt/ntpd/ntp_iocompletionport.c # 2009/04/03 03:48:57+00:00 davehart@shiny.ad.hartbrothers.com +3 -5 # move lock_thread_to_processor prototype to clockstuff.h # # ports/winnt/ntpd/ntservice.c # 2009/04/03 03:48:57+00:00 davehart@shiny.ad.hartbrothers.com +52 -41 # ntservice_systemisshuttingdown(), fix mismatched calling convention, remove erroneous SetServiceStatus calls, eliminate unreachable code warning by removing exit() calls from main() # # ports/winnt/ntpd/win32_io.c # 2009/04/03 03:48:57+00:00 davehart@shiny.ad.hartbrothers.com +0 -12 # emulate BSD setpriority() to reduce #ifdef SYS_WINNT # # ports/winnt/ntpdate/ntpdate.vcproj # 2009/04/03 03:48:57+00:00 davehart@shiny.ad.hartbrothers.com +0 -22 # remove util_clockstuff.c from individual projects, it's now in libntp library # # ports/winnt/ntpdc/ntpdc.vcproj # 2009/04/03 03:48:57+00:00 davehart@shiny.ad.hartbrothers.com +0 -22 # remove util_clockstuff.c from individual projects, it's now in libntp library # # ports/winnt/ntpq/ntpq.vcproj # 2009/04/03 03:48:57+00:00 davehart@shiny.ad.hartbrothers.com +0 -22 # remove util_clockstuff.c from individual projects, it's now in libntp library # # ports/winnt/scripts/mkver.bat # 2009/04/03 03:48:58+00:00 davehart@shiny.ad.hartbrothers.com +4 -4 # fix VC++ 2008 parallel build collision on %TEMP%\TZ.TMP by using a different filename for each program # # util/ntp-keygen.c # 2009/04/03 03:48:58+00:00 davehart@shiny.ad.hartbrothers.com +1 -4 # remove #ifdef SYS_WINNT, gettimeofday() prototype on Windows now matches Unix # diff -Nr a/ChangeLog b/ChangeLog 0a1,5 > * [Bug 216] New interpolation scheme for Windows eliminates 1ms jitter > * remove a bunch of #ifdef SYS_WINNT from portable code > * 64-bit time_t cleanup for building on newer Windows compilers > * Only set CMOS clock during ntpd exit on Windows if the computer is > shutting down or restarting. diff -Nr a/include/ntp_machine.h b/include/ntp_machine.h 230c230 < # define SOCKET int --- > typedef int SOCKET; 233c233 < # define closesocket close --- > # define closesocket(fd) close(fd) 235,276d234 < /* < * Windows NT < */ < #if defined(SYS_WINNT) < # if !defined(HAVE_CONFIG_H) || !defined(__config) < # include < # endif /* HAVE_CONFIG_H) */ < # include < # include < # include < < # define ifreq _INTERFACE_INFO < # define ifr_flags iiFlags < # define ifr_addr iiAddress.AddressIn < # define ifr_broadaddr iiBroadcastAddress.AddressIn < # define ifr_mask iiNetmask.AddressIn < # define zz_family sin_family < < # define S_IFREG _S_IFREG < # define stat _stat < # define isascii __isascii < # define isatty _isatty < # define mktemp _mktemp < # define unlink _unlink < # define fileno _fileno < # define write _write < #ifndef close < # define close _close < #endif < # undef interface < # include < #define getpid _getpid < /* < * Defining registers are not a good idea on Windows < * This gets rid of the usage < */ < #ifndef register < # define register < #endif < typedef char *caddr_t; < # define vsnprintf _vsnprintf < #endif /* SYS_WINNT */ 506,507c464 < && !defined(HAVE_NO_NICE) \ < && !defined(SYS_WINNT) --- > && !defined(HAVE_NO_NICE) diff -Nr a/include/ntp_stdlib.h b/include/ntp_stdlib.h 68d67 < extern char * humandate (u_long); diff -Nr a/include/ntp_types.h b/include/ntp_types.h 25a26,32 > * used to quiet compiler warnings > */ > #ifndef UNUSED_ARG > #define UNUSED_ARG(arg) ((void)(arg)) > #endif > > /* 66a74,84 > > /* > * On Unix struct sock_timeval is equivalent to struct timeval. > * On Windows built with 64-bit time_t, sock_timeval.tv_sec is a long > * as required by Windows' socket() interface timeout argument, while > * timeval.tv_sec is time_t for the more common use as a UTC time > * within NTP. > */ > #ifndef SYS_WINNT > #define sock_timeval timeval > #endif diff -Nr a/include/ntp_unixtime.h b/include/ntp_unixtime.h 139,141d138 < < extern char * tvtoa (const struct timeval *); < extern char * utvtoa (const struct timeval *); diff -Nr a/libntp/Makefile.am b/libntp/Makefile.am 16,17c16,17 < syssignal.c tsftomsu.c tstotv.c tvtoa.c tvtots.c \ < uglydate.c uinttoa.c utvtoa.c ymd2yd.c \ --- > syssignal.c tsftomsu.c tstotv.c tvtots.c \ > uglydate.c uinttoa.c ymd2yd.c \ diff -Nr a/libntp/buftvtots.c b/libntp/buftvtots.c 13a14 > #ifndef SYS_WINNT 35a37,53 > #else /* SYS_WINNT */ > /* > * Windows doesn't have the tty_clock line discipline, so > * don't look for a timestamp where there is none. > */ > int > buftvtots( > const char *bufp, > l_fp *ts > ) > { > UNUSED_ARG(bufp); > UNUSED_ARG(ts); > > return 0; > } > #endif /* SYS_WINNT */ diff -Nr a/libntp/humandate.c b/libntp/humandate.c 10,39c10 < static const char *months[] = { < "Jan", "Feb", "Mar", "Apr", "May", "Jun", < "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" < }; < static const char *days[] = { < "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" < }; < < char * < humandate( < u_long ntptime < ) < { < char *bp; < struct tm *tm; < < tm = ntp2unix_tm(ntptime, 1); < < if (!tm) < return "--- --- -- ---- --:--:--"; < < LIB_GETBUF(bp); < < (void) sprintf(bp, "%s, %s %2d %4d %2d:%02d:%02d", < days[tm->tm_wday], months[tm->tm_mon], tm->tm_mday, < 1900+tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec); < < return bp; < } < --- > extern const char *months[]; /* prettydate.c */ diff -Nr a/libntp/prettydate.c b/libntp/prettydate.c 12c12 < static const char *months[] = { --- > const char *months[] = { 152a153 > 154,155c155,157 < prettydate( < l_fp *ts --- > common_prettydate( > l_fp *ts, > int local 160c162 < time_t sec; --- > u_long sec; 168c170 < tm = ntp2unix_tm(sec, 1); --- > tm = ntp2unix_tm(sec, local); 182a185 > 184c187 < gmprettydate( --- > prettydate( 188,191c191,192 < char *bp; < struct tm *tm; < time_t sec; < u_long msec; --- > return common_prettydate(ts, 1); > } 193,196d193 < LIB_GETBUF(bp); < < sec = ts->l_ui; < msec = ts->l_uf / 4294967; /* fract / (2 ** 32 / 1000) */ 198,210c195,200 < tm = ntp2unix_tm(sec, 0); < if (!tm) { < (void) sprintf(bp, "%08lx.%08lx --- --- -- ---- --:--:--", < (u_long)ts->l_ui, (u_long)ts->l_uf); < } < else { < (void) sprintf(bp, "%08lx.%08lx %s, %s %2d %4d %2d:%02d:%02d.%03lu", < (u_long)ts->l_ui, (u_long)ts->l_uf, days[tm->tm_wday], < months[tm->tm_mon], tm->tm_mday, 1900 + tm->tm_year, < tm->tm_hour,tm->tm_min, tm->tm_sec, msec); < } < < return bp; --- > char * > gmprettydate( > l_fp *ts > ) > { > return common_prettydate(ts, 0); diff -Nr a/libntp/systime.c b/libntp/systime.c 79c79 < now->l_i = ts.tv_sec + JAN_1970; --- > now->l_i = (int32)ts.tv_sec + JAN_1970; diff -Nr a/ntpd/ntp_config.c b/ntpd/ntp_config.c 956c956 < addr_sock.ss_family = addr_node->type; --- > addr_sock.ss_family = (u_short)addr_node->type; 974c974 < addr_sock.ss_family = addr_node->type; --- > addr_sock.ss_family = (u_short)addr_node->type; 1229c1229 < addr_sock.ss_family = my_node->addr->type; --- > addr_sock.ss_family = (u_short)my_node->addr->type; 1250c1250 < addr_mask.ss_family = my_node->mask->type; --- > addr_mask.ss_family = (u_short)my_node->mask->type; 1479c1479 < addr_sock.ss_family = addr_node->type; --- > addr_sock.ss_family = (u_short)addr_node->type; 1820c1820 < peeraddr.ss_family = curr_peer->addr->type; --- > peeraddr.ss_family = (u_short)curr_peer->addr->type; diff -Nr a/ntpd/ntp_crypto.c b/ntpd/ntp_crypto.c 1937c1937 < return (timegm(&tm) + JAN_1970); --- > return ((u_long)timegm(&tm) + JAN_1970); diff -Nr a/ntpd/ntp_intres.c b/ntpd/ntp_intres.c 654c654 < struct timeval tvout; --- > struct sock_timeval tvout; diff -Nr a/ntpd/ntp_timer.c b/ntpd/ntp_timer.c 153,157d152 < # if defined SYS_WINNT & !defined(SYS_CYGWIN32) < HANDLE hToken = INVALID_HANDLE_VALUE; < TOKEN_PRIVILEGES tkp; < # endif /* SYS_WINNT */ < 212,233d206 < _tzset(); < < /* < * Get privileges needed for fiddling with the clock < */ < < /* get the current process token handle */ < if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { < msyslog(LOG_ERR, "OpenProcessToken failed: %m"); < exit(1); < } < /* get the LUID for system-time privilege. */ < LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &tkp.Privileges[0].Luid); < tkp.PrivilegeCount = 1; /* one privilege to set */ < tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; < /* get set-time privilege for this process. */ < AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0); < /* cannot test return value of AdjustTokenPrivileges. */ < if (GetLastError() != ERROR_SUCCESS) { < msyslog(LOG_ERR, "AdjustTokenPrivileges failed: %m"); < } < diff -Nr a/ntpd/ntpd.c b/ntpd/ntpd.c 383,386d382 < #ifdef SYS_WINNT < priority_done += NT_set_process_priority(); < #endif < diff -Nr a/ntpd/refclock_dumbclock.c b/ntpd/refclock_dumbclock.c 252c252 < int reality_delta; --- > time_t reality_delta; diff -Nr a/ntpdate/ntpdate.c b/ntpdate/ntpdate.c 68c68 < struct timeval timeout = {0,1000000/TIMER_HZ}; --- > struct sock_timeval timeout = {0,1000000/TIMER_HZ}; 242d241 < HANDLE TimerThreadHandle = NULL; 466,469d464 < #ifdef SYS_WINNT < /* Win32 does not implement line buffering */ < setvbuf(stdout, NULL, _IONBF, BUFSIZ); < #else 471d465 < #endif /* SYS_WINNT */ 564,570d557 < #ifdef SYS_WINNT < process_handle = GetCurrentProcess(); < if (!SetPriorityClass(process_handle, (DWORD) REALTIME_PRIORITY_CLASS)) { < msyslog(LOG_ERR, "SetPriorityClass failed: %m"); < } < #endif /* SYS_WINNT */ < 1532a1520,1522 > UNUSED_ARG(uTimerID); UNUSED_ARG(uMsg); UNUSED_ARG(dwUser); > UNUSED_ARG(dw1); UNUSED_ARG(dw2); > 1535d1524 < #endif /* SYS_WINNT */ 1537,1538d1525 < < #ifdef SYS_WINNT 1913c1900 < struct timeval tvzero; --- > struct sock_timeval tvzero; diff -Nr a/ntpdc/ntpdc.c b/ntpdc/ntpdc.c 180,181c180,181 < static struct timeval tvout = { DEFTIMEOUT, 0 }; /* time out for reads */ < static struct timeval tvsout = { DEFSTIMEOUT, 0 }; /* secondary time out */ --- > static struct sock_timeval tvout = { DEFTIMEOUT, 0 }; /* time out for reads */ > static struct sock_timeval tvsout = { DEFSTIMEOUT, 0 };/* secondary time out */ 192,203d191 < #if defined (SYS_WINNT) || defined (SYS_VXWORKS) < char password[9]; < #endif /* SYS_WINNT || SYS_VXWORKS */ < < #ifdef SYS_WINNT < DWORD NumberOfBytesWritten; < < HANDLE TimerThreadHandle = NULL; /* 1998/06/03 - Used in ntplib/machines.c */ < void timer(void) { ; }; /* 1998/06/03 - Used in ntplib/machines.c */ < < #endif /* SYS_WINNT */ < 687c675 < struct timeval tvo; --- > struct sock_timeval tvo; 1018c1006 < struct timeval tvzero; --- > struct sock_timeval tvzero; diff -Nr a/ntpq/ntpq.c b/ntpq/ntpq.c 386,387c386,387 < struct timeval tvout = { DEFTIMEOUT, 0 }; /* time out for reads */ < struct timeval tvsout = { DEFSTIMEOUT, 0 }; /* secondary time out */ --- > struct sock_timeval tvout = { DEFTIMEOUT, 0 }; /* time out for reads */ > struct sock_timeval tvsout = { DEFSTIMEOUT, 0 };/* secondary time out */ 849c849 < struct timeval tvo; --- > struct sock_timeval tvo; 2221c2221 < val = tvout.tv_sec * 1000 + tvout.tv_usec / 1000; --- > val = (int)tvout.tv_sec * 1000 + tvout.tv_usec / 1000; 2225c2225 < tvout.tv_usec = (pcmd->argval[0].uval - (tvout.tv_sec * 1000)) --- > tvout.tv_usec = (pcmd->argval[0].uval - ((long)tvout.tv_sec * 1000)) diff -Nr a/ports/winnt/include/clockstuff.h b/ports/winnt/include/clockstuff.h 10,14d9 < /* Windows NT versions of gettimeofday and settimeofday < * < * ftime() has internal DayLightSavings related BUGS < * therefore switched to GetSystemTimeAsFileTime() < */ 17d11 < void shutdown_winnt_time(void); 25c19 < #define HECTONANOSECONDS 10000000ui64 --- > #define HECTONANOSECONDS 10000000 36a31,61 > > /* > * Optional callback from libntp ntp_set_tod() to Windows ntpd code > * in nt_clockstuff that needs to know. Optional because other > * libntp clients like ntpdate don't use it. > */ > > typedef void (*time_stepped_callback)(void); > extern time_stepped_callback step_callback; > > /* > * get_sys_time_as_filetime is a function pointer to > * either GetSystemTimeAsFileTime provided by Windows > * or ntpd's interpolating replacement. > */ > > typedef void (WINAPI *PGSTAFT)(LPFILETIME pft); > extern PGSTAFT get_sys_time_as_filetime; > > void lock_thread_to_processor(HANDLE); > > #ifdef HAVE_PPSAPI > /* > * ntp_timestamp_from_counter provides an interface for > * serialpps.sys counterstamps to be converted to > * interpolated timestamps. > */ > > extern void ntp_timestamp_from_counter(l_fp *, ULONGLONG, ULONGLONG); > #endif > diff -Nr a/ports/winnt/include/config.h b/ports/winnt/include/config.h 56a57,69 > /* > * On Unix struct sock_timeval is equivalent to struct timeval. > * On Windows built with 64-bit time_t, sock_timeval.tv_sec is a long > * as required by Windows' socket() interface timeout argument, while > * timeval.tv_sec is time_t for the more common use as a UTC time > * within NTP. > * > * winsock.h unconditionally defines struct timeval with long tv_sec > * instead of time_t tv_sec. We redirect its declaration to struct > * sock_timeval instead of struct timeval with a #define. > */ > #define timeval sock_timeval > 61a75 > 83a98,103 > #undef timeval /* see sock_timeval #define and comment above */ > struct timeval { > time_t tv_sec; > long tv_usec; > }; > 151,152c171,172 < #define OPEN_BCAST_SOCKET 1 /* for ntp_io.c */ < #define TYPEOF_IP_MULTICAST_LOOP BOOL --- > #define OPEN_BCAST_SOCKET 1 /* for ntp_io.c */ > #define TYPEOF_IP_MULTICAST_LOOP BOOL 220,221d239 < int NT_set_process_priority(void); /* Define this function */ < 246c264 < # define SYSV_TIMEOFDAY /* for ntp_unixtime.h */ --- > # define HAVE_GETCLOCK 272a291,294 > #define HAVE_SYS_RESOURCE_H > #define HAVE_BSD_NICE /* emulate BSD setpriority() */ > > typedef char *caddr_t; diff -Nr a/ports/winnt/include/ntservice.h b/ports/winnt/include/ntservice.h 30c30 < void ServiceControl(DWORD dwCtrlCode); --- > void WINAPI ServiceControl(DWORD dwCtrlCode); 32a33 > BOOL ntservice_systemisshuttingdown(); diff -Nr a/ports/winnt/include/sys/resource.h b/ports/winnt/include/sys/resource.h 1,4c1,10 < /************************************************************** < * Dummy Header for Unix to Windows NT portability < * Created for NTP package < **************************************************************/ --- > /* > * ports/winnt/include/sys/resource.h > * > * routines declared in Unix systems' sys/resource.h > */ > > #define PRIO_PROCESS 0 > #define NTP_PRIO (-12) > > int setpriority(int, int, int); /* winnt\libntp\setpriority.c */ diff -Nr a/ports/winnt/include/sys/time.h b/ports/winnt/include/sys/time.h 1,4c1,5 < /************************************************************** < * Dummy Header for Unix to Windows NT portability < * Created for NTP package < **************************************************************/ --- > /* > * ports/winnt/include/sys/time.h > * > * routines declared in Unix systems' sys/time.h > */ 15,16c16,24 < extern int gettimeofday (struct timeval *); < extern int settimeofday (struct timeval *); --- > typedef struct timespec { > time_t tv_sec; > long tv_nsec; > } timespec_t; > > #define TIMEOFDAY 0 /* getclock() clktyp arg */ > extern int getclock(int, struct timespec *ts); > extern int gettimeofday(struct timeval *, int); > extern int settimeofday(struct timeval *); diff -Nr a/ports/winnt/libntp/SetSystemTime.c b/ports/winnt/libntp/SetSystemTime.c 5c5,7 < const char * set_tod_using = "SetSystemTime"; --- > const char *set_tod_using = "SetSystemTime"; > > time_stepped_callback step_callback = NULL; 14,27c16,25 < struct tm *gmtm; < const time_t x = tv->tv_sec; < long y = tv->tv_usec; < (void) tzp; < < gmtm = gmtime(&x); < st.wSecond = (WORD) gmtm->tm_sec; < st.wMinute = (WORD) gmtm->tm_min; < st.wHour = (WORD) gmtm->tm_hour; < st.wDay = (WORD) gmtm->tm_mday; < st.wMonth = (WORD) (gmtm->tm_mon + 1); < st.wYear = (WORD) (gmtm->tm_year + 1900); < st.wDayOfWeek = (WORD) gmtm->tm_wday; < st.wMilliseconds = (WORD) (y / 1000); --- > union { > FILETIME ft; > ULONGLONG ull; > } t; > > UNUSED_ARG(tzp); > > t.ull = FILETIME_1970 + > (ULONGLONG)tv->tv_sec * 10 * 1000 * 1000 + > (ULONGLONG)tv->tv_usec * 10; 29c27 < if (!SetSystemTime(&st)) { --- > if (!FileTimeToSystemTime(&t.ft, &st) || !SetSystemTime(&st)) { 32a31,34 > > if (step_callback) > (*step_callback)(); > diff -Nr a/ports/winnt/libntp/getclock.c b/ports/winnt/libntp/getclock.c 0a1,49 > /* > * getclock.c - Emulate Unix getclock(3) nanosecond interface for libntp/ntpd > */ > #include "config.h" > #include "clockstuff.h" > #include "ntp_stdlib.h" > > /* > * getclock() is in libntp. To use interpolation, > * ports/winnt/ntpd/nt_clockstuff.c overrides GetSystemTimeAsFileTime > * via the pointer get_sys_time_as_filetime. > */ > PGSTAFT get_sys_time_as_filetime; > > int > getclock( > int clktyp, > struct timespec *ts > ) > { > union { > FILETIME ft; > ULONGLONG ull; > } uNow; > > if (clktyp != TIMEOFDAY) { > #ifdef DEBUG > if (debug) { > printf("getclock() supports only TIMEOFDAY clktyp\n"); > } > #endif > errno = EINVAL; > return -1; > } > > if (! get_sys_time_as_filetime) > get_sys_time_as_filetime = GetSystemTimeAsFileTime; > > (*get_sys_time_as_filetime)(&uNow.ft); > > /* > * Convert the hecto-nano second time to timespec format > */ > uNow.ull -= FILETIME_1970; > ts->tv_sec = (time_t)( uNow.ull / HECTONANOSECONDS); > ts->tv_nsec = (long)(( uNow.ull % HECTONANOSECONDS) * 100); > > return 0; > } diff -Nr a/ports/winnt/libntp/libntp.dsp b/ports/winnt/libntp/libntp.dsp 88a89,96 > SOURCE=.\getclock.c > # End Source File > # Begin Source File > > SOURCE=.\setpriority.c > # End Source File > # Begin Source File > diff -Nr a/ports/winnt/libntp/libntp.vcproj b/ports/winnt/libntp/libntp.vcproj 714a715,718 > RelativePath=".\getclock.c" > > > > < < < < < 1578a1565,1568 > RelativePath=".\setpriority.c" > > > > < < < < < < < < RelativePath=".\util_clockstuff.c" 1911,1928d1878 < < < < < < 2136a2087,2090 > > > > RelativePath="..\include\sys\resource.h" diff -Nr a/ports/winnt/libntp/randfile.c b/ports/winnt/libntp/randfile.c 47,48c47,49 < if (homedir != NULL) { < strcpy(tmp, homedir); --- > if (homedir != NULL && > (strlen(homedir) + 5 /* \.rnd */) < sizeof(tmp)) { > strncpy(tmp, homedir, sizeof(tmp)); diff -Nr a/ports/winnt/libntp/setpriority.c b/ports/winnt/libntp/setpriority.c 0a1,79 > #include > #include > #include > #include /* our private version */ > #include "ntp_machine.h" > #include "ntp_stdlib.h" > #include "ntp_syslog.h" > #include "ntp_debug.h" > #include "ntp_fp.h" > #include "ntp.h" > #include "clockstuff.h" > > > /* > * setpriority > * > * to reduce the #ifdef forest in the portable code, > * we emulate the BSD setpriority interface: > * > * if (-1 == setpriority(PRIO_PROCESS, 0, NTP_PRIO)) > * msyslog(LOG_ERR, "setpriority() error: %m"); > * > * However, since the Windows port of ntpd has always raised its > * priority (to realtime if allowed, or silently downgraded to > * high by the system if not) with or without -N. Changing that > * now would endanger users who upgrade the binary without adding > * -N to its invocation. Instsrv assumes ntpd.exe is installed > * with no command-line arguments. > * > * This routine is used by utilities as well as ntpd itself, so > * it checks if the priority is already high or realtime and > * logs no complaints in that case, to avoid duplicating. ntpd > * will have raised the priority to one of those in > * init_winnt_time, while the utilities will rely on this > * code. > * > */ > > int setpriority( > int which, > int who, > int prio > ) > { > BOOL success; > DWORD prio_class; > > if (PRIO_PROCESS != which || who || NTP_PRIO != prio) { > DPRINTF(1,("windows setpriority() clone needs work.\n")); > } > > prio_class = GetPriorityClass(GetCurrentProcess()); > > if (HIGH_PRIORITY_CLASS == prio_class || > REALTIME_PRIORITY_CLASS == prio_class) > return 0; > > success = SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); > > if (!success) { > msyslog(LOG_ERR, "Unable to raise priority: %m"); > errno = EPERM; > return -1; > } > > prio_class = GetPriorityClass(GetCurrentProcess()); > > if (REALTIME_PRIORITY_CLASS == prio_class) > msyslog(LOG_INFO, "Raised to realtime priority class"); > else if (HIGH_PRIORITY_CLASS == prio_class) > msyslog(LOG_ERR, "Raised to high priority class, realtime " > "requires Increase Scheduling Priority " > "privilege (enabled with secpol.msc)."); > else > msyslog(LOG_ERR, "Unexpected process priority class %d", > prio_class); > > return 0; > } diff -Nr a/ports/winnt/libntp/syslog.c b/ports/winnt/libntp/syslog.c 134c134,135 < strcpy(progname, name); --- > strncpy(progname, name, sizeof(progname)); > progname[sizeof(progname) - 1] = 0; diff -Nr a/ports/winnt/libntp/util_clockstuff.c b/ports/winnt/libntp/util_clockstuff.c 4a5,6 > #include "ntp_syslog.h" > #include "ntp_stdlib.h" 7,9d8 < DWORD units_per_tick = 0; < DOUBLE ppm_per_adjust_unit = 0.0; /* to satisfy libntp */ < 12c11,12 < struct timeval *tv --- > struct timeval *tv, > int ignored 15,17c15 < /* Use the system time (roughly synchronised to the tick, and < * extrapolated using the system performance counter. < */ --- > struct timespec ts; 19,20c17 < FILETIME StartTime; < ULONGLONG Time; --- > UNUSED_ARG(ignored); 22,24c19 < GetSystemTimeAsFileTime(&StartTime); < Time = (((ULONGLONG) StartTime.dwHighDateTime) << 32) + < (ULONGLONG) StartTime.dwLowDateTime; --- > getclock(TIMEOFDAY, &ts); 26,30c21,22 < /* Convert the hecto-nano second time to tv format < */ < Time -= FILETIME_1970; < tv->tv_sec = (LONG) ( Time / 10000000ui64); < tv->tv_usec = (LONG) (( Time % 10000000ui64) / 10); --- > tv->tv_sec = ts.tv_sec; > tv->tv_usec = ts.tv_nsec / 10; diff -Nr a/ports/winnt/ntp-keygen/ntp-keygen.vcproj b/ports/winnt/ntp-keygen/ntp-keygen.vcproj 336,357d335 < RelativePath="..\libntp\util_clockstuff.c" < > < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < diff -Nr a/ports/winnt/ntpd/nt_clockstuff.c b/ports/winnt/ntpd/nt_clockstuff.c 3,38d2 < * < * Revision History: < * $Log$ < * Revision 1.9 2000/11/19 09:02:12 dietrich < * From: Ron Thornton [rthornto@pictel.com] < * Sent: Thu 11/16/00 8:51 AM < * On Windows 2000 it requires a privilege on the current process token < * that is disabled by default on Windows 2000. < * < * I set the token by adding the following code at the beginning of the < * init_winnt_time() function in nt_clockstuff.c. < * < * Revision 1.8 2000/11/19 08:03:20 dietrich < * From: "Colin Dancer" < * To: < * Sent: 10 November 2000 12:59 < * Subject: NT bug in NTP 4.0.99j < * < * I've found a bug in (and produced a fix for) the NT clock interpolation < * code in NTP 4.0.99j. < * < * The symptoms of the problem are that gettimeofday() function on NT < * can be wrong by hundreds of seconds if, while a gettimeofday() call < * is being processed, an APC completes after the query of the performance < * counter but before the lock is grabbed. The most obvious fix is to move < * the lock to include the querying of the performance counter, but this < * could affect the predictability of the timestamp so I have instead < * tweaked the code to detect and sidestep the duff calculation. < * < * I've also found that on a loaded system the execution of the APC can be < * delayed, leading to errors of upto 10ms. There is no easy fix to this, < * but I do have code for an alternative interpolation scheme which avoids < * the problem on single processor systems. I'm currently integrating this < * along with code for deciding which algorithm to use based on whether < * the system is SP or MP. < * 40a5,7 > * New interpolation scheme by Dave Hart February 2009 > * overcomes 500us-1ms inherent jitter with the older scheme, first identified > * by Peter Rosin (nee Ekberg) in 2003 [Bug 216]. 47a15,24 > #include /* our private version */ > > #if defined(_MSC_VER) && _MSC_VER >= 1400 /* VS 2005 */ > #include /* for __rdtsc() */ > #endif > > #ifdef HAVE_PPSAPI > #include > #endif > 48a26,27 > #include "ntp_unixtime.h" > #include "ntp_timer.h" 51d29 < #include "ntp_timer.h" 53a32,33 > extern double sys_residual; /* residual from previous adjustment */ > 58,68c38,43 < /* < * Whether or not MM timer modifications takes place is still controlled < * by the variable below which is initialized by a default value but < * might be changed depending on a command line switch. < */ < int modify_mm_timer = MM_TIMER_LORES; < < #define MM_TIMER_INTV 1 /* the interval we'd want to set the MM timer to [ms] */ < < static UINT wTimerRes; < static TIMECAPS tc; --- > /* > * Whether or not MM timer modifications takes place is still controlled > * by the variable below which is initialized by a default value but > * might be changed depending on a command line switch. > */ > static int modify_mm_timer = MM_TIMER_LORES; 69a45 > #define MM_TIMER_INTV 1 /* the interval we'd want to set the MM timer to [ms] */ 71c47 < extern double sys_residual; /* residual from previous adjustment */ --- > static UINT wTimerRes; 73d48 < char szMsgPath[255]; 82,83c57 < typedef union < { --- > typedef union ft_ull { 85a60,61 > LONGLONG ll; > LARGE_INTEGER li; 87a64 > /* leap second stuff */ 90c67 < static LARGE_INTEGER ls_ref_perf_cnt; --- > static ULONGLONG ls_ref_perf_cnt; 92a70,76 > static BOOL winnt_time_initialized = FALSE; > static BOOL winnt_use_interpolation = FALSE; > static ULONGLONG last_interp_time; > static unsigned clock_thread_id; > > > void WINAPI GetInterpTimeAsFileTime(LPFILETIME pft); 94,95c78,84 < static void StopClockThread(void); < void lock_thread_to_processor(HANDLE); --- > static void tune_ctr_freq(LONGLONG, LONGLONG); > void StopClockThread(void); > void atexit_revert_mm_timer(void); > void time_stepped(void); > > static HANDLE clock_thread = NULL; > static HANDLE TimerThreadExitRequest = NULL; 96a86,92 > /* > * interp_time estimates time in 100ns units > * based on a performance counter value given. > * The 2nd parameter indicates if this is > * part of a current time-of-day calculation. > */ > ULONGLONG interp_time(ULONGLONG, BOOL); 98c94,99 < static CRITICAL_SECTION TimerCritialSection; /* lock for LastTimerCount & LastTimerTime */ --- > /* > * add_counter_time_pair is called by the > * high priority clock thread with a new > * sample. > */ > void add_counter_time_pair(ULONGLONG, LONGLONG); 100,102c101,106 < static ULONGLONG RollOverCount = 0; < static ULONGLONG LastTimerCount = 0; < static ULONGLONG LastTimerTime = 0; --- > /* > * globals used by the above two functions to > * implement the counter/time history > */ > #define BASELINES_TOT 256 > #define BASELINES_USED 64 104,105c108,123 < static HANDLE ClockThreadHandle = NULL; < static HANDLE TimerThreadExitRequest = NULL; --- > static volatile int newest_baseline = 0; > static volatile int newest_baseline_gen = 0; > static ULONGLONG baseline_counts[BASELINES_TOT] = {0}; > static LONGLONG baseline_times[BASELINES_TOT] = {0}; > > static int clock_backward_count; > static ULONGLONG clock_backward_max; > > > /* > * clockperiod is the period used for SetSystemTimeAdjustment > * slewing calculations but does not necessarily correspond > * to the precision of the OS clock. Prior to Windows Vista > * (6.0) the two were identical. In 100ns units. > */ > static DWORD clockperiod; 107,109c125,166 < static DWORD every = 0; < static DWORD initial_units_per_tick = 0; < static DWORD lastLowTimer = 0; --- > /* > * os_clock_precision is the observed precision of the OS > * clock, meaning the increment between discrete values. This > * is currently calculated once at startup. 100ns units. > */ > static ULONGLONG os_clock_precision; > > /* > * NomPerfCtrFreq is from QueryPerformanceFrequency and is the > * number of performance counter beats per second. PerfCtrFreq > * starts from NomPerfCtrFreq but is maintained using a sliding > * window average based on actual performance counter behavior, > * to allow us to better tolerate powersaving measures that > * alter the effective frequency of the processor cycle counter > * (TSC) which sometimes underlies QueryPerformanceCounter. > * > * Note that the OS is unlikely to be so subtle in its internal > * scheduling of waitable timers, presumably done using the > * performance counter. Therefore our calculations for > * interpolated time should be based on PerfCtrFreq but our > * calculations for SetWaitableTimer should assume the OS will > * convert from FILETIME 100ns units to performance counter > * beats using the nominal frequency. > */ > > volatile ULONGLONG PerfCtrFreq = 0; > ULONGLONG NomPerfCtrFreq = 0; > > /* > * If we're using RDTSC beating at the same rate as > * QueryPerformanceCounter, there is a systemic > * offset we need to account for when using > * counterstamps from serialpps.sys, which are > * always from QPC (actually KeQueryPerformanceCounter). > */ > static LONGLONG QPC_offset = 0; > > /* > * use_pcc could be a local static in perf_ctr but > * lock_thread_to_processor cares about it. > */ > static int use_pcc = -1; 111,112c168,171 < ULONGLONG PerfFrequency = 0; < static DWORD units_per_tick = 0; --- > /* > * ppm_per_adjust_unit is parts per million effect on the OS > * clock per slewing adjustment unit per second. Per haps. > */ 115a175,296 > * performance counter frequency observations > */ > #define TUNE_CTR_DEPTH 3 /* running avg depth */ > > static HANDLE ctr_freq_timer = INVALID_HANDLE_VALUE; > static ULONGLONG tune_ctr_freq_max_interval; > static unsigned tune_ctr_period; > void start_ctr_freq_timer(ULONGLONG now_time); > void reset_ctr_freq_timer(ULONGLONG when, ULONGLONG now); > void reset_ctr_freq_timer_abs(ULONGLONG when); > > /* round a Windows time to the next bottom of the second */ > > #define ROUND_TO_NEXT_SEC_BOTTOM(t) \ > do { \ > (t) += 3 * HECTONANOSECONDS / 2 - 1; \ > (t) /= HECTONANOSECONDS; \ > (t) *= HECTONANOSECONDS; \ > (t) -= HECTONANOSECONDS / 2; \ > } while (0) > > /* there must be a better place for this */ > #define COUNTOF(arr) (sizeof(arr) / sizeof((arr)[0])) > > /* > * NT native time format is 100's of nanoseconds since 1601-01-01. > * Helpers for converting between "hectonanoseconds" and the > * performance counter scale from which interpolated time is > * derived. > */ > #define HNS2PERF(hns) ((hns) * PerfCtrFreq / HECTONANOSECONDS) > #define PERF2HNS(ctr) ((ctr) * HECTONANOSECONDS / PerfCtrFreq) > > > #if defined(_MSC_VER) && _MSC_VER >= 1400 /* VS 2005 */ > #define get_pcc() __rdtsc() > #else > /* > * something like this can be used for a compiler without __rdtsc() > */ > ULONGLONG __forceinline > get_pcc(void) > { > /* RDTSC returns in EDX:EAX, same as C compiler */ > __asm { > RDTSC > } > } > #endif > > /* > * perf_ctr() returns the current performance counter value, > * from QueryPerformanceCounter or RDTSC. > */ > > ULONGLONG WINAPI > perf_ctr(void) > { > FT_ULL ft1; > > if (1 == use_pcc) { > return get_pcc(); > } else if (0 == use_pcc) { > QueryPerformanceCounter(&ft1.li); > return ft1.ull; > } else { > FT_ULL ft2; > FT_ULL ft3; > FT_ULL ft4; > FT_ULL ft5; > LONGLONG offset; > char *ntpd_pcc_freq_text = getenv("NTPD_PCC_FREQ"); > > /* one-time initialization */ > #ifdef DEBUG > if (!NomPerfCtrFreq) { > msyslog(LOG_ERR, "NomPerfCtrFreq not initialized before first perf_ctr() call"); > exit(-1); > } > #endif > > QueryPerformanceCounter(&ft1.li); > ft2.ull = get_pcc(); > Sleep(1); > QueryPerformanceCounter(&ft3.li); > Sleep(1); > ft4.ull = get_pcc(); > Sleep(1); > QueryPerformanceCounter(&ft5.li); > > offset = ft2.ull - ft1.ull; > ft3.ull += offset; > ft5.ull += offset; > > if (ntpd_pcc_freq_text || > (ft2.ull <= ft3.ull && > ft3.ull <= ft4.ull && > ft4.ull <= ft5.ull)) { > > use_pcc = 1; > ft1.ull = ft2.ull; > QPC_offset = offset; > > if (ntpd_pcc_freq_text) > sscanf(ntpd_pcc_freq_text, > "%I64u", > &NomPerfCtrFreq); > > NLOG(NLOG_CLOCKINFO) > msyslog(LOG_INFO, > "using processor cycle counter " > "%.3f MHz", > NomPerfCtrFreq / 1e6); > } else { > use_pcc = 0; > } > > return ft1.ull; > } > } > > /* 119c300,302 < set_mm_timer(int timerres) --- > set_mm_timer( > int timerres > ) 122a306 > 135c319 < long dwTimeAdjustment; --- > long TimeAdjustment; 157,164c341,350 < /* dtemp is in micro seconds. NT uses 100 ns units, < * so a unit change in dwTimeAdjustment corresponds < * to slewing 10 ppm on a 100 Hz system. < * Calculate the number of 100ns units to add, < * using OS tick frequency as per suggestion from Harry Pyle, < * and leave the remainder in dtemp */ < dwTimeAdjustment = (DWORD)( dtemp / ppm_per_adjust_unit + (isneg ? -0.5 : 0.5)) ; < dtemp += (double) -dwTimeAdjustment * ppm_per_adjust_unit; --- > /* > * dtemp is in micro seconds. NT uses 100 ns units, > * so a unit change in TimeAdjustment corresponds > * to slewing 10 ppm on a 100 Hz system. Calculate > * the number of 100ns units to add, using OS tick > * frequency as per suggestion from Harry Pyle, > * and leave the remainder in dtemp > */ > TimeAdjustment = (long) (dtemp / ppm_per_adjust_unit + (isneg ? -0.5 : 0.5)); > dtemp -= (double) TimeAdjustment * ppm_per_adjust_unit; 167,169c353,357 < /* If a leap second is pending then determine the UTC time stamp < * of when the insertion must take place */ < if (leap_sec > 0) --- > /* > * If a leap second is pending then determine the UTC time stamp > * of when the insertion must take place > */ > if (leap_sec > 0) 173d360 < FT_ULL ft; 175d361 < int itmp; 177,178c363 < GetSystemTimeAsFileTime(&ft.ft); < FileTimeToSystemTime(&ft.ft, &st); --- > GetSystemTime(&st); 180c365,366 < /* Accept leap announcement only 1 month in advance, --- > /* > * Accept leap announcement only 1 month in advance, 185,186c371,374 < /* The comarison time stamp is computed according < * to 0:00h UTC of the following day */ --- > /* > * The comparison time stamp is computed according > * to 0:00h UTC of the following day > */ 200,203c388,392 < msyslog(LOG_INFO, "Detected positive leap second announcement " < "for %04d-%02d-%02d %02d:%02d:%02d UTC", < st.wYear, st.wMonth, st.wDay, < st.wHour, st.wMinute, st.wSecond); --- > msyslog(LOG_NOTICE, > "Detected positive leap second announcement " > "for %04d-%02d-%02d %02d:%02d:%02d UTC", > st.wYear, st.wMonth, st.wDay, > st.wHour, st.wMinute, st.wSecond); 206c395 < } --- > } 209,210c398,401 < /* If the time stamp for the next leap second has been set < * then check if the leap second must be handled */ --- > /* > * If the time stamp for the next leap second has been set > * then check if the leap second must be handled > */ 213c404 < LARGE_INTEGER this_perf_count; --- > ULONGLONG this_perf_count; 215c406 < QueryPerformanceCounter( &this_perf_count ); --- > this_perf_count = perf_ctr(); 224c415 < ls_time_adjustment = every / LS_CORR_INTV_SECS; --- > ls_time_adjustment = clockperiod / LS_CORR_INTV_SECS; 227c418 < msyslog(LOG_INFO, "Inserting positive leap second."); --- > msyslog(LOG_NOTICE, "Inserting positive leap second."); 232,233c423,424 < ls_elapsed = ( this_perf_count.QuadPart - ls_ref_perf_cnt.QuadPart ) < * HECTONANOSECONDS / PerfFrequency; --- > ls_elapsed = ( this_perf_count - ls_ref_perf_cnt ) > * HECTONANOSECONDS / PerfCtrFreq; 244,248c435,440 < /* NOTE: While the system time is slewed during the leap second < * the interpolation function which is based on the performance < * counter does not account for the slew. < */ < dwTimeAdjustment -= ls_time_adjustment; --- > /* > * NOTE: While the system time is slewed during the leap second > * the interpolation function which is based on the performance > * counter does not account for the slew. > */ > TimeAdjustment -= ls_time_adjustment; 254,261c446,449 < if (last_Adj != dwTimeAdjustment) { < last_Adj = dwTimeAdjustment; < # ifdef DEBUG < if (debug > 1) < printf("SetSystemTimeAdjustment( %ld) + (%ld)\n", dwTimeAdjustment, units_per_tick); < # endif < dwTimeAdjustment += units_per_tick; < rc = !SetSystemTimeAdjustment(dwTimeAdjustment, FALSE); --- > if (last_Adj != TimeAdjustment) { > last_Adj = TimeAdjustment; > DPRINTF(1, ("SetSystemTimeAdjustment(%+ld)\n", TimeAdjustment)); > rc = !SetSystemTimeAdjustment(clockperiod + TimeAdjustment, FALSE); 270c458 < sys_residual = dtemp / 1000000.0; --- > sys_residual = dtemp / 1e6; 273,276c461,463 < #ifdef DEBUG < if (debug > 6) < printf("adj_systime: adj %.9f -> remaining residual %.9f\n", now, sys_residual); < #endif --- > DPRINTF(6, ("adj_systime: adj %.9f -> remaining residual %.9f\n", > now, sys_residual)); > 281c468,469 < void init_winnt_time(void) --- > void > init_winnt_time(void) 283c471 < BOOL noslew; --- > char szMsgPath[MAX_PATH+1]; 285a474,482 > TIMECAPS tc; > BOOL noslew; > DWORD adjclockperiod; > LARGE_INTEGER Freq; > FT_ULL initial_hectonanosecs; > FT_ULL next_hectonanosecs; > > if (winnt_time_initialized) > return; 292a490,495 > /* Set up the Console Handler */ > if (!SetConsoleCtrlHandler(OnConsoleEvent, TRUE)) > { > msyslog(LOG_ERR, "Can't set console control handler: %m"); > } > 308c511 < /* get the current process token handle */ --- > /* get the current process token handle */ 315c518 < /* get the LUID for system-time privilege. */ --- > /* get the LUID for system-time privilege. */ 332,333c535,577 < /* Reset the Clock to a reasonable increment */ < if (!GetSystemTimeAdjustment(&initial_units_per_tick, &every,&noslew)) --- > CloseHandle(hToken); > hToken = INVALID_HANDLE_VALUE; > > /* > * ntpd on Windows has always raised its priority, without > * requiring -N as on Unix. Since Windows ntpd doesn't share > * the history of unix ntpd of once having no -N and therefore > * needing to be invoked under nice, there is no reason to > * bring it in line with the Unix version in this regard. > * Instsrv assumes ntpd is invoked with no arguments, and > * upgrading users would be negatively surprised by the > * poor timekeeping if they failed to add -N as part of > * upgrading were we to correct this platform difference. > */ > if (-1 == setpriority(PRIO_PROCESS, 0, NTP_PRIO)) > exit(-1); > > /* > * register with libntp ntp_set_tod() to call us back > * when time is stepped. > */ > step_callback = time_stepped; > > /* > * 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) 335c579 < msyslog(LOG_ERR, "GetSystemTimeAdjustment failed: %m\n"); --- > msyslog(LOG_ERR, "QueryPerformanceFrequency failed: %m\n"); 339c583,586 < units_per_tick = initial_units_per_tick; --- > NomPerfCtrFreq = PerfCtrFreq = Freq.QuadPart; > msyslog(LOG_INFO, > "Performance counter frequency %.3f MHz", > PerfCtrFreq / 1e6); 341,343c588,593 < /* Calculate the time adjustment resulting from incrementing < * units per tick by 1 unit for 1 second */ < ppm_per_adjust_unit = 1000000.0 / (double) every; --- > /* Determine the existing system time slewing */ > if (!GetSystemTimeAdjustment(&adjclockperiod, &clockperiod, &noslew)) > { > msyslog(LOG_ERR, "GetSystemTimeAdjustment failed: %m\n"); > exit(-1); > } 345,349c595,611 < #ifdef DEBUG < msyslog(LOG_INFO, "Initial Clock increment %7.1f us", < (float) (units_per_tick / 10)); < msyslog(LOG_INFO, "Adjustment rate %5.3f ppm/s", ppm_per_adjust_unit); < #endif --- > /* > * If there is no slewing before ntpd, adjclockperiod and clockperiod > * will be equal. Any difference is carried into adj_systime's first > * pass as the previous adjustment. > */ > last_Adj = adjclockperiod - clockperiod; > > if (last_Adj) > msyslog(LOG_INFO, > "Clock interrupt period %.3f msec " > "(startup slew %.1f usec/period)", > clockperiod / 1e4, > last_Adj / 10.); > else > msyslog(LOG_INFO, > "Clock interrupt period %.3f msec", > clockperiod / 1e4); 351c613,617 < StartClockThread(); --- > /* > * Calculate the time adjustment resulting from incrementing > * units per tick by 1 unit for 1 second > */ > ppm_per_adjust_unit = 1e6 / clockperiod; 353,356c619,644 < /* Set up the Console Handler */ < if (!SetConsoleCtrlHandler(OnConsoleEvent, TRUE)) < { < msyslog(LOG_ERR, "Can't set console control handler: %m"); --- > /* > * Spin on GetSystemTimeAsFileTime to determine its > * granularity. Prior to Windows Vista this is > * typically the same as the clock period. > */ > GetSystemTimeAsFileTime(&initial_hectonanosecs.ft); > do { > GetSystemTimeAsFileTime(&next_hectonanosecs.ft); > } while (initial_hectonanosecs.ull == next_hectonanosecs.ull); > > os_clock_precision = next_hectonanosecs.ull - > initial_hectonanosecs.ull; > > msyslog(LOG_INFO, > "Windows clock precision %.3f msec, min. slew %.3f ppm/s", > os_clock_precision / 1e4, > ppm_per_adjust_unit); > > winnt_time_initialized = TRUE; > > if (os_clock_precision < 4 * 10000 && !getenv("NTPD_USE_INTERP_DANGEROUS")) { > msyslog(LOG_INFO, "using Windows clock directly"); > } else { > winnt_use_interpolation = TRUE; > get_sys_time_as_filetime = GetInterpTimeAsFileTime; > StartClockThread(); 361c649,650 < void reset_winnt_time(void) --- > void > atexit_revert_mm_timer(void) 363,372c652,683 < /* restore the clock frequency back to its original value */ < if (!SetSystemTimeAdjustment(0, TRUE)) < { < msyslog(LOG_ERR, "Failed to reset clock state, SetSystemTimeAdjustment(): %m"); < } < /* read the current system time, and write it back to < force CMOS update: */ < /************ Added back in 2003-01-26 *****************/ < { < SYSTEMTIME st; --- > timeEndPeriod(wTimerRes); > DPRINTF(1, ("MM timer resolution reset\n")); > } > > > void > reset_winnt_time(void) > { > SYSTEMTIME st; > > /* > * If we're in the 2-second slew right after a leap second, > * we don't want to continue that extreme slew, in that case > * disable our slewing and return clock discipline to the > * kernel. Similarly if we are not yet synchronized, > * our current slew may not be a good ongoing trim. > * Otherwise, our leave in place the last SetSystemTimeAdjustment > * as an ongoing frequency correction, better than nothing. > * TODO: > * Verify this will not call SetSystemTimeAdjustment if > * ntpd is running in ntpdate mode. > */ > if (sys_leap == LEAP_NOTINSYNC || ls_time_adjustment) > SetSystemTimeAdjustment(0, TRUE); > > /* > * Read the current system time, and write it back to > * force CMOS update, only if we are exiting because > * the computer is shutting down and we are already > * synchronized. > */ > if (ntservice_systemisshuttingdown() && sys_leap != LEAP_NOTINSYNC) { 374a686,687 > NLOG(NLOG_SYSEVENT | NLOG_CLOCKINFO) > msyslog(LOG_NOTICE, "system is shutting down, CMOS time reset."); 378a692,694 > /* > * GetSystemTimeAsFileTime() interface clone is used by getclock() in ntpd. > */ 380,382c696,698 < int < gettimeofday( < struct timeval *tv --- > void WINAPI > GetInterpTimeAsFileTime( > LPFILETIME pft 385,395c701,702 < /* Use the system time (roughly synchronised to the tick, and < * extrapolated using the system performance counter. < */ < < ULONGLONG Count; < LARGE_INTEGER LargeIntNowCount; < ULONGLONG Time; < ULONGLONG NowCount; < ULONGLONG PreCount; /*FIX*/ < LONGLONG TicksElapsed; < LONG time_adjustment; --- > FT_ULL now_time; > FT_ULL now_count; 399c706 < */ --- > */ 401,406c708,709 < PreCount = LastTimerCount; /*FIX*/ < < if (!QueryPerformanceCounter(&LargeIntNowCount)) { < msyslog(LOG_ERR, "QueryPeformanceCounter failed: %m"); < exit(1); < } --- > now_count.ull = perf_ctr(); > now_time.ull = interp_time(now_count.ull, TRUE); 408c711 < NowCount = LargeIntNowCount.QuadPart; --- > if (last_interp_time > now_time.ull) { 410,415c713,718 < /* Get base time we are going to extrapolate from < */ < EnterCriticalSection(&TimerCritialSection); < Count = LastTimerCount; < Time = LastTimerTime; < LeaveCriticalSection(&TimerCritialSection); --- > clock_backward_count++; > if (last_interp_time - now_time.ull > clock_backward_max) > clock_backward_max = last_interp_time - now_time.ull; > now_time.ull = last_interp_time; > } else > last_interp_time = now_time.ull; 417,453c720,721 < /* Calculate when now is. < * < * Result = LastTimerTime + (NowCount - LastTimerCount) / PerfFrequency < */ < < if (NowCount >= Count) < { < TicksElapsed = NowCount - Count; /* linear progression of ticks */ < } < else < { < /************************************************************************/ < /* Differentiate between real rollover and the case of taking a */ < /* perfcount then the APC coming in. */ < /************************************************************************/ < if (Count > PreCount) /*FIX*/ < { /*FIX*/ < TicksElapsed = 0; /*FIX*/ < } /*FIX*/ < else /*FIX*/ < { /*FIX*/ < TicksElapsed = NowCount + (RollOverCount - Count); /*FIX*/ < } /*FIX*/ < } < < /* Calculate the new time (in 100's of nano-seconds) < */ < time_adjustment = (long) ((TicksElapsed * HECTONANOSECONDS) / PerfFrequency); < Time += time_adjustment; < < /* Convert the hecto-nano second time to tv format < */ < Time -= FILETIME_1970; < tv->tv_sec = (LONG) ( Time / 10000000ui64); < tv->tv_usec = (LONG) (( Time % 10000000ui64) / 10); < < return 0; --- > *pft = now_time.ft; > return; 455a724,730 > > /* > * TimerApcFunction is invoked on the high-priority clock > * thread to capture a new baseline system time and > * performance counter correlation every 43 msec (64Hz > * OS clock precision). > */ 463,464c738,741 < LARGE_INTEGER LargeIntNowCount; < (void) lpArgToCompletionRoutine; /* not used */ --- > static BOOL ctr_freq_timer_started = FALSE; > static ULONGLONG prev_count; > ULONGLONG now_time; > FT_ULL now_count; 466,467d742 < if (dwTimerLowValue == lastLowTimer) return; < 469c744 < QueryPerformanceCounter(&LargeIntNowCount); --- > now_count.ull = perf_ctr(); 471,472c746,747 < /* Save this for next time */ < lastLowTimer = dwTimerLowValue; --- > now_time = (((ULONGLONG)dwTimerHighValue << 32) | > dwTimerLowValue); 474,475c749,752 < /* Check to see if the counter has rolled. This happens < more often on Multi-CPU systems */ --- > /* > * Save this correlation in the history. > */ > add_counter_time_pair(now_count.ull, now_time); 477,488c754,759 < if ((ULONGLONG) LargeIntNowCount.QuadPart < LastTimerCount) { < /* Counter Rolled - try and estimate the rollover point using < the nominal counter frequency divided by an estimate of the < OS frequency */ < RollOverCount = LastTimerCount + PerfFrequency * every / HECTONANOSECONDS - < (ULONGLONG) LargeIntNowCount.QuadPart; < #ifdef DEBUG < msyslog(LOG_INFO, < "Performance Counter Rollover %I64u:\rLast Timer Count %I64u\rCurrent Count %I64u", < RollOverCount, LastTimerCount, LargeIntNowCount.QuadPart); < #endif < } --- > /* > * Once we're synchronized start the counter frequency > * tuning timer. > */ > if (INVALID_HANDLE_VALUE == ctr_freq_timer && > LEAP_NOTINSYNC != sys_leap) 490,498c761 < /* Now we can hang out and wait for the critical section to free up; < we will get the CPU this timeslice. Meanwhile other tasks can use < the last value of LastTimerCount */ < < EnterCriticalSection(&TimerCritialSection); < LastTimerCount = (ULONGLONG) LargeIntNowCount.QuadPart; < LastTimerTime = ((ULONGLONG) dwTimerHighValue << 32) + < (ULONGLONG) dwTimerLowValue; < LeaveCriticalSection(&TimerCritialSection); --- > start_ctr_freq_timer(now_time); 502,503c765,768 < < DWORD WINAPI ClockThread(void *arg) --- > unsigned WINAPI > ClockThread( > void *arg > ) 504a770,831 > LARGE_INTEGER DueTime; > HANDLE timer; > double HZ; > double TimerHz; > DWORD timer_period_msec; > DWORD res; > char *ntpd_int_int_text; > > UNUSED_ARG(arg); > > timer = CreateWaitableTimer(NULL, FALSE, NULL); > > ntpd_int_int_text = getenv("NTPD_INT_INT"); > > HZ = (double)HECTONANOSECONDS / clockperiod; > > if (HZ > 63 && HZ < 65) { > timer_period_msec = 43; > } else if (HZ > 98 && HZ < 102) { > timer_period_msec = 27; > if (!ntpd_int_int_text) > msyslog(LOG_WARNING, > "%.3f Hz system clock may benefit from " > "custom NTPD_INT_INT env var timer interval " > "override between approx. 20 and 50 msecs.", > HZ); > } else { > timer_period_msec = (DWORD)(0.5 + (2.752 * clockperiod / 10000)); > if (!ntpd_int_int_text) > msyslog(LOG_WARNING, > "unfamiliar %.3f Hz system clock may benefit " > "from custom NTPD_INT_INT env var timer " > "interval override between approx. 20 and 50 " > "msecs.", > HZ); > } > > if (ntpd_int_int_text) { > timer_period_msec = atoi(ntpd_int_int_text); > timer_period_msec = max(9, timer_period_msec); > msyslog(LOG_NOTICE, > "using NTPD_INT_INT env var override %u", > timer_period_msec); > } > > TimerHz = 1e3 / timer_period_msec; > msyslog(LOG_NOTICE, "HZ %.3f using %u msec timer %.3f Hz %d deep", > HZ, > timer_period_msec, > TimerHz, > BASELINES_USED); > > /* negative DueTime means relative to now */ > DueTime.QuadPart = -(int)timer_period_msec; > > SetWaitableTimer( > timer, > &DueTime, /* first fire */ > timer_period_msec, /* period thereafter */ > TimerApcFunction, /* callback routine */ > &timer, /* context for callback */ > FALSE); /* do not interfere with power saving */ 506,521c833,851 < LARGE_INTEGER DueTime; < HANDLE WaitableTimerHandle = CreateWaitableTimer(NULL, FALSE, NULL); < < (void) arg; /* not used */ < < if (WaitableTimerHandle != NULL) { < DueTime.QuadPart = 0i64; < if (SetWaitableTimer(WaitableTimerHandle, &DueTime, 1L /* ms */, TimerApcFunction, &WaitableTimerHandle, FALSE) != NO_ERROR) { < for(;;) { < if (WaitForSingleObjectEx(TimerThreadExitRequest, INFINITE, TRUE) == WAIT_OBJECT_0) { < break; /* we've been asked to exit */ < } < } < } < CloseHandle(WaitableTimerHandle); < WaitableTimerHandle = NULL; --- > /* > * The clock thread spends the rest of its life in the TimerApcFunction > * and ctr_freq_timer_fired timer APC callbacks, which can only occur > * while this thread is in an alertable wait. Note the Ex on > * WaitForSingleObjectEx and TRUE for fAlertable. The wait will return > * after each APC callback in which case we simply wait again. We will > * break out of the loop when StopClockThread signals our exit event. > */ > do res = WaitForSingleObjectEx( > TimerThreadExitRequest, > INFINITE, > TRUE); > while (WAIT_OBJECT_0 != res); > > CloseHandle(timer); > > if (ctr_freq_timer != INVALID_HANDLE_VALUE) { > CloseHandle(ctr_freq_timer); > ctr_freq_timer = INVALID_HANDLE_VALUE; 522a853 > 527c858,859 < static void StartClockThread(void) --- > static void > StartClockThread(void) 529,558c861,862 < DWORD tid; < FILETIME StartTime; < LARGE_INTEGER Freq = { 0, 0 }; < < /* get the performance counter freq */ < if (!QueryPerformanceFrequency(&Freq)) < { < msyslog(LOG_ERR, "QueryPerformanceFrequency failed: %m\n"); < exit (-1); < } < < PerfFrequency = Freq.QuadPart; < < < if ( modify_mm_timer != 0) < { < if (timeGetDevCaps( &tc, sizeof( tc ) ) == TIMERR_NOERROR ) < { < wTimerRes = min( max( tc.wPeriodMin, MM_TIMER_INTV ), tc.wPeriodMax ); < < timeBeginPeriod( wTimerRes ); < #ifdef DEBUG < msyslog( LOG_INFO, "MM timer resolution: %u..%u ms, set to %u ms\n", < tc.wPeriodMin, tc.wPeriodMax, wTimerRes ); < #endif < } < else < msyslog( LOG_ERR, "Failed to get MM timer caps\n" ); < } < --- > static BOOL done_once = FALSE; > FT_ULL StartTime; 561,563c865,867 < GetSystemTimeAsFileTime(&StartTime); < LastTimerTime = (((ULONGLONG) StartTime.dwHighDateTime) << 32) + < (ULONGLONG) StartTime.dwLowDateTime; --- > GetSystemTimeAsFileTime(&StartTime.ft); > baseline_times[0] = StartTime.ull; > baseline_counts[0] = perf_ctr(); 566,567c870 < InitializeCriticalSection(&TimerCritialSection); < TimerThreadExitRequest = CreateEvent(NULL, FALSE, FALSE, "TimerThreadExitRequest"); --- > TimerThreadExitRequest = CreateEvent(NULL, FALSE, FALSE, NULL); 569,570c872,879 < ClockThreadHandle = CreateThread(NULL, 0, ClockThread, NULL, < CREATE_SUSPENDED, &tid); --- > clock_thread = > (HANDLE)_beginthreadex( > NULL, > 0, > ClockThread, > NULL, > CREATE_SUSPENDED, > &clock_thread_id); 572c881 < if (ClockThreadHandle != NULL) { --- > if (clock_thread != NULL) { 574c883 < if (!SetThreadPriority(ClockThreadHandle, THREAD_PRIORITY_TIME_CRITICAL)) { --- > if (!SetThreadPriority(clock_thread, THREAD_PRIORITY_TIME_CRITICAL)) { 578,579c887,888 < lock_thread_to_processor(ClockThreadHandle); < ResumeThread(ClockThreadHandle); --- > lock_thread_to_processor(clock_thread); > ResumeThread(clock_thread); 581c890,894 < lock_thread_to_processor(GetCurrentThread()); --- > if (FALSE == done_once) { > done_once = TRUE; > lock_thread_to_processor(GetCurrentThread()); > atexit( StopClockThread ); > } 583c896,901 < atexit( StopClockThread ); --- > /* > * Give the clock thread time to fill its counter/time > * sample buffer. This will underfill the buffer a > * bit for sample periods over 43 msec. > */ > Sleep(BASELINES_USED * 43); 587a906,929 > void > StopClockThread(void) > { > /* > * if the clock thread exit()s this routine > * will be called on the clock thread and > * we need not (and can't) use the normal > * TimerThreadExitRequest event. > */ > if (GetCurrentThreadId() != clock_thread_id) { > > if (!SetEvent(TimerThreadExitRequest) || > WaitForSingleObject(clock_thread, 2 * 1000) != > WAIT_OBJECT_0) { > msyslog(LOG_ERR, "Failed to stop clock thread."); > } > } > CloseHandle(TimerThreadExitRequest); > TimerThreadExitRequest = NULL; > CloseHandle(clock_thread); > clock_thread = NULL; > } > > 596a939,958 > if ( ! winnt_time_initialized) { > DPRINTF(1, ("init_winnt_time() must be called before " > "lock_thread_to_processor(), exiting\n")); > exit(-1); > } > > if ( ! winnt_use_interpolation) > return; > > if (-1 == use_pcc) { > DPRINTF(1, ("perf_ctr is not called before affinity, " > "change lock_thread_to_processor to call it\n")); > exit(-1); > } else if (0 == use_pcc) > return; > > /* > * Calculate the ThreadAffinityMask we'll use once on the > * first invocation. > */ 597a960 > 638c1001 < !(ThreadAffinityMask & ProcessAffinityMask)) { --- > !(ThreadAffinityMask & ProcessAffinityMask)) 644c1007 < } else { --- > else 648d1010 < } 654,657c1016,1090 < !SetThreadAffinityMask(thread, ThreadAffinityMask)) { < < DPRINTF(1, ("Unable to wire thread to mask %x: %s\n", < ThreadAffinityMask, strerror(GetLastError()))); --- > !SetThreadAffinityMask(thread, ThreadAffinityMask)) > > msyslog(LOG_ERR, > "Unable to wire thread to mask %x: %m\n", > ThreadAffinityMask); > } > > > #ifdef HAVE_PPSAPI > /* > * helper routine for serial PPS which returns QueryPerformanceCounter > * timestamp and needs to interpolate it to an NTP timestamp. > */ > void > pps_ntp_timestamp_from_counter( > ntp_fp_t *result, > ULONGLONG Timestamp, > ULONGLONG Counterstamp > ) > { > /* > * convert between equivalent l_fp and PPSAPI ntp_fp_t > */ > ntp_timestamp_from_counter( > (l_fp *)result, > Timestamp, > Counterstamp); > } > > > void > ntp_timestamp_from_counter( > l_fp *result, > ULONGLONG Timestamp, > ULONGLONG Counterstamp > ) > { > #ifdef DEBUG > FT_ULL Now; > #endif > ULONGLONG InterpTimestamp; > > if (winnt_use_interpolation) { > InterpTimestamp = interp_time(Counterstamp + QPC_offset, FALSE); > > #ifdef DEBUG > /* sanity check timestamp is within 1 minute of now */ > GetSystemTimeAsFileTime(&Now.ft); > Now.ll -= InterpTimestamp; > if (Now.ll > 60 * HECTONANOSECONDS || > Now.ll < -60 * (LONGLONG) HECTONANOSECONDS) { > DPRINTF(1, ("ntp_timestamp_from_counter interpolated " > "time %.6fs from current\n", > Now.ll / (double) HECTONANOSECONDS)); > DPRINTF(1, ("interpol time %llx from %llx\n", > InterpTimestamp, > Counterstamp)); > exit(-1); > } > #endif > } else { /* ! winnt_use_interpolation */ > /* have to simply use the driver's system time timestamp */ > InterpTimestamp = Timestamp; > #ifdef DEBUG > /* sanity check timestamp is within 1 minute of now */ > GetSystemTimeAsFileTime(&Now.ft); > Now.ll -= InterpTimestamp; > if (Now.ll > 60 * HECTONANOSECONDS || > Now.ll < -60 * (LONGLONG) HECTONANOSECONDS) { > DPRINTF(1, ("ntp_timestamp_from_counter serial driver system " > "time %.6fs from current\n", > Now.ll / (double) HECTONANOSECONDS)); > exit(-1); > } > #endif 658a1092,1098 > > /* convert from 100ns units to NTP fixed point format */ > > InterpTimestamp -= FILETIME_1970; > result->l_ui = JAN_1970 + (u_int32)(InterpTimestamp / HECTONANOSECONDS); > result->l_uf = (u_int32)((InterpTimestamp % HECTONANOSECONDS) * > (FRAC / HECTONANOSECONDS)); 659a1100 > #endif /* HAVE_PPSAPI */ 662,667c1103,1354 < static void StopClockThread(void) < { < if ( wTimerRes ) /* if not 0 then the MM timer has been modified at startup */ < { < timeEndPeriod( wTimerRes ); < wTimerRes = 0; --- > void > time_stepped(void) > { > /* > * called back by ntp_set_tod after the system > * time has been stepped (set). > * > * We normally prevent the reported time from going backwards > * but need to allow it in this case. > */ > if (FALSE == winnt_use_interpolation) > return; > > > /* > * Restart the clock thread to get a new baseline > * time/counter correlation. > */ > StopClockThread(); > > /* > * newest_baseline_gen is a generation counter > * incremented once each time newest_baseline > * is reset. > */ > newest_baseline_gen++; > > last_interp_time = > clock_backward_max = > clock_backward_count = > newest_baseline = 0; > > memset(baseline_counts, 0, sizeof(baseline_counts)); > memset(baseline_times, 0, sizeof(baseline_times)); > > StartClockThread(); > } > > > /* > * log2ull - log base 2 of a unsigned 64-bit number > */ > int > log2ull( > ULONGLONG n > ) > { > const ULONGLONG one = 1; > int log = 0; > > if (n >= one<<32) { n >>= 32; log += 32; } > if (n >= one<<16) { n >>= 16; log += 16; } > if (n >= one<< 8) { n >>= 8; log += 8; } > if (n >= one<< 4) { n >>= 4; log += 4; } > if (n >= one<< 2) { n >>= 2; log += 2; } > if (n >= one<< 1) { log += 1; } > > return (n) ? log : (-1); > } > > > /* > * ctr_freq_timer_fired is called once a few seconds before > * tune_ctr_period seconds have elapsed, to reset the timer > * and hopefully minimize error due to the system using the > * nominal performance counter frequency to set the timer > * internally, which is typically dozens of PPM from the > * actual performance counter rate. A few seconds later > * it is called again to observe the counter and estimate the > * counter frequency. > */ > static void CALLBACK > ctr_freq_timer_fired( > LPVOID arg, > DWORD dwTimeLow, > DWORD dwTimeHigh > ) > { > static FT_ULL begin_time = {0}; > static FT_ULL begin_count = {0}; > static ULONGLONG next_period_time = 0; > static ULONGLONG report_systemtime = 0; > FT_ULL now_time; > FT_ULL now_count; > > if (!begin_time.ull) { > begin_count.ull = perf_ctr(); > begin_time.ft.dwLowDateTime = dwTimeLow; > begin_time.ft.dwHighDateTime = dwTimeHigh; > > /* > * adapt perf ctr observation interval to the > * counter frequency > */ > tune_ctr_period = 22680 / log2ull(NomPerfCtrFreq); > > /* > * reset timer 2s before period ends to minimize > * error from OS timer routines using nominal > * performance frequency internally. > */ > tune_ctr_freq_max_interval = tune_ctr_period - 2; > > next_period_time = begin_time.ull + > (ULONGLONG)tune_ctr_period * HECTONANOSECONDS; > > ROUND_TO_NEXT_SEC_BOTTOM(next_period_time); > > reset_ctr_freq_timer(next_period_time, begin_time.ull); > > return; > } > > now_time.ft.dwLowDateTime = dwTimeLow; > now_time.ft.dwHighDateTime = dwTimeHigh; > > if (now_time.ull >= next_period_time) { > > now_count.ull = perf_ctr(); > tune_ctr_freq( > now_count.ull - begin_count.ull, > now_time.ull - begin_time.ull); > > next_period_time += (ULONGLONG)tune_ctr_period * HECTONANOSECONDS; > begin_count.ull = now_count.ull; > begin_time.ull = now_time.ull; > } > > /* > * Log clock backward events no more often than 5 minutes. > */ > if (!report_systemtime) > > report_systemtime = now_time.ull + > 5 * 60 * HECTONANOSECONDS; > > else if (report_systemtime <= now_time.ull) { > > report_systemtime += 5 * 60 * HECTONANOSECONDS; > > if (clock_backward_count) { > msyslog(LOG_WARNING, > "clock would have gone backward %d times, " > "max %.1f usec", > clock_backward_count, > clock_backward_max / 10.); > > clock_backward_max = clock_backward_count = 0; > } > } > > reset_ctr_freq_timer(next_period_time, now_time.ull); > } > > > void > reset_ctr_freq_timer_abs( > ULONGLONG when > ) > { > FT_ULL fire_time; > > fire_time.ull = when; > > SetWaitableTimer( > ctr_freq_timer, > &fire_time.li, /* first fire */ > 0, /* not periodic */ > ctr_freq_timer_fired, /* callback routine */ > NULL, /* context for callback */ > FALSE); /* do not interfere with power saving */ > } > > > void > reset_ctr_freq_timer( > ULONGLONG when, > ULONGLONG now > ) > { > if (when - now > > (tune_ctr_freq_max_interval * HECTONANOSECONDS + HECTONANOSECONDS)) > > when = now + tune_ctr_freq_max_interval * HECTONANOSECONDS; > > reset_ctr_freq_timer_abs(when); > } > > > void > start_ctr_freq_timer( > ULONGLONG now_time > ) > { > ULONGLONG when; > > ctr_freq_timer = CreateWaitableTimer(NULL, FALSE, NULL); > > when = now_time; > ROUND_TO_NEXT_SEC_BOTTOM(when); > > reset_ctr_freq_timer_abs(when); > } > > > /* > * tune_ctr_freq is called once per tune_ctr_period seconds > * with a counter difference and time difference. > */ > void > tune_ctr_freq( > LONGLONG ctr_delta, > LONGLONG time_delta > ) > { > static unsigned count = 0; > static unsigned dispcount = 0; > static unsigned report_at_count = 0; > static int disbelieved = 0; > static int i = 0; > static double nom_freq = 0; > static LONGLONG diffs[TUNE_CTR_DEPTH] = {0}; > static LONGLONG sum = 0; > > LONGLONG delta; > LONGLONG deltadiff; > ULONGLONG ObsPerfCtrFreq; > double obs_freq; > double this_freq; > int isneg; > > /* nom_freq is constant over the run */ > if (!report_at_count) { > report_at_count = 24 * 60 * 60 / tune_ctr_period; > nom_freq = NomPerfCtrFreq / 1e6; > } > > /* delta is the per-second observed frequency this time */ > delta = (LONGLONG)((double)ctr_delta * HECTONANOSECONDS / > time_delta); > > /* disbelieve any delta more than +/- 976 PPM from nominal */ > deltadiff = delta - NomPerfCtrFreq; > if (0 > deltadiff) { > isneg = 1; > deltadiff = -deltadiff; > } else > isneg = 0; > > if ((ULONGLONG)deltadiff > (NomPerfCtrFreq / 1024)) { > disbelieved++; > dispcount++; 669c1356,1359 < msyslog( LOG_INFO, "MM timer set to default\n" ); --- > msyslog(LOG_DEBUG, "ctr delta %s%lld exceeds limit %llu", > (isneg) ? "-" : "", > deltadiff, > NomPerfCtrFreq / 1024); 670a1361,1425 > } else { > > /* > * collect average over TUNE_CTR_DEPTH samples > * for our PerfCtrFreq trimming. > */ > > if (isneg) > deltadiff = -deltadiff; > sum -= diffs[i]; > diffs[i] = deltadiff; > sum += deltadiff; > i = (i + 1) % COUNTOF(diffs); > count++; > dispcount++; > } > > this_freq = delta / 1e6; > > ObsPerfCtrFreq = NomPerfCtrFreq + (sum / COUNTOF(diffs)); > > #if 1 /* #if 0 to disable changing freq used */ > /* get rid of ObsPerfCtrFreq when removing the #ifdef */ > PerfCtrFreq = ObsPerfCtrFreq; > #endif > obs_freq = ObsPerfCtrFreq / 1e6; > > /* > * report observed ctr freq each time the estimate used during > * startup moves toward the observed freq from the nominal, > * and once a day afterward. > */ > > if (count > COUNTOF(diffs) && > /* (count % COUNTOF(diffs)) && */ /* enables reporting each */ > dispcount < report_at_count) /* TUNE_CTR_DEPTH samples */ > return; > > NLOG(NLOG_CLOCKINFO) > if (count <= COUNTOF(diffs)) > /* moving to observed freq. from nominal (startup) */ > msyslog(LOG_INFO, > (obs_freq > 100) > ? "ctr %.3f MHz %+6.2f PPM using " > "%.3f MHz %+6.2f PPM" > : "ctr %.6f MHz %+6.2f PPM using " > "%.6f MHz %+6.2f PPM", > this_freq, > 1e6 * (this_freq - nom_freq) / nom_freq, > obs_freq, > 1e6 * (obs_freq - nom_freq) / nom_freq); > else > /* steady state */ > msyslog(LOG_INFO, > (obs_freq > 100) > ? "ctr %.3f MHz %+.2f PPM" > : "ctr %.6f MHz %+.2f PPM", > obs_freq, > 1e6 * (obs_freq - nom_freq) / nom_freq); > > if (disbelieved) { > msyslog(LOG_ERR, > "%d ctr samples exceed +/- 976 PPM range gate", > disbelieved); > disbelieved = 0; 673,677c1428,1445 < if (SetEvent(TimerThreadExitRequest) && < WaitForSingleObject(ClockThreadHandle, 10000L) == 0) < { < CloseHandle(TimerThreadExitRequest); < TimerThreadExitRequest = NULL; --- > dispcount = 0; > } > > > /* > * add_counter_time_pair is called by the > * high priority clock thread with each new > * baseline counter/time correlation. > */ > void > add_counter_time_pair( > ULONGLONG ctr, > LONGLONG time > ) > { > int i; > > i = (newest_baseline + 1) % BASELINES_TOT; 679,680c1447,1448 < CloseHandle(ClockThreadHandle); < ClockThreadHandle = NULL; --- > baseline_counts[i] = ctr; > baseline_times[i] = time; 682c1450,1493 < DeleteCriticalSection(&TimerCritialSection); --- > newest_baseline = i; > } > > > /* > * interp_time estimates NT time in 100ns units > * based on a performance counter value given. > * This must tolerate recent historical counters > * as well as current. When current is FALSE > * we can't assume ctr is the latest/highest > * seen. > */ > ULONGLONG > interp_time( > ULONGLONG ctr, > BOOL current > ) > { > static __declspec(thread) int last_newest = -1; > static __declspec(thread) int last_newest_gen; > static __declspec(thread) int best_index; > ULONGLONG this_ctr; > LONGLONG this_time; > LONGLONG latest_time; > LONGLONG ctr_diff; > int i; > int i_gen; > int c; > > /* > * Use the system time (roughly synchronised to the tick, and > * extrapolated using the system performance counter. > * > * Cache the results per thread and only repeat the > * calculation when new data has arrived. > */ > i = newest_baseline; > i_gen = newest_baseline_gen; > > if (last_newest == i && last_newest_gen == i_gen) { > this_time = baseline_times[best_index]; > ctr_diff = ctr - baseline_counts[best_index]; > this_time += (LONGLONG)PERF2HNS((double)ctr_diff); > return this_time; 684,687c1495,1533 < else < { < msyslog(LOG_ERR, "Failed to stop clock thread."); < Sleep( 100 ); --- > > last_newest = i; > last_newest_gen = i_gen; > > latest_time = 0; > > /* > * Run through the history calculating the interpolated > * time based on each counter/time correlation in turn, > * and believe the latest one. This is akin to the NTP > * protocol minimum delay clock filter. Errors due to > * counter/time correlations with stale time are all > * negative. > */ > for (c = 0; c < BASELINES_USED; c++) { > if (baseline_times[i]) { > this_time = baseline_times[i]; > this_ctr = baseline_counts[i]; > > ctr_diff = ctr - this_ctr; > > if (current && ctr_diff < 0) { > /* > * The performance counter apparently went > * backwards without rolling over. It might > * be nice to complain but we don't want > * to do it repeatedly. > */ > ctr_diff = 0; > } > > this_time += (LONGLONG)PERF2HNS((double)ctr_diff); > > if (this_time > latest_time) { > latest_time = this_time; > best_index = i; > } > } > i = i ? (i - 1) : (BASELINES_TOT - 1); 688a1535,1536 > > return latest_time; diff -Nr a/ports/winnt/ntpd/ntp_iocompletionport.c b/ports/winnt/ntpd/ntp_iocompletionport.c 19a20 > #include "clockstuff.h" 57,59d57 < /* in nt_clockstuff.c */ < extern void lock_thread_to_processor(HANDLE); < 160c158 < /* UNUSED_ARG(NotUsed); */ --- > UNUSED_ARG(NotUsed); 700c698 < /* UNUSED_ARG(Bytes); */ --- > UNUSED_ARG(Bytes); diff -Nr a/ports/winnt/ntpd/ntservice.c b/ports/winnt/ntpd/ntservice.c 33a34 > 37c38 < static char ConsoleTitle[128]; --- > static BOOL computer_shutting_down = FALSE; 43d43 < extern char *progname; 50c50 < void ServiceControl(DWORD dwCtrlCode); --- > void WINAPI ServiceControl(DWORD dwCtrlCode); 102c102 < exit(ntpdmain(argc, argv)); --- > rc = ntpdmain(argc, argv); 107c107 < { TEXT(NTP_DISPLAY_NAME), (LPSERVICE_MAIN_FUNCTION) service_main }, --- > { TEXT(NTP_DISPLAY_NAME), service_main }, 112,113c112,114 < if (!rc) { < progname = argv[0]; --- > if (rc) > rc = 0; > else { 116c117 < fprintf(stderr, "%s: unable to start as service, rc: %i\n\n", progname, rc); --- > fprintf(stderr, "%s: unable to start as service, rc: %i\n\n", argv[0], rc); 119d119 < exit(rc); 122c122 < exit(0); --- > return rc; 129a130,131 > char ConsoleTitle[256]; > 133c135 < (LPHANDLER_FUNCTION)ServiceControl); --- > ServiceControl); 137d138 < UpdateSCM(SERVICE_STOPPED); 148a150 > 156,159c158,161 < /* service_ctrl - control handler for NTP service < * signals the service_main routine of start/stop requests < * from the control panel or other applications making < * win32API calls --- > > /* > * Routine to check if the service is stopping > * because the computer is shutting down 160a163,167 > BOOL > ntservice_systemisshuttingdown() { > return computer_shutting_down; > } > 164,171d170 < < if (!foreground) { /* did not become a service, simply exit */ < /* service mode, need to have the service_main routine < * register with the service control manager that the < * service has stopped running, before exiting < */ < UpdateSCM(SERVICE_STOPPED); < } 181a181,188 > > if (!foreground) { > /* service mode, need to have the service_main routine > * register with the service control manager that the > * service has stopped running, before exiting > */ > UpdateSCM(SERVICE_STOPPED); > } 188c195 < void --- > void WINAPI 195a203,205 > computer_shutting_down = TRUE; > /* fall through to stop case */ > 197d206 < UpdateSCM(SERVICE_STOP_PENDING); 199a209 > UpdateSCM(SERVICE_STOP_PENDING); 203c213 < --- > 234,237c244 < if (!SetServiceStatus(hServiceStatus, &ss)) { < ss.dwCurrentState = SERVICE_STOPPED; < SetServiceStatus(hServiceStatus, &ss); < } --- > SetServiceStatus(hServiceStatus, &ss); 250c257 < case CTRL_BREAK_EVENT : --- > case CTRL_BREAK_EVENT: 260,261c267,271 < printf("debug level %d\n", debug); < break ; --- > msyslog(LOG_DEBUG, "debug level %d", debug); > break; > #else > case CTRL_BREAK_EVENT: > break; 264,266c274,276 < case CTRL_C_EVENT : < case CTRL_CLOSE_EVENT : < case CTRL_SHUTDOWN_EVENT : --- > case CTRL_C_EVENT: > case CTRL_CLOSE_EVENT: > case CTRL_SHUTDOWN_EVENT: 271c281 < break; --- > break; 274,276c284,285 < return FALSE; < < --- > /* pass to next handler */ > return FALSE; 277a287,288 > > /* we've handled it, no more handlers should be called */ diff -Nr a/ports/winnt/ntpd/win32_io.c b/ports/winnt/ntpd/win32_io.c 17,28d16 < int NT_set_process_priority(void) < { < if (!SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS)) < { < msyslog(LOG_ERR, "SetPriorityClass: %m"); < return 0; < } < else < return 1; < } < < diff -Nr a/ports/winnt/ntpdate/ntpdate.vcproj b/ports/winnt/ntpdate/ntpdate.vcproj 244,265d243 < RelativePath="..\libntp\util_clockstuff.c" < > < < < < < < < < < < < < < < < < < < < < < < < < regedit /e %TEMP%\TZ-%GENERATED_PROGRAM%.TMP "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation" > IF NOT EXIST %TEMP%\TZ-%GENERATED_PROGRAM%.TMP GOTO NOTZINFO 136c136 < for /f "Tokens=1* Delims==" %%a in ('type %TEMP%\TZ.TMP') do if %%a == "ActiveTimeBias" SET ACTIVEBIAS=%%b --- > for /f "Tokens=1* Delims==" %%a in ('type %TEMP%\TZ-%GENERATED_PROGRAM%.TMP') do if %%a == "ActiveTimeBias" SET ACTIVEBIAS=%%b 140c140 < IF EXIST %TEMP%\TZ.TMP DEL %TEMP%\TZ.TMP --- > IF EXIST %TEMP%\TZ-%GENERATED_PROGRAM%.TMP DEL %TEMP%\TZ-%GENERATED_PROGRAM%.TMP diff -Nr a/util/ntp-keygen.c b/util/ntp-keygen.c 282d281 < #ifndef SYS_WINNT 284,286c283 < #else < gettimeofday(&tv); < #endif --- >