VxWorks osdMonotonic implementation

PowerPC time-base frequencies are 32-bit.
Adjust when warnings are printed.
Use long double to calculate time from time-base.
This commit is contained in:
Andrew Johnson
2017-10-27 15:17:38 -05:00
parent a1d2f337f4
commit 49d638be97
+34 -13
View File
@@ -8,11 +8,11 @@
#define _VSB_CONFIG_FILE <../lib/h/config/vsbConfig.h>
#include <vxWorks.h>
#include <stdio.h>
#define EPICS_EXPOSE_LIBCOM_MONOTONIC_PRIVATE
#include "epicsTypes.h"
#include "epicsTime.h"
#include "epicsFindSymbol.h"
#define NS_PER_SEC 1000000000
@@ -23,30 +23,35 @@ union timebase {
UINT64 u64; /* epicsMonotonicGet() */
};
static epicsUInt64 ticksPerSec;
#if CPU_FAMILY == PPC
#include <arch/ppc/vxPpcLib.h>
#include "epicsFindSymbol.h"
/* On PowerPC the timebase counter runs at a rate related to the
* bus clock and its frequency should always fit into a UINT32.
*/
static epicsUInt32 ticksPerSec;
#define TIMEBASEGET(TB) \
vxTimeBaseGet(&TB.u32[0], &TB.u32[1])
typedef epicsUInt64 (*sysTimeBaseFreq_t)(void);
void osdMonotonicInit(void)
{
typedef epicsUInt32 (*sysTimeBaseFreq_t)(void);
sysTimeBaseFreq_t sysTimeBaseFreq =
(sysTimeBaseFreq_t) epicsFindSymbol("_sysTimeBaseFreq");
if (sysTimeBaseFreq) {
ticksPerSec = sysTimeBaseFreq();
return;
}
printf("Warning: BSP routine sysTimeBaseFreq() not found,\n"
"can't set up monotonic time source.\n");
ticksPerSec = 0;
if (!ticksPerSec)
printf("Warning: Failed to set up monotonic time source.\n");
/* Warn here only if the BSP routine exists but returned 0 */
}
else
ticksPerSec = 0; /* Warn on first use */
}
@@ -55,6 +60,12 @@ void osdMonotonicInit(void)
#include <arch/i86/pentiumLib.h>
#include <hwif/cpu/arch/i86/vxCpuIdLib.h>
/* On Intel the timebase counter frequency is returned by the OS as a
* UINT64. Some CPUs may count at multi-GHz rates so we need 64 bits.
*/
static epicsUInt64 ticksPerSec;
#define TIMEBASEGET(TB) \
pentiumTscGet64(&TB.i64)
@@ -68,7 +79,7 @@ void osdMonotonicInit(void)
#else
#error CPU Family not supported yet!
#error This CPU family not supported yet!
#endif
@@ -84,9 +95,19 @@ epicsUInt64 epicsMonotonicGet(void)
{
union timebase tbNow;
if (!ticksPerSec)
if (!ticksPerSec) {
static int warned = 0;
if (!warned) {
printf("Warning: Monotonic time source is not available.\n");
warned = 1;
}
return 0;
}
TIMEBASEGET(tbNow);
return tbNow.u64 / (ticksPerSec / NS_PER_SEC);
/* Using a long double for the calculation below to preserve
* as many bits in the mantissa as possible.
*/
return ((long double) tbNow.u64) * NS_PER_SEC / ticksPerSec;
}