]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 708] Set the affinity to a specific CPU for the clock interpolation thread only...
authorMartin Burnicki <burnicki@ntp.org>
Thu, 5 Oct 2006 10:20:42 +0000 (10:20 +0000)
committerMartin Burnicki <burnicki@ntp.org>
Thu, 5 Oct 2006 10:20:42 +0000 (10:20 +0000)
bk: 4524dc7aMWie7qzP5W9KOVWne64sAA

ports/winnt/ntpd/nt_clockstuff.c
ports/winnt/ntpd/win32_io.c

index 3f95ab60d8052adc59c7091f24b7f52c7d224351..c4a7407032706c581a8128d87d33164fa21b1c7b 100644 (file)
-/* Windows NT Clock Routines
- *
- *
- * 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" <colin.dancer@pyrochrome.net>
- * To: <bugs@ntp.org>
- * 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.
- *
- * Created by Sven Dietrich  sven@inter-yacht.com
- *
- */
-
+/* This file implementes system calls that are not compatible with UNIX */
 
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+# include <config.h>
 #endif
 
-#include "ntp_stdlib.h"
-#include "clockstuff.h"
-#include "ntservice.h"
-#include "ntp_timer.h"
-#include "ntpd.h"
-
-/*
- * Include code to possibly modify the MM timer while the service is active. 
- */
-
-  /*
-   * 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;
-
-
-extern double sys_residual;    /* residual from previous adjustment */
-
-char szMsgPath[255];
-BOOL init_randfile();
-
-static long last_Adj = 0;
-
-#define LS_CORR_INTV_SECS  2   /* seconds to apply leap second correction */
-#define LS_CORR_INTV   ( (LONGLONG) HECTONANOSECONDS * LS_CORR_INTV_SECS )  
-#define LS_CORR_LIMIT  ( (LONGLONG) HECTONANOSECONDS / 2 )  // half a second
-
-typedef union
-{
-       FILETIME ft;
-       ULONGLONG ull;
-} FT_ULL;
-
-static FT_ULL ls_ft;
-static DWORD ls_time_adjustment;
-static LARGE_INTEGER ls_ref_perf_cnt;
-static LONGLONG ls_elapsed;
-
-static void StartClockThread(void);
-static void StopClockThread(void);
-
-
-static CRITICAL_SECTION TimerCritialSection; /* lock for LastTimerCount & LastTimerTime */
-
-static ULONGLONG RollOverCount = 0;
-static ULONGLONG LastTimerCount = 0;
-static ULONGLONG LastTimerTime = 0;
-
-static HANDLE ClockThreadHandle = NULL;
-static HANDLE TimerThreadExitRequest = NULL;
-
-static DWORD every = 0;
-static DWORD initial_units_per_tick = 0;
-static DWORD lastLowTimer = 0;
+#include <stdio.h>
+#include "ntp_machine.h"
+#include "ntp_stdlib.h"
+#include "ntp_syslog.h"
+#include "ntp_fp.h"
+#include "ntp.h"
+#include "ntp_refclock.h"
+#include "win32_io.h"
 
-ULONGLONG PerfFrequency = 0;
-static DWORD units_per_tick = 0;
-static DOUBLE ppm_per_adjust_unit = 0.0;
 
-/*
- * Request Multimedia Timer
- */
-void
-set_mm_timer(int timerres)
+int NT_set_process_priority(void)
 {
-       modify_mm_timer = timerres;
+       if (!SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS)) 
+               {
+               msyslog(LOG_ERR, "SetPriorityClass: %m"); 
+               return 0;
+               }
+       else 
+               return 1;
 }
+
 /*
- * adj_systime - called once every second to make system time adjustments.
- * Returns 1 if okay, 0 if trouble.
+ * refclock_open - open serial port for reference clock
+ *
+ * This routine opens a serial port for I/O and sets default options. It
+ * returns the file descriptor if success and zero if failure.
  */
 int
-adj_systime(
-       double now
+refclock_open(
+       char *dev,              /* device name pointer */
+       u_int speed,            /* serial port speed (code) */
+       u_int flags             /* line discipline flags */
        )
 {
-       double dtemp;
-       u_char isneg = 0;
-       int rc;
-       long dwTimeAdjustment;
-
-       /*
-        * Add the residual from the previous adjustment to the new
-        * adjustment, bound and round.
-        */
-       dtemp = sys_residual + now;
-       sys_residual = 0;
-       if (dtemp < 0)
-       {
-               isneg = 1;
-               dtemp = -dtemp;
+       HANDLE Handle = INVALID_HANDLE_VALUE;
+       COMMTIMEOUTS timeouts;
+       DCB dcb = {0};
+
+       //
+       // open communication port handle
+       //
+       Handle = CreateFile(dev,
+               GENERIC_READ | GENERIC_WRITE,
+               0, // no sharing
+               NULL, // no security
+               OPEN_EXISTING,
+               FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
+               NULL); // not template
+       if (Handle == INVALID_HANDLE_VALUE) {  
+                
+               msyslog(LOG_ERR, "NT_COM: Device %s: CreateFile error: %m", dev);
+               return -1;
        }
 
-       if (dtemp > NTP_MAXFREQ)
-               dtemp = NTP_MAXFREQ;
-
-       dtemp = dtemp * 1e6;
-
-       if (isneg)
-               dtemp = -dtemp;
-
-       /* 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;      
-
+       /*  Change the input/output buffers to be large.
+       */
+       if (!SetupComm( Handle, 1024, 1024)) {
+               msyslog(LOG_ERR, "NT_COM: Device %s: SetupComm error: %m", dev);
+               return -1;
+       }
 
-  /* If a leap second is pending then determine the UTC time stamp 
-        * of when the insertion must take place */
-       if (leap_next & LEAP_ADDSECOND)  
-       {
-               if ( ls_ft.ull == 0 )  /* time stamp has not yet been computed */
-               {
-                       FT_ULL ft;
-                       SYSTEMTIME st;
-                       int itmp;
-
-                       GetSystemTimeAsFileTime(&ft.ft);   
-                       FileTimeToSystemTime(&ft.ft, &st);
-
-                       /* Accept leap announcement only 1 month in advance,
-                        * for end of March, June, September, or December.
-                        */
-                       if ( ( st.wMonth % 3 ) == 0 )
-                       {
-                               /* The comarison time stamp is computed according 
-                                * to 0:00h UTC of the following day */   
-                               if ( ++st.wMonth > 12 )
-                               {
-                                       st.wMonth -= 12;
-                                       st.wYear++;
-                               }
-                               
-                               st.wDay = 1;
-                               st.wHour = 0;
-                               st.wMinute = 0;
-                               st.wSecond = 0;
-                               st.wMilliseconds = 0;
-
-                               SystemTimeToFileTime(&st, &ls_ft.ft);
-                               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);
-                       }
-               }
-  }
+       dcb.DCBlength = sizeof(dcb);
+       if (!GetCommState(Handle, &dcb)) {
+               // Error getting current DCB settings
+               msyslog(LOG_ERR, "NT_COM: Device %s: GetCommState error: %m", dev);
+               return -1;
+       }
 
-  /* If the time stamp for the next leap second has been set
-        * then check if the leap second must be handled */
-       if ( ls_ft.ull )
-       {
-               LARGE_INTEGER this_perf_count;
+       switch (speed) {
+         case B300 :   dcb.BaudRate = 300; break;
+         case B1200 :  dcb.BaudRate = 1200; break;
+         case B2400 :  dcb.BaudRate = 2400; break;
+         case B4800 :  dcb.BaudRate = 4800; break;
+         case B9600 :  dcb.BaudRate = 9600; break;
+         case B19200 : dcb.BaudRate = 19200; break;
+         case B38400 : dcb.BaudRate = 38400; break;
+         default :
+               msyslog(LOG_ERR, "NT_COM: Device %s: unsupported baud rate", dev);
+               return -1;
+       }
 
-               QueryPerformanceCounter( &this_perf_count );
 
-               if ( ls_time_adjustment == 0 ) /* has not yet been scheduled */
-               {
-                       FT_ULL curr_ft;
-
-                       GetSystemTimeAsFileTime(&curr_ft.ft);   
-                       if ( curr_ft.ull >= ls_ft.ull )
-                       {
-                               ls_time_adjustment = every / LS_CORR_INTV_SECS;
-                               ls_ref_perf_cnt = this_perf_count;
-                               ls_elapsed = 0;
-                               msyslog(LOG_INFO, "Inserting positive leap second.");
-                       }
-               }
-               else  /* leap sec adjustment has been scheduled previously */
-               {
-                       ls_elapsed = ( this_perf_count.QuadPart - ls_ref_perf_cnt.QuadPart ) 
-                                      * HECTONANOSECONDS / PerfFrequency;
-               }
-
-               if ( ls_time_adjustment )  /* leap second adjustment is currently active */
-               {
-                       if ( ls_elapsed > ( LS_CORR_INTV - LS_CORR_LIMIT ) )
-                       {
-                               ls_time_adjustment = 0;  /* leap second adjustment done */
-                               ls_ft.ull = 0;
-                       }
-
-               /* 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;
-               }
+       dcb.ByteSize = 8;
+       dcb.fBinary = TRUE;
+       dcb.fParity = TRUE;
+       dcb.fOutxCtsFlow = 0;
+       dcb.fOutxDsrFlow = 0;
+       dcb.fDtrControl = DTR_CONTROL_DISABLE;
+       dcb.fDsrSensitivity = 0;
+       dcb.fTXContinueOnXoff = FALSE;
+       dcb.fOutX = 0; 
+       dcb.fInX = 0;
+       dcb.fErrorChar = 0;
+       dcb.fNull = 0;
+       dcb.fRtsControl = RTS_CONTROL_DISABLE; // RTS_CONTROL_DISABLE;
+       dcb.fAbortOnError = 0;
+       dcb.ByteSize = 8;
+       dcb.StopBits = ONESTOPBIT;
+       dcb.Parity = NOPARITY;
+       dcb.ErrorChar = 0;
+       dcb.EvtChar = 0;
+       dcb.EofChar = 0;
+
+       if (!SetCommState(Handle, &dcb)) {
+               msyslog(LOG_ERR, "NT_COM: Device %s: SetCommState error: %m", dev);
+               return -1;
        }
 
+       timeouts.ReadIntervalTimeout = 20; 
+       timeouts.ReadTotalTimeoutMultiplier = 0;
+       timeouts.ReadTotalTimeoutConstant = 5000;
+       timeouts.WriteTotalTimeoutMultiplier = 0;
+       timeouts.WriteTotalTimeoutConstant = 5000;
 
-       /* only adjust the clock if adjustment changes */
-       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);
-       }
-       else rc = 0;
-       if (rc)
-       {
-               msyslog(LOG_ERR, "Can't adjust time: %m");
-               return 0;
-       }
-       else {
-               sys_residual = dtemp / 1000000.0;
+          // Error setting time-outs.
+       if (!SetCommTimeouts(Handle, &timeouts)) {
+               msyslog(LOG_ERR, "NT_COM: Device %s: SetCommTimeouts error: %m", dev);
+               return -1;
        }
 
-#ifdef DEBUG
-       if (debug > 6)
-               printf("adj_systime: adj %.9f -> remaining residual %.9f\n", now, sys_residual);
-#endif
-       return 1;
+       return (int) Handle;
 }
 
 
-void init_winnt_time(void)
-{
-       BOOL noslew;
-       HANDLE hToken = INVALID_HANDLE_VALUE;
-       TOKEN_PRIVILEGES tkp;
-
-       /*
-        * Make sure the service is initialized
-        * before we do anything else
-        */
-       ntservice_init();
-
-       /* Set the Event-ID message-file name. */
-       if (!GetModuleFileName(NULL, szMsgPath, sizeof(szMsgPath))) 
-       {
-               msyslog(LOG_ERR, "GetModuleFileName(PGM_EXE_FILE) failed: %m\n");
-               exit(1);
-       }
-
-       /* Initialize random file before OpenSSL checks */
-       if(!init_randfile())
-               msyslog(LOG_ERR, "Unable to initialize .rnd file\n");
+int 
+ioctl(int fd,
+         int cmd,
+         int *x) {
 
-       /*
-        * 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);
+       if ((cmd == TIOCMSET) && (*x & TIOCM_RTS)) {
+               if (!EscapeCommFunction((HANDLE) fd, SETRTS)) 
+                       return -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 use return value of AdjustTokenPrivileges. */
-       /* (success does not indicate all privileges were set) */
-       if (GetLastError() != ERROR_SUCCESS) 
-       {
-               msyslog(LOG_ERR, "AdjustTokenPrivileges failed: %m");
-               /* later set time call will probably fail */
+       else if ((cmd == TIOCMSET) && !(*x & TIOCM_RTS)){
+               if (!EscapeCommFunction((HANDLE) fd, CLRRTS)) 
+                       return -1;
        }
 
-       /* Reset the Clock to a reasonable increment */
-       if (!GetSystemTimeAdjustment(&initial_units_per_tick, &every,&noslew))
-       {
-               msyslog(LOG_ERR, "GetSystemTimeAdjustment failed: %m\n");
-               exit(-1);
-       }
-
-       units_per_tick = initial_units_per_tick;
-
-       /* Calculate the time adjustment resulting from incrementing
-        * units per tick by 1 unit for 1 second */
-       ppm_per_adjust_unit = 1000000.0 / (double) every;
-
-#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
-
-       /*++++ Gerhard Junker
-       * see Platform SDK for QueryPerformanceCounter
-       * On a multiprocessor machine, it should not matter which processor is called. 
-       * However, you can get different results on different processors due to bugs in the BIOS or the HAL. 
-       * To specify processor affinity for a thread, use the SetThreadAffinityMask function. 
-       * ... we will hope, the apc routine will run on the same processor
-       */
-
-       SetThreadAffinityMask(GetCurrentThread(), 1L);
-
-       /*---- Gerhard Junker */
-
-       StartClockThread();
-
-       /* Set up the Console Handler */
-       if (!SetConsoleCtrlHandler(OnConsoleEvent, TRUE))
-       {
-               msyslog(LOG_ERR, "Can't set console control handler: %m");
-       }
+       return 0;
 }
 
 
-void reset_winnt_time(void)
+int    
+tcsetattr(
+       int fd, 
+       int optional_actions, 
+       const struct termios * s)
 {
-       /* 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;
-               GetSystemTime(&st);
-               SetSystemTime(&st);
+       DCB dcb = { 0 };
+       HANDLE Handle = (HANDLE) fd;
+       dcb.DCBlength = sizeof(dcb);
+       if (!GetCommState(Handle, &dcb)) {
+               // Error getting current DCB settings
+               msyslog(LOG_ERR, "NT_COM: GetCommState error: %m");
+               return FALSE;
        }
-}
-
 
-
-int
-gettimeofday(
-       struct timeval *tv
-       )
-{
-       /*  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;
-
-       /*  Mark a mark ASAP. The latency to here should
-        *  be reasonably deterministic
-        */
-
-       PreCount = LastTimerCount;                                           /*FIX*/
-
-       if (!QueryPerformanceCounter(&LargeIntNowCount)) {
-               msyslog(LOG_ERR, "QueryPeformanceCounter failed: %m");
-               exit(1);
+       switch (max(s->c_ospeed, s->c_ispeed)) {
+               case B300 :   dcb.BaudRate = 300; break;
+               case B1200 :  dcb.BaudRate = 1200; break;
+               case B2400 :  dcb.BaudRate = 2400; break;
+               case B4800 :  dcb.BaudRate = 4800; break;
+               case B9600 :  dcb.BaudRate = 9600; break;
+               case B19200 : dcb.BaudRate = 19200; break;
+               case B38400 : dcb.BaudRate = 38400; break;
+               default :
+                       msyslog(LOG_ERR, "NT_COM: unsupported baud rate");
+                       return FALSE;
        }
 
-       NowCount = LargeIntNowCount.QuadPart;
-
-       /*  Get base time we are going to extrapolate from
-        */     
-       EnterCriticalSection(&TimerCritialSection);
-       Count = LastTimerCount;
-       Time = LastTimerTime;
-       LeaveCriticalSection(&TimerCritialSection);
-
-       /*  Calculate when now is.
-        *
-        *  Result = LastTimerTime +  (NowCount - LastTimerCount) / PerfFrequency
-        */
+       switch (s->c_cflag & CSIZE) {
+               case CS5 : dcb.ByteSize = 5; break;
+               case CS6 : dcb.ByteSize = 6; break;
+               case CS7 : dcb.ByteSize = 7; break;
+               case CS8 : dcb.ByteSize = 8; break;
+               default :
+                       msyslog(LOG_ERR, "NT_COM: unsupported word size");
+                       return FALSE;
+       }
 
-       if (NowCount >= Count)
-       {
-               TicksElapsed = NowCount - Count; /* linear progression of ticks */
+       if (s->c_cflag & PARENB) {
+               dcb.fParity = TRUE;
+               if (s->c_cflag & PARODD) {
+                       dcb.Parity = ODDPARITY;
+               }
+               else {
+                       dcb.Parity = EVENPARITY;
+               }
        }
-       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*/
+       else {
+               dcb.fParity = FALSE;
+               dcb.Parity = NOPARITY;
        }
 
-       /*  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;
-}
-
-static void CALLBACK
-TimerApcFunction(
-       LPVOID lpArgToCompletionRoutine,
-       DWORD dwTimerLowValue,
-       DWORD dwTimerHighValue
-       )
-{
-       LARGE_INTEGER LargeIntNowCount;
-       (void) lpArgToCompletionRoutine; /* not used */
-
-       if (dwTimerLowValue == lastLowTimer) return;
-       
-       /* Grab the counter first of all */
-       QueryPerformanceCounter(&LargeIntNowCount);
-
-       /* Save this for next time */
-       lastLowTimer = dwTimerLowValue;
-
-       /* Check to see if the counter has rolled. This happens
-          more often on Multi-CPU systems */
-
-       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
+       dcb.fOutxCtsFlow = 0;
+       dcb.fOutxDsrFlow = 0;
+       dcb.fDtrControl = DTR_CONTROL_DISABLE;
+       dcb.fDsrSensitivity = 0;
+       dcb.fOutX = 0; 
+       dcb.fInX = 0;
+       dcb.fErrorChar = 0;
+       dcb.fNull = 0;
+       dcb.fRtsControl = RTS_CONTROL_DISABLE;
+       dcb.fAbortOnError = 0;
+       dcb.ErrorChar = 0;
+       dcb.EvtChar = 0;
+       dcb.EofChar = 0;
+
+       if (!SetCommState(Handle, &dcb)) {
+               msyslog(LOG_ERR, "NT_COM: SetCommState error: %m");
+               return FALSE;
        }
-
-       /* 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);
+       return TRUE;
 }
 
-
-
-DWORD WINAPI ClockThread(void *arg)
+extern int     
+tcgetattr(
+       int fd, struct termios *s)
 {
-
-       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;
+       DCB dcb = { 0 };
+       HANDLE Handle = (HANDLE) fd;
+       dcb.DCBlength = sizeof(dcb);
+       if (!GetCommState(Handle, &dcb)) {
+               // Error getting current DCB settings
+               msyslog(LOG_ERR, "NT_COM: GetCommState error: %m");
+               return FALSE;
        }
-       return 0;
-}
-
 
-static void StartClockThread(void)
-{
-       DWORD tid;
-       FILETIME StartTime;
-       LARGE_INTEGER Freq = { 0, 0 };
+       /*  Set c_ispeed & c_ospeed
+       */
+       switch (dcb.BaudRate) {
+               case 300 : s->c_ispeed = s->c_ospeed = B300; break;
+               case 1200 : s->c_ispeed = s->c_ospeed = B1200; break;
+               case 2400 : s->c_ispeed = s->c_ospeed = B2400; break;
+               case 4800 : s->c_ispeed = s->c_ospeed = B4800; break;
+               case 9600 : s->c_ispeed = s->c_ospeed = B9600; break;
+               case 19200 : s->c_ispeed = s->c_ospeed = B19200; break;
+               case 38400 : s->c_ispeed = s->c_ospeed = B38400; break;
+               default : s->c_ispeed = s->c_ospeed = B9600;
+       }
        
-       /* get the performance counter freq */
-       if (!QueryPerformanceFrequency(&Freq))
-       {
-               msyslog(LOG_ERR, "QueryPerformanceFrequency failed: %m\n");
-               exit (-1);
+
+       s->c_cflag = 0;
+       switch (dcb.ByteSize) {
+               case 5 : s->c_cflag |= CS5; break;
+               case 6 : s->c_cflag |= CS6; break;
+               case 7 : s->c_cflag |= CS7; break;
+               case 8 : s->c_cflag |= CS8; break;
+       }
+       if (dcb.fParity) {
+                 s->c_cflag |= PARENB;
+       }
+       switch (dcb.Parity) {
+               case EVENPARITY : break;
+               case MARKPARITY : break;
+               case NOPARITY : break;
+               case ODDPARITY : s->c_cflag |= PARODD; break;
+               case SPACEPARITY : break;
        }
 
-       PerfFrequency = Freq.QuadPart;
+       s->c_iflag = 0;
+       s->c_lflag = 0;
+       s->c_line = 0;
+       s->c_oflag = 0;
 
+       return TRUE; /* ok */
+}
 
-       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" );
-       }
+extern int tcflush(int fd, int mode) {
 
 
-       /* 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, "TimerThreadExitRequest");
 
-       ClockThreadHandle = CreateThread(NULL, 0, ClockThread, NULL, 0, &tid);
-       if (ClockThreadHandle != NULL)
-       {
-               /* remember the thread priority is only within the process class */
-               if (!SetThreadPriority(ClockThreadHandle, THREAD_PRIORITY_TIME_CRITICAL)) 
-               {
-#ifdef DEBUG
-                       printf("Error setting thread priority\n");
-#endif
-                 }
-       }
+return 0;
 
-       atexit( StopClockThread );
 }
 
-static void StopClockThread(void)
-{      
-       if ( wTimerRes )  /* if not 0 then the MM timer has been modified at startup */
-       {
-               timeEndPeriod( wTimerRes ); 
-               wTimerRes = 0;
-#ifdef DEBUG
-               msyslog( LOG_INFO, "MM timer set to default\n" );
-#endif
-       }
+extern int cfsetispeed(struct termios *tio, int speed) {
+               
+return 0;              
+};     
 
-       if (SetEvent(TimerThreadExitRequest) &&
-           WaitForSingleObject(ClockThreadHandle, 10000L) == 0)
-       {
-               CloseHandle(TimerThreadExitRequest);
-               TimerThreadExitRequest = NULL;
 
-               CloseHandle(ClockThreadHandle);
-               ClockThreadHandle = NULL;
+extern int cfsetospeed(struct termios *tio, int speed) {
+               
+return 0;              
+};     
 
-               DeleteCriticalSection(&TimerCritialSection);
-       }
-       else
-       {
-               msyslog(LOG_ERR, "Failed to stop clock thread.");
-               Sleep( 100 );
-       }
-}
index a9b2e3e3011ad952f1c1bbc0906554d3caa12ed6..c4a7407032706c581a8128d87d33164fa21b1c7b 100644 (file)
 
 int NT_set_process_priority(void)
 {
-       DWORD  SingleCPUMask = 0;
-       DWORD ProcessAffinityMask, SystemAffinityMask;
-       if (!GetProcessAffinityMask(GetCurrentProcess(), &ProcessAffinityMask, &
-                SystemAffinityMask))
-               msyslog(LOG_ERR, "GetProcessAffinityMask: %m");
-       else {
-               SingleCPUMask = 1; 
-# ifdef DEBUG 
-       msyslog(LOG_INFO, "System AffinityMask = %x", SystemAffinityMask); 
-# endif 
-               }
-
-       while (SingleCPUMask && !(SingleCPUMask & SystemAffinityMask)) 
-               SingleCPUMask = SingleCPUMask << 1; 
-               
-       if (!SingleCPUMask) 
-               msyslog(LOG_ERR, "Can't set Processor Affinity Mask"); 
-       else if (!SetProcessAffinityMask(GetCurrentProcess(), SingleCPUMask)) 
-               msyslog(LOG_ERR, "SetProcessAffinityMask: %m"); 
-# ifdef DEBUG 
-       else msyslog(LOG_INFO,"ProcessorAffinity Mask: %x", SingleCPUMask ); 
-# endif 
        if (!SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS)) 
                {
                msyslog(LOG_ERR, "SetPriorityClass: %m");