From 8a90688880bae68bc8b6bf537e09a4fc6306421c Mon Sep 17 00:00:00 2001 From: Freddie Akeroyd Date: Sun, 4 Oct 2020 00:20:11 +0100 Subject: [PATCH] Make returned value relative to IOC boot time to improve accuracy --- modules/libcom/src/osi/os/WIN32/osdMonotonic.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/modules/libcom/src/osi/os/WIN32/osdMonotonic.c b/modules/libcom/src/osi/os/WIN32/osdMonotonic.c index 208c1aaa0..e9db3b1da 100644 --- a/modules/libcom/src/osi/os/WIN32/osdMonotonic.c +++ b/modules/libcom/src/osi/os/WIN32/osdMonotonic.c @@ -14,8 +14,10 @@ #include "epicsTime.h" #include "generalTimeSup.h" -static epicsUInt64 osdMonotonicResolution; /* timer resolution in nanoseconds */ -static double perfCounterScale; /* convert performance counter tics to nanoseconds */ +static epicsUInt64 osdMonotonicResolution; /* timer resolution in nanoseconds */ +static epicsUInt64 perfCounterFrequency; /* performance counter tics per second */ +static epicsUInt64 perfCounterOffset; /* performance counter value at initialisation */ +static const epicsUInt64 sec2nsec = 1000000000; /* number of nanoseconds in a second */ void osdMonotonicInit(void) { @@ -27,8 +29,9 @@ void osdMonotonicInit(void) QueryPerformanceCounter(&val) && freq.QuadPart != 0) { - perfCounterScale = 1e9 / freq.QuadPart; - osdMonotonicResolution = 1 + (int)perfCounterScale; + perfCounterFrequency = freq.QuadPart; + perfCounterOffset = val.QuadPart; + osdMonotonicResolution = sec2nsec / perfCounterFrequency + (sec2nsec % perfCounterFrequency != 0 ? 1 : 0); } else { cantProceed("osdMonotonicInit: Windows Performance Counter is not available\n"); } @@ -45,7 +48,7 @@ epicsUInt64 epicsMonotonicGet(void) if(!QueryPerformanceCounter(&val)) { cantProceed("epicsMonotonicGet: Failed to read Windows Performance Counter\n"); return 0; - } else { - return (epicsUInt64)(val.QuadPart * perfCounterScale + 0.5); /* return value in nanoseconds */ + } else { /* return value in nanoseconds */ + return (epicsUInt64)((double)(val.QuadPart - perfCounterOffset) * sec2nsec / perfCounterFrequency + 0.5); } }