/* & it prescales by 32, thus 4 usec */
/* on mv167, granularity is 1usec anyway*/
/* To defeat rounding, set to 1 */
-#define USECS_PER_SEC 1000000L /* Microseconds per second */
+#define USECS_PER_SEC MILLION /* Microseconds per second */
#define TICK (((USECS_PER_SEC / CLKRATE) / CLK_GRANULARITY) * CLK_GRANULARITY)
/* emulate unix sleep
}
return 0;
}
-#endif
-
-#else /* SYS_WINNT */
-
-
-#include <time.h>
-#include <sys\timeb.h>
-#include "ntp_syslog.h"
-
-char * set_tod_using = "SetSystemTime";
-
-/* Windows NT versions of gettimeofday and settimeofday
- *
- * ftime() has internal DayLightSavings related BUGS
- * therefore switched to GetSystemTimeAsFileTime()
- */
-
-/* 100ns intervals between 1/1/1601 and 1/1/1970 as reported by
- * SystemTimeToFileTime()
- */
-
-#define FILETIME_1970 0x019db1ded53e8000
-#define HECTONANOSECONDS 10000000ui64
-
-static LONGLONG PerfFrequency = 0;
-static LONGLONG LastTimerCount = 0;
-static ULONGLONG LastTimerTime = 0;
-static CRITICAL_SECTION TimerCritialSection; /* lock for LastTimerCount & LastTimerTime */
-
-
-int
-gettimeofday(
- struct timeval *tv
- )
-{
- /* Use the system time (roughly synchronised to the tick, and
- * extrapolated using the system performance counter.
- */
-
- ULONGLONG Count;
- ULONGLONG Time;
- LARGE_INTEGER LargeIntNowCount;
- ULONGLONG NowCount;
- ULONGLONG TicksElapsed;
-
- /* Mark a mark ASAP. The latency to here should
- * be reasonably deterministic
- */
- if (!QueryPerformanceCounter(&LargeIntNowCount)) {
- msyslog(LOG_ERR, "QueryPeformanceCounter failed: %m");
- exit(1);
- }
- NowCount = LargeIntNowCount.QuadPart;
-
- /* Get base time we are going to extrapolate from
- */
- EnterCriticalSection(&TimerCritialSection);
- {
- Count = LastTimerCount;
- Time = LastTimerTime;
- }
- LeaveCriticalSection(&TimerCritialSection);
-
- printf ("Count %I64d\n", Count);
-
- /* Caclulate when now is.
- *
- * Result = LastTimerTime + (NowCount - LastTimerCount) / PerfFrequency
- */
- if (NowCount >= Count) {
- TicksElapsed = NowCount - Count; /* linear progression of ticks */
- }
- else {
- TicksElapsed = NowCount + 1 + ~Count; /* tick counter has wrapped around - I don't think this will ever happen*/
- }
-
- /* Calculate the new time (in 100's of nano-seconds)
- */
- Time += ((TicksElapsed * HECTONANOSECONDS) / PerfFrequency);
-
-
- /* 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;
-}
-
-
-static void CALLBACK
-TimerApcFunction(
- LPVOID lpArgToCompletionRoutine,
- DWORD dwTimerLowValue,
- DWORD dwTimerHighValue
- )
-{
- LARGE_INTEGER LargeIntNowCount;
- ULARGE_INTEGER Time;
- (void) lpArgToCompletionRoutine; /* not used */
-
- if (QueryPerformanceCounter(&LargeIntNowCount)) {
-
- /* Fill in the data
- */
- Time.u.LowPart = dwTimerLowValue;
- Time.u.HighPart = dwTimerHighValue;
-
- EnterCriticalSection(&TimerCritialSection);
- {
- LastTimerCount = LargeIntNowCount.QuadPart;
- LastTimerTime = Time.QuadPart;
- }
- LeaveCriticalSection(&TimerCritialSection);
- }
-}
-
-
-
+#endif /* SYS_CYGWIN32 */
-static HANDLE ClockThreadHandle = NULL;
-static HANDLE TimerThreadExitRequest = NULL;
-
-DWORD WINAPI ClockThread(void *arg)
-{
- LARGE_INTEGER DueTime;
- HANDLE WaitableTimerHandle = CreateWaitableTimer(NULL, FALSE, NULL);
-
- (void) arg; /* not used */
-
- if (WaitableTimerHandle != NULL) {
- DueTime.QuadPart = 0i64;
- if (SetWaitableTimer(WaitableTimerHandle, &DueTime, 10L /* 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;
- }
- return 0;
-}
-
-static void StartClockThread(void)
-{
- DWORD tid;
- FILETIME StartTime;
- LARGE_INTEGER Freq = { 0, 0 };
-
- /* get the performance counter freq*/
- if (QueryPerformanceFrequency(&Freq)) {
- PerfFrequency = Freq.QuadPart;
- }
-
- /* init variables with the time now */
- GetSystemTimeAsFileTime(&StartTime);
- LastTimerTime = (((ULONGLONG) StartTime.dwHighDateTime) << 32) + (ULONGLONG) StartTime.dwLowDateTime;
-
- /* init sync objects */
- InitializeCriticalSection(&TimerCritialSection);
- TimerThreadExitRequest = CreateEvent(NULL, FALSE, FALSE, NULL);
- ClockThreadHandle = CreateThread(NULL, 0, ClockThread, NULL, 0, &tid);
- if (ClockThreadHandle != NULL) {
- /* remober the thread priority is only within the process class */
- if (!SetThreadPriority(ClockThreadHandle, THREAD_PRIORITY_TIME_CRITICAL)) {
- printf("Error setting thread priority\n");
- }
- }
-}
-
-static void StopClockThread(void)
-{
- if (SetEvent(TimerThreadExitRequest) &&
- WaitForSingleObject(ClockThreadHandle, 10000L) == 0) {
- CloseHandle(TimerThreadExitRequest);
- TimerThreadExitRequest = NULL;
-
- CloseHandle(ClockThreadHandle);
- ClockThreadHandle = NULL;
-
- DeleteCriticalSection(&TimerCritialSection);
- }
-}
-
-typedef void (__cdecl *CRuntimeFunction)(void);
-
-#pragma data_seg(".CRT$XIY")
- CRuntimeFunction _StartClockThread = StartClockThread;
-#pragma data_seg(".CRT$XTY")
- CRuntimeFunction _StopClockThread = StopClockThread;
-#pragma data_seg() /* reset */
-
-
-int
-ntp_set_tod(
- struct timeval *tv,
- void *tzp
- )
-{
- SYSTEMTIME st;
- struct tm *gmtm;
- long x = tv->tv_sec;
- long y = tv->tv_usec;
- (void) tzp;
-
- gmtm = gmtime((const time_t *) &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);
-
- if (!SetSystemTime(&st)) {
- msyslog(LOG_ERR, "SetSystemTime failed: %m\n");
- return -1;
- }
- return 0;
-}
-
-
-
-#endif /* SYS_WINNT */
+#endif /* not SYS_WINNT */
#if defined (SYS_WINNT) || defined (SYS_VXWORKS)
/* getpass is used in ntpq.c and ntpdc.c */
{
int c, i;
static char password[32];
-
+#ifdef DEBUG
fprintf(stderr, "%s", prompt);
fflush(stderr);
+#endif
for (i=0; i<sizeof(password)-1 && ((c=_getch())!='\n'); i++) {
password[i] = c;
}
double sys_maxfreq = MAXFREQ; /* max frequency correction */
#if defined SYS_WINNT || defined SYS_CYGWIN32
-long tvu_maxslew; /* maximum adjust doable in 1 second */
-u_long tsf_maxslew; /* same as above, as long format */
-l_fp sys_clock_offset; /* correction for current system time */
-/*
- * units_per_tick = number of 100 nanosecond units added to the clock at each tick
- * adj_precision = converts microsecond/second to .1us/N*.1us
- * determined by GetSystemTimeAdjustment() in default_get_precision()
- */
-DWORD units_per_tick;
-long adj_precision;
+static long last_Adj = 0;
/*long adj_precision = (long)(HZ * 0.1); */ /* adj precision in usec (tickadj) */
#endif /* SYS_WINNT */
}
+
/*
* adj_systime - called once every second to make system time adjustments.
* Returns 1 if okay, 0 if trouble.
#if !defined SYS_WINNT && !defined SYS_CYGWIN32
struct timeval oadjtv;
#else
- DWORD dwTimeAdjustment;
+ int rc;
+ long dwTimeAdjustment;
#endif
/*
dtemp = sys_maxfreq;
#endif /* SCO5_CLOCK */
+#ifdef SYS_WINNT
+ dtemp = dtemp * 1000000.0;
+#else
dtemp = dtemp * 1e6 + .5;
+#endif
if (isneg)
dtemp = -dtemp;
adjtv.tv_sec = 0;
adjtv.tv_usec = (int32)dtemp;
-#if defined SYS_WINNT || defined SYS_CYGWIN32
- dwTimeAdjustment = units_per_tick + adjtv.tv_usec / adj_precision;
-#endif /* SYS_WINNT */
+#if defined SYS_WINNT || defined SYS_CYGWIN32
+ /* dtemp is in micro seconds. NT uses 100 ns units,
+ * so a unit change in dwTimeAdjustment corresponds
+ * to slewing 10 ppm.
+ * Calculate the number of 100ns units to add,
+ * and leave the remainder in dtemp */
+ dwTimeAdjustment = dtemp / 10;
+ dtemp += (double) -dwTimeAdjustment * 10.0;
+ dwTimeAdjustment += PRESET_TICK;
+
+ /* only adjust the clock if adjustment changes */
+ if (last_Adj != dwTimeAdjustment) {
+ last_Adj = dwTimeAdjustment;
+# ifdef DEBUG
+ if (debug > 1)
+ printf("SetSystemTimeAdjustment( %ld)\n", dwTimeAdjustment);
+# endif
+ rc = !SetSystemTimeAdjustment(dwTimeAdjustment, FALSE);
+ }
+ else rc = 0;
+ if (rc)
+#else
/*
* Here we do the actual adjustment. If for some reason the adjtime()
* call fails, like it is not implemented or something like that,
* we honk to the log. If the previous adjustment did not complete,
* we correct the residual offset.
*/
-#if !defined (SYS_WINNT) && !defined (SYS_CYGWIN32)
/* casey - we need a posix type thang here */
if (adjtime(&adjtv, &oadjtv) < 0)
-#else
- if (debug) {
- printf("SetSystemTimeAdjustment( %ld)\n", dwTimeAdjustment);
- }
- if (!SetSystemTimeAdjustment(dwTimeAdjustment, FALSE))
#endif /* SYS_WINNT */
{
msyslog(LOG_ERR, "Can't adjust time: %m");
else {
#if !defined (SYS_WINNT) && !defined (SYS_CYGWIN32)
sys_residual += oadjtv.tv_usec / 1e6;
+#else
+ sys_residual = dtemp / 1000000.0;
#endif /* SYS_WINNT */
}
#ifdef DEBUG
if (debug > 6)
- printf("adj_systime: adj %.6f -> remaining residual %.6f\n", now, sys_residual);
+ printf("adj_systime: adj %.9lf -> remaining residual %.9lf\n", now, sys_residual);
#endif
return 1;
}