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:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user