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
This commit is contained in:
Jeff Hill
2002-09-07 00:11:06 +00:00
parent 593ee10818
commit 25acc515c4
18 changed files with 64 additions and 258 deletions
+1 -98
View File
@@ -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 ()
//
-8
View File
@@ -13,15 +13,7 @@
#ifndef osdTimeh
#define osdTimeh
#include <sys/types.h>
#include <sys/time.h>
/* from win32 */
typedef u_int32_t DWORD;
typedef struct _FILETIME {
DWORD dwLowDateTime; /* low 32 bits */
DWORD dwHighDateTime; /* high 32 bits */
} FILETIME;
#endif /* ifndef osdTimeh */
-9
View File
@@ -19,14 +19,5 @@
* causes `struct timespec' to be defined in more than one place.
*/
#include <inttypes.h>
/* from win32 */
typedef uint32_t DWORD;
typedef struct _FILETIME {
DWORD dwLowDateTime; /* low 32 bits */
DWORD dwHighDateTime; /* high 32 bits */
} FILETIME;
#endif /* ifndef osdTimeh */
+1 -8
View File
@@ -16,13 +16,6 @@
#ifndef osdTimeh
#define osdTimeh
#include <sys/types.h>
/* 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 */
-9
View File
@@ -17,8 +17,6 @@
#ifndef osdTimeh
#define osdTimeh
#include <inttypes.h>
/*
* 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 */
+1 -2
View File
@@ -23,7 +23,6 @@
#include <stdlib.h>
#define VC_EXTRALEAN
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#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 ();
+1 -6
View File
@@ -20,12 +20,7 @@
#include <limits.h>
#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 <winsock2.h>
+1 -6
View File
@@ -21,12 +21,7 @@
#include <stdio.h>
#include <limits.h>
#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 <winsock2.h>
-1
View File
@@ -30,7 +30,6 @@
* WIN32 specific
*/
#define VC_EXTRALEAN
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>
#include <process.h>
-1
View File
@@ -26,7 +26,6 @@
* Windows includes
*/
#define VC_EXTRALEAN
#define WIN32_LEAN_AND_MEAN
#include <wtypes.h>
#include <process.h>
-1
View File
@@ -30,7 +30,6 @@
* WIN32 specific
*/
#define VC_EXTRALEAN
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>
#include <process.h>
+1 -6
View File
@@ -21,12 +21,7 @@
#include <stddef.h>
#include <stdio.h>
#ifndef VC_EXTRALEAN
# define VC_EXTRALEAN
#endif
#ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
#endif
#define VC_EXTRALEAN
#include <winsock2.h>
#include <process.h>
@@ -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 <assert.h>
#endif
#include <windows.h>
#ifdef __cplusplus
#endif /* __cplusplus */
+58 -54
View File
@@ -26,7 +26,6 @@
// WIN32
//
#define VC_EXTRALEAN
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <process.h>
@@ -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;
}
-2
View File
@@ -17,8 +17,6 @@
#ifndef osdTimeh
#define osdTimeh
#include <winsock2.h>
struct timespec {
time_t tv_sec; /* seconds since some epoch */
long tv_nsec; /* nanoseconds within the second */
-7
View File
@@ -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 */
-7
View File
@@ -9,10 +9,3 @@
\*************************************************************************/
/* Following needed for struct timeval */
#include <sys/times.h>
/* from win32 */
typedef uint32_t DWORD;
typedef struct _FILETIME {
DWORD dwLowDateTime; /* low 32 bits */
DWORD dwHighDateTime; /* high 32 bits */
} FILETIME;
-10
View File
@@ -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<wasteTime; i++) {
useSomeCPU = epicsTime::getCurrent();