From 25acc515c45b8b0e58c9cc03038d7e10bf467a6b Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Sat, 7 Sep 2002 00:11:06 +0000 Subject: [PATCH] perform FILETIME conversions only on windows because monolithic win32 header files are incompatible with other things in EPICS and we cant include windows.h in osdTime.h --- src/libCom/osi/epicsTime.cpp | 99 +----------------- src/libCom/osi/os/Darwin/osdTime.h | 8 -- src/libCom/osi/os/Linux/osdTime.h | 9 -- src/libCom/osi/os/RTEMS/osdTime.h | 9 +- src/libCom/osi/os/VMS/osdTime.h | 9 -- src/libCom/osi/os/WIN32/dllmain.cpp | 3 +- src/libCom/osi/os/WIN32/osdEvent.c | 7 +- src/libCom/osi/os/WIN32/osdMutex.c | 7 +- src/libCom/osi/os/WIN32/osdNetIntf.c | 1 - src/libCom/osi/os/WIN32/osdProcess.c | 1 - src/libCom/osi/os/WIN32/osdSock.c | 1 - src/libCom/osi/os/WIN32/osdThread.c | 7 +- src/libCom/osi/os/WIN32/osdThreadPrivate.h | 23 ----- src/libCom/osi/os/WIN32/osdTime.cpp | 112 +++++++++++---------- src/libCom/osi/os/WIN32/osdTime.h | 2 - src/libCom/osi/os/posix/osdTime.h | 7 -- src/libCom/osi/os/vxWorks/osdTime.h | 7 -- src/libCom/test/epicsTimeTest.cpp | 10 -- 18 files changed, 64 insertions(+), 258 deletions(-) delete mode 100644 src/libCom/osi/os/WIN32/osdThreadPrivate.h diff --git a/src/libCom/osi/epicsTime.cpp b/src/libCom/osi/epicsTime.cpp index e1dc83c7f..6d4110afa 100644 --- a/src/libCom/osi/epicsTime.cpp +++ b/src/libCom/osi/epicsTime.cpp @@ -22,6 +22,7 @@ #include "epicsVersion.h" #include "envDefs.h" #include "epicsTime.h" +#include "osiSock.h" /* pull in struct timeval */ static const char *id = "@(#) " EPICS_VERSION_STRING ", Common Utilities Library" __DATE__; @@ -419,104 +420,6 @@ epicsTime::epicsTime (const aitTimeStamp &ts) *this = epicsTime (this->secPastEpoch+secAdj, this->nSec+nSecAdj); } -static const FILETIME epicsEpochInFileTime = { 0x18d64000, 0x01b41e2a }; - -static inline bool fileTimeGreaterThanOrEqual ( const FILETIME & lhs, const FILETIME & rhs ) -{ - if ( lhs.dwHighDateTime > rhs.dwHighDateTime ) { - return true; - } - else if ( lhs.dwHighDateTime < rhs.dwHighDateTime ) { - return false; - } - else if ( lhs.dwLowDateTime >= rhs.dwLowDateTime ) { - return true; - } - return false; -} - -epicsTime::operator _FILETIME () const -{ - static const DWORD dwordMax = 0xffffffff; - static const double ticksPerLowWord = - static_cast < double > ( dwordMax ) + 1.0; - static const double ftNanoSecPerTick = 100; - static const double ftTicksPerSec = 1e7; - - // compute the ticks past the epics epoch in file time ticks - double ftTicks = this->secPastEpoch * ftTicksPerSec + this->nSec / ftNanoSecPerTick; - FILETIME ftTicksPastEpicsEpoch; - ftTicksPastEpicsEpoch.dwHighDateTime = static_cast < DWORD > ( ftTicks / ticksPerLowWord ); - double lowPart = ftTicks - ftTicksPastEpicsEpoch.dwHighDateTime * ticksPerLowWord; - ftTicksPastEpicsEpoch.dwLowDateTime = static_cast < DWORD > ( lowPart ); - - // add the EPICS epoch offset - FILETIME result; - result.dwHighDateTime = - epicsEpochInFileTime.dwHighDateTime + ftTicksPastEpicsEpoch.dwHighDateTime; - if ( epicsEpochInFileTime.dwLowDateTime > dwordMax - ftTicksPastEpicsEpoch.dwLowDateTime ) { - // carry - result.dwHighDateTime++; - double tmp = epicsEpochInFileTime.dwLowDateTime; - tmp += ftTicksPastEpicsEpoch.dwLowDateTime; - result.dwLowDateTime = static_cast < DWORD > ( tmp - dwordMax ); - } - else { - result.dwLowDateTime = - epicsEpochInFileTime.dwLowDateTime + ftTicksPastEpicsEpoch.dwLowDateTime; - } - return result; -} - -epicsTime::epicsTime ( const _FILETIME & ts ) -{ - static const DWORD dwordMax = 0xffffffff; - - if ( fileTimeGreaterThanOrEqual ( ts , epicsEpochInFileTime ) ) { - // remove epics epoch offset from the incoming file time - FILETIME ftTicksPastEpicsEpoch; - ftTicksPastEpicsEpoch.dwHighDateTime = - ts.dwHighDateTime - epicsEpochInFileTime.dwHighDateTime; - if ( ts.dwLowDateTime >= epicsEpochInFileTime.dwLowDateTime ) { - ftTicksPastEpicsEpoch.dwLowDateTime = - ts.dwLowDateTime - epicsEpochInFileTime.dwLowDateTime; - } - else { - // borrow - ftTicksPastEpicsEpoch.dwHighDateTime--; - ftTicksPastEpicsEpoch.dwLowDateTime = - ( dwordMax - epicsEpochInFileTime.dwLowDateTime ) - + ts.dwLowDateTime + 1; - } - - // adjust between file time ticks and EPICS time ticks - static const double ticksPerLowWord = - static_cast < double > ( dwordMax ) + 1.0; - static const double ftTicksPerSec = 1e7; - static const double epicsTicksPerSec = 1e9; - double ftTicksPastEpicsEpochFP = - ticksPerLowWord * ftTicksPastEpicsEpoch.dwHighDateTime + - ftTicksPastEpicsEpoch.dwLowDateTime; - double epicsTicksPastEpicsEpoch = ftTicksPastEpicsEpochFP * - ( epicsTicksPerSec / ftTicksPerSec ); - this->secPastEpoch = static_cast < unsigned long > - ( epicsTicksPastEpicsEpoch / nSecPerSec ); - double nSecPart = epicsTicksPastEpicsEpoch - - this->secPastEpoch * epicsTime::nSecPerSec; - this->nSec = static_cast < unsigned long > ( nSecPart ); - } - else { - this->secPastEpoch = 0; - this->nSec = 0; - } -} - -epicsTime & epicsTime::operator = ( const _FILETIME & rhs ) -{ - *this = epicsTime ( rhs ); - return *this; -} - // // epicsTime::ntpTimeStamp () // diff --git a/src/libCom/osi/os/Darwin/osdTime.h b/src/libCom/osi/os/Darwin/osdTime.h index 3cfca0bd6..e9314234d 100644 --- a/src/libCom/osi/os/Darwin/osdTime.h +++ b/src/libCom/osi/os/Darwin/osdTime.h @@ -13,15 +13,7 @@ #ifndef osdTimeh #define osdTimeh -#include #include -/* from win32 */ -typedef u_int32_t DWORD; -typedef struct _FILETIME { - DWORD dwLowDateTime; /* low 32 bits */ - DWORD dwHighDateTime; /* high 32 bits */ -} FILETIME; - #endif /* ifndef osdTimeh */ diff --git a/src/libCom/osi/os/Linux/osdTime.h b/src/libCom/osi/os/Linux/osdTime.h index f01ab5a5f..4c8bd2592 100644 --- a/src/libCom/osi/os/Linux/osdTime.h +++ b/src/libCom/osi/os/Linux/osdTime.h @@ -19,14 +19,5 @@ * causes `struct timespec' to be defined in more than one place. */ -#include - -/* from win32 */ -typedef uint32_t DWORD; -typedef struct _FILETIME { - DWORD dwLowDateTime; /* low 32 bits */ - DWORD dwHighDateTime; /* high 32 bits */ -} FILETIME; - #endif /* ifndef osdTimeh */ diff --git a/src/libCom/osi/os/RTEMS/osdTime.h b/src/libCom/osi/os/RTEMS/osdTime.h index 1e25e38e6..2c2ce5218 100644 --- a/src/libCom/osi/os/RTEMS/osdTime.h +++ b/src/libCom/osi/os/RTEMS/osdTime.h @@ -16,13 +16,6 @@ #ifndef osdTimeh #define osdTimeh -#include - -/* from win32 */ -typedef u_int32_t DWORD; -typedef struct _FILETIME { - DWORD dwLowDateTime; /* low 32 bits */ - DWORD dwHighDateTime; /* high 32 bits */ -} FILETIME; +/* NOOP */ #endif /* ifndef osdTimeh */ diff --git a/src/libCom/osi/os/VMS/osdTime.h b/src/libCom/osi/os/VMS/osdTime.h index bdf7a64e1..dc6b0c453 100644 --- a/src/libCom/osi/os/VMS/osdTime.h +++ b/src/libCom/osi/os/VMS/osdTime.h @@ -17,8 +17,6 @@ #ifndef osdTimeh #define osdTimeh -#include - /* * I assume that this is never defined on VMS ? */ @@ -27,11 +25,4 @@ struct timespec { long tv_nsec; /* nanoseconds within the second */ }; -/* from win32 */ -typedef uint32_t DWORD; -typedef struct _FILETIME { - DWORD dwLowDateTime; /* low 32 bits */ - DWORD dwHighDateTime; /* high 32 bits */ -} FILETIME; - #endif /* ifndef osdTimeh */ \ No newline at end of file diff --git a/src/libCom/osi/os/WIN32/dllmain.cpp b/src/libCom/osi/os/WIN32/dllmain.cpp index 58dd54798..d1a4e4cfe 100644 --- a/src/libCom/osi/os/WIN32/dllmain.cpp +++ b/src/libCom/osi/os/WIN32/dllmain.cpp @@ -23,7 +23,6 @@ #include #define VC_EXTRALEAN -#define WIN32_LEAN_AND_MEAN #include #include "epicsVersion.h" @@ -31,7 +30,7 @@ #include "osiSock.h" #ifndef _WIN32 -#error This source is specific to WIN32 +# error This source is specific to WIN32 #endif extern "C" void epicsThreadCleanupWIN32 (); diff --git a/src/libCom/osi/os/WIN32/osdEvent.c b/src/libCom/osi/os/WIN32/osdEvent.c index 07ee46a78..ed1841072 100644 --- a/src/libCom/osi/os/WIN32/osdEvent.c +++ b/src/libCom/osi/os/WIN32/osdEvent.c @@ -20,12 +20,7 @@ #include -#ifndef VC_EXTRALEAN -# define VC_EXTRALEAN -#endif -#ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -#endif +#define VC_EXTRALEAN /* including less than this causes conflicts with winsock2.h :-( */ #define _WIN32_WINNT 0x400 #include diff --git a/src/libCom/osi/os/WIN32/osdMutex.c b/src/libCom/osi/os/WIN32/osdMutex.c index 2df5bc843..de9cda3d9 100644 --- a/src/libCom/osi/os/WIN32/osdMutex.c +++ b/src/libCom/osi/os/WIN32/osdMutex.c @@ -21,12 +21,7 @@ #include #include -#ifndef VC_EXTRALEAN -# define VC_EXTRALEAN -#endif -#ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -#endif +#define VC_EXTRALEAN /* including less than this causes conflicts with winsock2.h :-( */ #define _WIN32_WINNT 0x400 #include diff --git a/src/libCom/osi/os/WIN32/osdNetIntf.c b/src/libCom/osi/os/WIN32/osdNetIntf.c index 1db7f899b..ddcd30c7e 100644 --- a/src/libCom/osi/os/WIN32/osdNetIntf.c +++ b/src/libCom/osi/os/WIN32/osdNetIntf.c @@ -30,7 +30,6 @@ * WIN32 specific */ #define VC_EXTRALEAN -#define WIN32_LEAN_AND_MEAN #include #include #include diff --git a/src/libCom/osi/os/WIN32/osdProcess.c b/src/libCom/osi/os/WIN32/osdProcess.c index 856d94b04..8300e1c41 100644 --- a/src/libCom/osi/os/WIN32/osdProcess.c +++ b/src/libCom/osi/os/WIN32/osdProcess.c @@ -26,7 +26,6 @@ * Windows includes */ #define VC_EXTRALEAN -#define WIN32_LEAN_AND_MEAN #include #include diff --git a/src/libCom/osi/os/WIN32/osdSock.c b/src/libCom/osi/os/WIN32/osdSock.c index 0dab75d40..5e7f2873c 100644 --- a/src/libCom/osi/os/WIN32/osdSock.c +++ b/src/libCom/osi/os/WIN32/osdSock.c @@ -30,7 +30,6 @@ * WIN32 specific */ #define VC_EXTRALEAN -#define WIN32_LEAN_AND_MEAN #include #include #include diff --git a/src/libCom/osi/os/WIN32/osdThread.c b/src/libCom/osi/os/WIN32/osdThread.c index 6dfd64f93..9206b4e9c 100644 --- a/src/libCom/osi/os/WIN32/osdThread.c +++ b/src/libCom/osi/os/WIN32/osdThread.c @@ -21,12 +21,7 @@ #include #include -#ifndef VC_EXTRALEAN -# define VC_EXTRALEAN -#endif -#ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -#endif +#define VC_EXTRALEAN #include #include diff --git a/src/libCom/osi/os/WIN32/osdThreadPrivate.h b/src/libCom/osi/os/WIN32/osdThreadPrivate.h deleted file mode 100644 index 62a50fabc..000000000 --- a/src/libCom/osi/os/WIN32/osdThreadPrivate.h +++ /dev/null @@ -1,23 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef assert // allow use of epicsAssert.h -#include -#endif - -#include - - - -#ifdef __cplusplus - - - -#endif /* __cplusplus */ \ No newline at end of file diff --git a/src/libCom/osi/os/WIN32/osdTime.cpp b/src/libCom/osi/os/WIN32/osdTime.cpp index bb356206b..b21a31e72 100644 --- a/src/libCom/osi/os/WIN32/osdTime.cpp +++ b/src/libCom/osi/os/WIN32/osdTime.cpp @@ -26,7 +26,6 @@ // WIN32 // #define VC_EXTRALEAN -#define WIN32_LEAN_AND_MEAN #include #include @@ -46,16 +45,7 @@ # define debugPrintf(argsInParen) #endif -static const SYSTEMTIME epicsEpochST = { - 1990, // year - 1, // month - 1, // day of the week (Monday) - 1, // day of the month - 0, // hour - 0, // min - 0, // sec - 0 // milli sec -}; +static const LONGLONG epicsEpochInFileTime = 0x01b41e2a18d64000; class currentTime : public epicsTimerNotify { public: @@ -65,7 +55,6 @@ public: void startPLL (); private: CRITICAL_SECTION mutex; - LONGLONG epicsEpochInFileTime; LONGLONG lastPerfCounter; LONGLONG perfCounterFreq; LONGLONG epicsTimeLast; // nano-sec since the EPICS epoch @@ -84,7 +73,8 @@ static bool osdTimeInitSuccess = false; static epicsThreadOnceId osdTimeOnceFlag = EPICS_THREAD_ONCE_INIT; static const LONGLONG FILE_TIME_TICKS_PER_SEC = 10000000; static const LONGLONG EPICS_TIME_TICKS_PER_SEC = 1000000000; - +static const LONGLONG ET_TICKS_PER_FT_TICK = + EPICS_TIME_TICKS_PER_SEC / FILE_TIME_TICKS_PER_SEC; // // osdTimeInit () // @@ -92,6 +82,19 @@ static void osdTimeInit ( void * ) { pCurrentTime = new currentTime (); + // self test FILETIME conversion only if + // its a debug build +# if defined ( _DEBUG ) + { + epicsTime ts0 = epicsTime::getCurrent (); + FILETIME ft = ts0; + epicsTime ts1 = ft; + double diff = fabs ( ts0 - ts1 ); + // we expect to loose 100 nS of precision when moving to and from win32 filetime + assert ( diff <= 100e-9 ); + } +# endif + // set here to avoid recursion problems osdTimeInitSuccess = true; @@ -247,7 +250,6 @@ int epicsTime_localtime ( const time_t *pAnsiTime, struct tm *pTM ) } currentTime::currentTime () : - epicsEpochInFileTime ( 0 ), lastPerfCounter ( 0 ), perfCounterFreq ( 0 ), epicsTimeLast ( 0 ), @@ -258,21 +260,13 @@ currentTime::currentTime () : pTimer ( 0 ), perfCtrPresent ( false ) { - FILETIME ft; - { - SystemTimeToFileTime ( & epicsEpochST, & ft ); - LARGE_INTEGER tmp; - tmp.LowPart = ft.dwLowDateTime; - tmp.HighPart = ft.dwHighDateTime; - this->epicsEpochInFileTime = tmp.QuadPart; - } - InitializeCriticalSection ( & this->mutex ); // avoid interruptions by briefly becoming a time critical thread int originalPriority = GetThreadPriority ( GetCurrentThread () ); SetThreadPriority ( GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL ); + FILETIME ft; GetSystemTimeAsFileTime ( & ft ); LARGE_INTEGER tmp; QueryPerformanceCounter ( & tmp ); @@ -288,12 +282,12 @@ currentTime::currentTime () : liFileTime.LowPart = ft.dwLowDateTime; liFileTime.HighPart = ft.dwHighDateTime; - if ( liFileTime.QuadPart >= this->epicsEpochInFileTime ) { + if ( liFileTime.QuadPart >= epicsEpochInFileTime ) { // the windows file time has a maximum resolution of 100 nS // and a nominal resolution of 10 mS - 16 mS this->epicsTimeLast = - ( liFileTime.QuadPart - this->epicsEpochInFileTime ) * - ( EPICS_TIME_TICKS_PER_SEC / FILE_TIME_TICKS_PER_SEC ); + ( liFileTime.QuadPart - epicsEpochInFileTime ) * + ET_TICKS_PER_FT_TICK; } else { errlogPrintf ( @@ -384,23 +378,7 @@ void currentTime::getCurrentTime ( epicsTimeStamp & dest ) // fall back to low res file time FILETIME ft; GetSystemTimeAsFileTime ( & ft ); - LARGE_INTEGER lift; - lift.LowPart = ft.dwLowDateTime; - lift.HighPart = ft.dwHighDateTime; - - if ( lift.QuadPart > this->epicsEpochInFileTime ) { - LONGLONG fileTimeTicksSinceEpochEPICS = - lift.QuadPart - this->epicsEpochInFileTime; - dest.secPastEpoch = static_cast < epicsUInt32 > - ( fileTimeTicksSinceEpochEPICS / FILE_TIME_TICKS_PER_SEC ); - dest.nsec = static_cast < epicsUInt32 > - ( ( fileTimeTicksSinceEpochEPICS % FILE_TIME_TICKS_PER_SEC ) * - EPICS_TIME_TICKS_PER_SEC / FILE_TIME_TICKS_PER_SEC ); - } - else { - dest.secPastEpoch = 0; - dest.nsec = 0; - } + dest = epicsTime ( ft ); } } @@ -502,8 +480,8 @@ epicsTimerNotify::expireStatus currentTime::expire ( const epicsTime & ) this->lastPerfCounter = curPerfCounter.QuadPart; LONGLONG epicsTimeFromCurrentFileTime = - ( curFileTime.QuadPart - this->epicsEpochInFileTime )* - ( EPICS_TIME_TICKS_PER_SEC / FILE_TIME_TICKS_PER_SEC ); + ( curFileTime.QuadPart - epicsEpochInFileTime ) * + ET_TICKS_PER_FT_TICK; delta = epicsTimeFromCurrentFileTime - this->epicsTimeLast; if ( delta > EPICS_TIME_TICKS_PER_SEC || delta < -EPICS_TIME_TICKS_PER_SEC ) { @@ -564,14 +542,40 @@ void currentTime::startPLL () this->pTimer->start ( *this, 1.0 ); } +epicsTime::operator FILETIME () const +{ + LARGE_INTEGER ftTicks; + ftTicks.QuadPart = ( this->secPastEpoch * FILE_TIME_TICKS_PER_SEC ) + + ( this->nSec / ET_TICKS_PER_FT_TICK ); + ftTicks.QuadPart += epicsEpochInFileTime; + FILETIME ts; + ts.dwLowDateTime = ftTicks.LowPart; + ts.dwHighDateTime = ftTicks.HighPart; + return ts; +} +epicsTime::epicsTime ( const FILETIME & ts ) +{ + LARGE_INTEGER lift; + lift.LowPart = ts.dwLowDateTime; + lift.HighPart = ts.dwHighDateTime; + if ( lift.QuadPart > epicsEpochInFileTime ) { + LONGLONG fileTimeTicksSinceEpochEPICS = + lift.QuadPart - epicsEpochInFileTime; + this->secPastEpoch = static_cast < epicsUInt32 > + ( fileTimeTicksSinceEpochEPICS / FILE_TIME_TICKS_PER_SEC ); + this->nSec = static_cast < epicsUInt32 > + ( ( fileTimeTicksSinceEpochEPICS % FILE_TIME_TICKS_PER_SEC ) * + ET_TICKS_PER_FT_TICK ); + } + else { + this->secPastEpoch = 0; + this->nSec = 0; + } +} - - - - - - - - - +epicsTime & epicsTime::operator = ( const FILETIME & rhs ) +{ + *this = epicsTime ( rhs ); + return *this; +} diff --git a/src/libCom/osi/os/WIN32/osdTime.h b/src/libCom/osi/os/WIN32/osdTime.h index 7ce9905a5..c9594b23c 100644 --- a/src/libCom/osi/os/WIN32/osdTime.h +++ b/src/libCom/osi/os/WIN32/osdTime.h @@ -17,8 +17,6 @@ #ifndef osdTimeh #define osdTimeh -#include - struct timespec { time_t tv_sec; /* seconds since some epoch */ long tv_nsec; /* nanoseconds within the second */ diff --git a/src/libCom/osi/os/posix/osdTime.h b/src/libCom/osi/os/posix/osdTime.h index a4f933ff2..d1334abc4 100644 --- a/src/libCom/osi/os/posix/osdTime.h +++ b/src/libCom/osi/os/posix/osdTime.h @@ -34,12 +34,5 @@ epicsShareFunc void epicsShareAPI } #endif /* __cplusplus */ -/* from win32 */ -typedef uint32_t DWORD; -typedef struct _FILETIME { - DWORD dwLowDateTime; /* low 32 bits */ - DWORD dwHighDateTime; /* high 32 bits */ -} FILETIME; - #endif /* ifndef osdTimeh */ diff --git a/src/libCom/osi/os/vxWorks/osdTime.h b/src/libCom/osi/os/vxWorks/osdTime.h index e5b39f19a..aa303bbc1 100644 --- a/src/libCom/osi/os/vxWorks/osdTime.h +++ b/src/libCom/osi/os/vxWorks/osdTime.h @@ -9,10 +9,3 @@ \*************************************************************************/ /* Following needed for struct timeval */ #include - -/* from win32 */ -typedef uint32_t DWORD; -typedef struct _FILETIME { - DWORD dwLowDateTime; /* low 32 bits */ - DWORD dwHighDateTime; /* high 32 bits */ -} FILETIME; diff --git a/src/libCom/test/epicsTimeTest.cpp b/src/libCom/test/epicsTimeTest.cpp index b3f7c72ea..3c2c6128c 100644 --- a/src/libCom/test/epicsTimeTest.cpp +++ b/src/libCom/test/epicsTimeTest.cpp @@ -61,16 +61,6 @@ int epicsTimeTest (void) printf ("epicsTime Test (%3d loops)\n========================\n\n", nTimes); - // test FILETIME conversion - { - epicsTime ts0 = epicsTime::getCurrent (); - FILETIME ft = ts0; - epicsTime ts1 = ft; - double diff = fabs ( ts0 - ts1 ); - // we expect to loose 100 nS of precision when moving to and from win32 filetime - assert ( diff <= 100e-9 ); - } - for (int iTimes=0; iTimes < nTimes; ++iTimes) { for (i=0; i