From aa71115a4b367ef5a58675f475b03c2916642ed7 Mon Sep 17 00:00:00 2001 From: "W. Eric Norum" Date: Tue, 15 Apr 2008 14:42:19 +0000 Subject: [PATCH] Back out yesterday's mistaken commits. --- src/libCom/osi/os/vxWorks/drvNTPTime.c | 245 ------------------------- src/libCom/osi/os/vxWorks/drvNTPTime.h | 14 -- src/libCom/osi/os/vxWorks/drvVxTime.c | 217 ---------------------- src/libCom/osi/os/vxWorks/drvVxTime.h | 14 -- src/libCom/osi/os/vxWorks/iocClock.c | 219 ++++++++++++++++++++++ src/libCom/osi/os/vxWorks/iocClock.h | 20 ++ 6 files changed, 239 insertions(+), 490 deletions(-) delete mode 100644 src/libCom/osi/os/vxWorks/drvNTPTime.c delete mode 100644 src/libCom/osi/os/vxWorks/drvNTPTime.h delete mode 100644 src/libCom/osi/os/vxWorks/drvVxTime.c delete mode 100644 src/libCom/osi/os/vxWorks/drvVxTime.h create mode 100644 src/libCom/osi/os/vxWorks/iocClock.c create mode 100644 src/libCom/osi/os/vxWorks/iocClock.h diff --git a/src/libCom/osi/os/vxWorks/drvNTPTime.c b/src/libCom/osi/os/vxWorks/drvNTPTime.c deleted file mode 100644 index 290cbd6d0..000000000 --- a/src/libCom/osi/os/vxWorks/drvNTPTime.c +++ /dev/null @@ -1,245 +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. -\*************************************************************************/ -/* iocClock.c */ - -/* Author: Marty Kraimer Date: 16JUN2000 */ - -/* This file is originally named as iocClock.c and provide the NTP time - * as default time source if no other time source registered during initialization. - * Now we made some minor change to add this to the time provider list */ - -/* Sheng Peng @ SNS ORNL 07/2004 */ -/* Version 1.1 */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "epicsTypes.h" -#include "cantProceed.h" -#include "errlog.h" -#include "epicsThread.h" -#include "epicsMutex.h" -#include "epicsTime.h" -#include "envDefs.h" - -#define BILLION 1000000000 -#define NTPTimeSyncInterval 10.0 - -#define NTPTIME_DRV_VERSION "NTPTime Driver Version 1.2" - -#include "epicsGeneralTime.h" - -static void NTPTimeSyncNTP(void); -static int NTPTimeGetCurrent(epicsTimeStamp *pDest); - -long NTPTime_Report(int level); - -typedef struct NTPTimePvt { - int synced; /* if never synced, we can't use it */ - epicsMutexId lock; - epicsTimeStamp clock; - unsigned long lastTick; - epicsUInt32 nanosecondsPerTick; - int tickRate; - int ticksToSkip; - const char *pserverAddr; -}NTPTimePvt; -static NTPTimePvt *pNTPTimePvt = 0; -static int nConsecutiveBad = 0; - -extern char* sysBootLine; - -static void NTPTimeSyncNTP(void) -{ - struct timespec Currtime; - epicsTimeStamp epicsTime; - int status; - int prevStatusBad = 0; - - while(1) { - double diffTime; - epicsThreadSleep(NTPTimeSyncInterval); - pNTPTimePvt->tickRate = sysClkRateGet(); - status = sntpcTimeGet((char *)pNTPTimePvt->pserverAddr, - pNTPTimePvt->tickRate,&Currtime); - if(status) { - ++nConsecutiveBad; - /*wait 1 minute before reporting failure*/ - if(nConsecutiveBad<(60/NTPTimeSyncInterval)) continue; - if(!prevStatusBad) - errlogPrintf("NTPTimeSyncWithNTPserver: sntpcTimeGet %s\n", - strerror(errno)); - prevStatusBad = 1; - pNTPTimePvt->synced = FALSE; - continue; - } - nConsecutiveBad=0; - if(prevStatusBad) { - errlogPrintf("NTPTimeSyncWithNTPserver: sntpcTimeGet OK\n"); - prevStatusBad = 0; - } - epicsTimeFromTimespec(&epicsTime,&Currtime); - epicsMutexMustLock(pNTPTimePvt->lock); - diffTime = epicsTimeDiffInSeconds(&epicsTime,&pNTPTimePvt->clock); - if(diffTime>=0.0) { - pNTPTimePvt->clock = epicsTime; - pNTPTimePvt->ticksToSkip = 0;/* fix bug here */ - } else {/*dont go back in time*/ - pNTPTimePvt->ticksToSkip = (int) ((-1)*diffTime*pNTPTimePvt->tickRate);/* fix bug here */ - } - pNTPTimePvt->lastTick = tickGet(); - pNTPTimePvt->synced = TRUE; - epicsMutexUnlock(pNTPTimePvt->lock); - } -} - -static long NTPTime_InitOnce(int priority) -{ - int status; - struct timespec Currtime; - epicsTimeStamp epicsTime; - - pNTPTimePvt = callocMustSucceed(1,sizeof(NTPTimePvt),"NTPTime_Init"); - - memset(pNTPTimePvt, 0, sizeof(NTPTimePvt)); - pNTPTimePvt->synced = FALSE; - pNTPTimePvt->lock = epicsMutexCreate(); - pNTPTimePvt->nanosecondsPerTick = BILLION/sysClkRateGet(); - pNTPTimePvt->tickRate = sysClkRateGet(); - /* look first for environment variable or CONFIG_SITE_ENV default */ - pNTPTimePvt->pserverAddr = envGetConfigParamPtr(&EPICS_TS_NTP_INET); - if(!pNTPTimePvt->pserverAddr) { /* if neither, use the boot host */ - BOOT_PARAMS bootParms; - static char host_addr[BOOT_ADDR_LEN]; - bootStringToStruct(sysBootLine,&bootParms); - /* bootParms.had = host IP address */ - strncpy(host_addr,bootParms.had,BOOT_ADDR_LEN); - pNTPTimePvt->pserverAddr = host_addr; - } - if(!pNTPTimePvt->pserverAddr) { - errlogPrintf("No NTP server is defined. Clock does not work\n"); - return -1; - } - /* if TIMEZONE not defined, set it from EPICS_TIMEZONE */ - if (getenv("TIMEZONE") == NULL) { - const char *timezone = envGetConfigParamPtr(&EPICS_TIMEZONE); - if(timezone == NULL) { - printf("NTPTime_Init: No Time Zone Information\n"); - } else { - epicsEnvSet("TIMEZONE",timezone); - } - } - - /* try to sync with NTP server once here */ - pNTPTimePvt->tickRate = sysClkRateGet(); - status = sntpcTimeGet((char *)pNTPTimePvt->pserverAddr,pNTPTimePvt->tickRate,&Currtime); - if(status) - {/* sync failed */ - printf("First try to sync with NTP server failed!\n"); - } - else - {/* sync OK */ - epicsTimeFromTimespec(&epicsTime,&Currtime); - epicsMutexMustLock(pNTPTimePvt->lock); - pNTPTimePvt->clock = epicsTime; - pNTPTimePvt->lastTick = tickGet(); - pNTPTimePvt->synced = TRUE; - epicsMutexUnlock(pNTPTimePvt->lock); - printf("First try to sync with NTP server succeed!\n"); - } - - epicsThreadCreate("NTPTimeSyncNTP", - epicsThreadPriorityHigh, - epicsThreadGetStackSize(epicsThreadStackSmall), - (EPICSTHREADFUNC)NTPTimeSyncNTP,0); - - /* register to link list */ - generalTimeCurrentTpRegister("NTP", priority, NTPTimeGetCurrent); - - return 0; -} - -struct InitInfo { - int priority; - long retval; -}; -static void NTPTime_InitOnceWrapper(void *arg) -{ - struct InitInfo *pargs = (struct InitInfo *)arg; - pargs->retval = NTPTime_InitOnce(pargs->priority); -} - -long NTPTime_Init(int priority) -{ - struct InitInfo args; - static epicsThreadOnceId onceId = EPICS_THREAD_ONCE_INIT; - - args.priority = priority; - epicsThreadOnce(&onceId, NTPTime_InitOnceWrapper, &args); - return args.retval; -} - -static int NTPTimeGetCurrent(epicsTimeStamp *pDest) -{ - unsigned long currentTick,nticks,nsecs; - - if(!pNTPTimePvt->synced) return epicsTimeERROR; - - epicsMutexMustLock(pNTPTimePvt->lock); - currentTick = tickGet(); - while(currentTick!=pNTPTimePvt->lastTick) { - nticks = (currentTick>pNTPTimePvt->lastTick) - ? (currentTick - pNTPTimePvt->lastTick) - : (currentTick + (ULONG_MAX - pNTPTimePvt->lastTick)); - if(pNTPTimePvt->ticksToSkip>0) {/*dont go back in time*/ - if(nticksticksToSkip) { - /*pNTPTimePvt->ticksToSkip -= nticks;*/ /* fix bug here */ - break; - } - nticks -= pNTPTimePvt->ticksToSkip; - pNTPTimePvt->ticksToSkip = 0; /* fix bug here */ - } - pNTPTimePvt->lastTick = currentTick; - pNTPTimePvt->tickRate = sysClkRateGet(); - nsecs = nticks/pNTPTimePvt->tickRate; - nticks = nticks - nsecs*pNTPTimePvt->tickRate; - pNTPTimePvt->clock.nsec += nticks * pNTPTimePvt->nanosecondsPerTick; - if(pNTPTimePvt->clock.nsec>=BILLION) { - ++nsecs; - pNTPTimePvt->clock.nsec -= BILLION; - } - pNTPTimePvt->clock.secPastEpoch += nsecs; - } - *pDest = pNTPTimePvt->clock; - epicsMutexUnlock(pNTPTimePvt->lock); - return(0); -} - -long NTPTime_Report(int level) -{ - printf(NTPTIME_DRV_VERSION"\n"); - - if(!pNTPTimePvt) - {/* drvNTPTime is not used, we just report version then quit */ - printf("NTP time driver is not initialized yet!\n\n"); - } - else - { - printf("\n"); - } - return 0; -} diff --git a/src/libCom/osi/os/vxWorks/drvNTPTime.h b/src/libCom/osi/os/vxWorks/drvNTPTime.h deleted file mode 100644 index 4242f26b5..000000000 --- a/src/libCom/osi/os/vxWorks/drvNTPTime.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _INC_drvDevNTPTime -#define _INC_drvDevNTPTime - -#ifdef __cplusplus -extern "C" { -#endif - -long NTPTime_Init(int); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/libCom/osi/os/vxWorks/drvVxTime.c b/src/libCom/osi/os/vxWorks/drvVxTime.c deleted file mode 100644 index e0db59376..000000000 --- a/src/libCom/osi/os/vxWorks/drvVxTime.c +++ /dev/null @@ -1,217 +0,0 @@ -/* Sheng Peng @ SNS ORNL 07/2004 */ -/* Version 1.1 */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "epicsTypes.h" -#include "cantProceed.h" -#include "errlog.h" -#include "epicsThread.h" -#include "osdThread.h" -#include "epicsMutex.h" -#include "epicsTime.h" -#include "epicsTimer.h" -#include "epicsInterrupt.h" -#include "envDefs.h" - -#include -#include -#include - -#define BILLION 1000000000 -#define VXWORKS_TO_EPICS_EPOCH 631152000UL - -#define VXTIME_DRV_VERSION "vxWorks Ticks Time Driver Version 1.2" -#define SYNC_PERIOD 60.0 - -#include "epicsGeneralTime.h" - -static void VxTimeSyncTime(void *param); -static int VxTimeGetCurrent(epicsTimeStamp *pDest); -static void VxTime_StartSync(int junk); - -long VxTime_Report(int level); - -typedef struct VxTimePvt { - int synced; /* if never synced, we can't use it */ - epicsMutexId lock; - epicsTimerId sync_timer; - epicsTimeStamp lastReportedTS; - epicsTimeStamp lastSyncedTS; - struct timespec lastSyncedVxTime; - int priority; - int synced_priority; -}VxTimePvt; - -static VxTimePvt *pVxTimePvt = 0; - -static void VxTimeSyncTime(void *param) -{ - epicsTimeStamp now; - struct timespec ticks_now; - - /* Ask for the best time available, not including ourselves */ - if (generalTimeGetExceptPriority(&now, &pVxTimePvt->synced_priority, pVxTimePvt->priority) == epicsTimeOK) { - /* It's a good time, we unconditionally sync ourselves to it, as - this driver is the bottom of the heap */ - clock_gettime( CLOCK_REALTIME,&ticks_now ); - - epicsMutexMustLock(pVxTimePvt->lock); - pVxTimePvt->lastSyncedTS = now; - pVxTimePvt->lastSyncedVxTime = ticks_now; - pVxTimePvt->synced = TRUE; - epicsMutexUnlock(pVxTimePvt->lock); - } - /* Restart the timer, to call us again in SYNC_PERIOD seconds */ - epicsTimerStartDelay(pVxTimePvt->sync_timer, SYNC_PERIOD); -} - -long VxTime_InitOnce(int priority) -{ - pVxTimePvt = callocMustSucceed(1,sizeof(VxTimePvt),"VxTime_Init"); - memset(pVxTimePvt, 0, sizeof(VxTimePvt)); - pVxTimePvt->synced = FALSE; - pVxTimePvt->lock = epicsMutexCreate(); - pVxTimePvt->priority = priority; - - /* register to link list */ - generalTimeCurrentTpRegister("vxWorks Ticks", priority, VxTimeGetCurrent); - - /* Don't start the syncing until the time system is up properly. - * This cannot be done using EPICS initHooks, as they are external - * to libCom, but this code is vxWorks-specific anyway, so use the - * vxWorks primitives. wdLib (watchdogs cannot be used as the called - * routines cannot take semaphores. */ - taskSpawn("VxTime Start Sync", 150, VX_FP_TASK, - epicsThreadGetStackSize(epicsThreadStackMedium), - (FUNCPTR) VxTime_StartSync, 0,0,0,0,0,0,0,0,0,0); - - return 0; -} - -struct InitInfo { - int priority; - long retval; -}; -static void VxTime_InitOnceWrapper(void *arg) -{ - struct InitInfo *pargs = (struct InitInfo *)arg; - pargs->retval = VxTime_InitOnce(pargs->priority); -} - -long VxTime_Init(int priority) -{ - struct InitInfo args; - static epicsThreadOnceId onceId = EPICS_THREAD_ONCE_INIT; - - args.priority = priority; - epicsThreadOnce(&onceId, VxTime_InitOnceWrapper, &args); - return args.retval; -} - -static int VxTimeGetCurrent(epicsTimeStamp *pDest) -{ - struct timespec cur_vwtime; - unsigned long diff_sec, diff_nsec; - epicsTimeStamp epicsTime; - - double diffTime; - - epicsMutexMustLock(pVxTimePvt->lock); - - clock_gettime( CLOCK_REALTIME,&cur_vwtime ); - - if(!pVxTimePvt->synced) - { - if( cur_vwtime.tv_sec < VXWORKS_TO_EPICS_EPOCH ) - { /* Earlier than 1990 is clearly wrong. Set the time to 1/1/90 - + 1 day (to avoid timezone problems) and set the VxWorks - clock to that point */ - cur_vwtime.tv_sec = VXWORKS_TO_EPICS_EPOCH + 86400; - cur_vwtime.tv_nsec = 0; - clock_settime( CLOCK_REALTIME, &cur_vwtime); - epicsInterruptContextMessage("****************************" - "***************************************************\n" - "WARNING: VxWorks time not set. Initialised to 2/1/90\n" - "*****************************************************" - "**************************\n"); - } - epicsTimeFromTimespec(&epicsTime, &cur_vwtime); - } - else/* synced, need calculation */ - {/* the vxWorks time is always monotonic */ - if( cur_vwtime.tv_nsec >= pVxTimePvt->lastSyncedVxTime.tv_nsec ) - { - diff_sec = cur_vwtime.tv_sec - pVxTimePvt->lastSyncedVxTime.tv_sec; - diff_nsec = cur_vwtime.tv_nsec - pVxTimePvt->lastSyncedVxTime.tv_nsec; - } - else - { - diff_sec = cur_vwtime.tv_sec - pVxTimePvt->lastSyncedVxTime.tv_sec - 1; - diff_nsec = BILLION - pVxTimePvt->lastSyncedVxTime.tv_nsec + cur_vwtime.tv_nsec; - } - - epicsTime.nsec = pVxTimePvt->lastSyncedTS.nsec + diff_nsec; - epicsTime.secPastEpoch = pVxTimePvt->lastSyncedTS.secPastEpoch + diff_sec; - if( epicsTime.nsec >= BILLION ) - { - epicsTime.nsec -= BILLION; - epicsTime.secPastEpoch ++; - } - } - - diffTime = epicsTimeDiffInSeconds(&epicsTime,&pVxTimePvt->lastReportedTS); - if(diffTime >= 0.0) - {/* time is monotonic */ - *pDest = epicsTime; - pVxTimePvt->lastReportedTS = epicsTime; - } - else - {/* time never goes back */ - *pDest = pVxTimePvt->lastReportedTS; - } - - epicsMutexUnlock(pVxTimePvt->lock); - return(0); -} - -long VxTime_Report(int level) -{ - printf(VXTIME_DRV_VERSION"\n"); - - if(!pVxTimePvt) - {/* drvVxTime is not used, we just report version then quit */ - printf("vxWorks ticks time driver is not initialized yet!\n\n"); - } - else - { - printf("%synced. Last time = %lds, %ldns. ", - pVxTimePvt->synced ?"S":"Not s", - pVxTimePvt->lastSyncedVxTime.tv_sec, - pVxTimePvt->lastSyncedVxTime.tv_nsec); - printf("Timer = %p\n", pVxTimePvt->sync_timer); - } - return 0; -} - -static void VxTime_StartSync(int junk) -{ - /* Wait some time before trying to start the timer up */ - taskDelay(10 * sysClkRateGet()); - pVxTimePvt->sync_timer = generalTimeCreateSyncTimer(VxTimeSyncTime, 0); - /* Sync the first time in one second, then drop back to less frequently */ - epicsTimerStartDelay(pVxTimePvt->sync_timer, 1.0); -} diff --git a/src/libCom/osi/os/vxWorks/drvVxTime.h b/src/libCom/osi/os/vxWorks/drvVxTime.h deleted file mode 100644 index c2c6b7267..000000000 --- a/src/libCom/osi/os/vxWorks/drvVxTime.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _INC_drvVxTime -#define _INC_drvVxTime - -#ifdef __cplusplus -extern "C" { -#endif - -long VxTime_Init(int); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/libCom/osi/os/vxWorks/iocClock.c b/src/libCom/osi/os/vxWorks/iocClock.c new file mode 100644 index 000000000..5617b3ed0 --- /dev/null +++ b/src/libCom/osi/os/vxWorks/iocClock.c @@ -0,0 +1,219 @@ +/*************************************************************************\ +* 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. +\*************************************************************************/ +/* iocClock.c */ + +/* Author: Marty Kraimer Date: 16JUN2000 */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "epicsTypes.h" +#include "cantProceed.h" +#include "errlog.h" +#include "epicsThread.h" +#include "epicsMutex.h" +#include "epicsTime.h" +#include "iocClock.h" +#include "envDefs.h" + +#define BILLION 1000000000 +#define iocClockSyncRate 10.0 + +static int iocClockGetCurrent(epicsTimeStamp *pDest); +static int iocClockGetEvent(epicsTimeStamp *pDest, int eventNumber); + +typedef struct iocClockPvt { + epicsMutexId lock; + epicsTimeStamp clock; + unsigned long lastTick; + epicsUInt32 nanosecondsPerTick; + int tickRate; + int ticksToSkip; + pepicsTimeGetCurrent getCurrent; + pepicsTimeGetEvent getEvent; + const char *pserverAddr; +}iocClockPvt; +static iocClockPvt *piocClockPvt = 0; +static int nConsecutiveBad = 0; + +extern char* sysBootLine; + +static void syncNTP(void) +{ + struct timespec Currtime; + epicsTimeStamp epicsTime; + STATUS status; + int prevStatusBad = 0; + int firstTime=1; + + while(1) { + double diffTime; + if(!firstTime)epicsThreadSleep(iocClockSyncRate); + firstTime = 0; + status = sntpcTimeGet((char *)piocClockPvt->pserverAddr, + piocClockPvt->tickRate,&Currtime); + if(status) { + ++nConsecutiveBad; + /*wait 1 minute before reporting failure*/ + if(nConsecutiveBad<(60/iocClockSyncRate)) continue; + if(!prevStatusBad) + errlogPrintf("iocClockSyncWithNTPserver: sntpcTimeGet %s\n", + strerror(errno)); + prevStatusBad = 1; + continue; + } + nConsecutiveBad=0; + if(prevStatusBad) { + errlogPrintf("iocClockSyncWithNTPserver: sntpcTimeGet OK\n"); + prevStatusBad = 0; + } + epicsTimeFromTimespec(&epicsTime,&Currtime); + epicsMutexMustLock(piocClockPvt->lock); + diffTime = epicsTimeDiffInSeconds(&epicsTime,&piocClockPvt->clock); + if(diffTime>=0.0) { + piocClockPvt->clock = epicsTime; + } else {/*dont go back in time*/ + piocClockPvt->ticksToSkip = (int) (diffTime*piocClockPvt->tickRate); + } + piocClockPvt->lastTick = tickGet(); + epicsMutexUnlock(piocClockPvt->lock); + } +} + +void iocClockInit() +{ + if(piocClockPvt) return; + piocClockPvt = callocMustSucceed(1,sizeof(iocClockPvt),"iocClockInit"); + piocClockPvt->lock = epicsMutexCreate(); + piocClockPvt->nanosecondsPerTick = BILLION/sysClkRateGet(); + piocClockPvt->tickRate = sysClkRateGet(); + piocClockPvt->getCurrent = iocClockGetCurrent; + piocClockPvt->getEvent = iocClockGetEvent; + /* look first for environment variable or CONFIG_SITE_ENV default */ + piocClockPvt->pserverAddr = envGetConfigParamPtr(&EPICS_TS_NTP_INET); + if(!piocClockPvt->pserverAddr) { /* if neither, use the boot host */ + BOOT_PARAMS bootParms; + static char host_addr[BOOT_ADDR_LEN]; + bootStringToStruct(sysBootLine,&bootParms); + /* bootParms.had = host IP address */ + strncpy(host_addr,bootParms.had,BOOT_ADDR_LEN); + piocClockPvt->pserverAddr = host_addr; + } + if(!piocClockPvt->pserverAddr) { + errlogPrintf("No NTP server is defined. Clock does not work\n"); + return; + } + /* if TIMEZONE not defined, set it from EPICS_TIMEZONE */ + if (getenv("TIMEZONE") == NULL) { + const char *timezone = envGetConfigParamPtr(&EPICS_TIMEZONE); + if(timezone == NULL) { + printf("iocClockInit: No Time Zone Information\n"); + } else { + char envtimezone[100]; + sprintf(envtimezone,"TIMEZONE=%s",timezone); + if(putenv(envtimezone)==ERROR) { + printf("iocClockInit: TIMEZONE putenv failed\n"); + } + } + } + epicsThreadCreate("syncNTP", + epicsThreadPriorityHigh, + epicsThreadGetStackSize(epicsThreadStackSmall), + (EPICSTHREADFUNC)syncNTP,0); + return; +} + +void iocClockRegister(pepicsTimeGetCurrent getCurrent, + pepicsTimeGetEvent getEvent) +{ + if(piocClockPvt) { + printf("iocClockRegister: iocClock already initialized\n"); + return; + } + piocClockPvt = callocMustSucceed(1,sizeof(iocClockPvt),"iocClockRegister"); + piocClockPvt->getCurrent = getCurrent; + piocClockPvt->getEvent = getEvent; +} + +int iocClockGetCurrent(epicsTimeStamp *pDest) +{ + unsigned long currentTick,nticks,nsecs; + + epicsMutexMustLock(piocClockPvt->lock); + currentTick = tickGet(); + while(currentTick!=piocClockPvt->lastTick) { + nticks = (currentTick>piocClockPvt->lastTick) + ? (currentTick - piocClockPvt->lastTick) + : (currentTick + (ULONG_MAX - piocClockPvt->lastTick)); + if(piocClockPvt->ticksToSkip>0) {/*dont go back in time*/ + if(nticksticksToSkip) { + piocClockPvt->ticksToSkip -= nticks; + break; + } + nticks -= piocClockPvt->ticksToSkip; + } + piocClockPvt->lastTick = currentTick; + nsecs = nticks/piocClockPvt->tickRate; + nticks = nticks - nsecs*piocClockPvt->tickRate; + piocClockPvt->clock.nsec += nticks * piocClockPvt->nanosecondsPerTick; + if(piocClockPvt->clock.nsec>=BILLION) { + ++nsecs; + piocClockPvt->clock.nsec -= BILLION; + } + piocClockPvt->clock.secPastEpoch += nsecs; + } + *pDest = piocClockPvt->clock; + epicsMutexUnlock(piocClockPvt->lock); + return(0); +} + +int iocClockGetEvent(epicsTimeStamp *pDest, int eventNumber) +{ + if (eventNumber==epicsTimeEventCurrentTime) { + *pDest = piocClockPvt->clock; + return(0); + } + return(epicsTimeERROR); +} + +int epicsTimeGetCurrent (epicsTimeStamp *pDest) +{ + if(!piocClockPvt) { + iocClockInit(); + /*wait two seconds for syncNTP to contact network time server*/ + epicsThreadSleep(2.0); + } + if(piocClockPvt->getCurrent) return((*piocClockPvt->getCurrent)(pDest)); + return(epicsTimeERROR); +} + +int epicsTimeGetEvent (epicsTimeStamp *pDest, int eventNumber) +{ + if(!piocClockPvt) { + iocClockInit(); + /*wait two seconds for syncNTP to contact network time server*/ + epicsThreadSleep(2.0); + } + if(piocClockPvt->getEvent) + return((*piocClockPvt->getEvent)(pDest,eventNumber)); + return(epicsTimeERROR); +} + diff --git a/src/libCom/osi/os/vxWorks/iocClock.h b/src/libCom/osi/os/vxWorks/iocClock.h new file mode 100644 index 000000000..91b6813dc --- /dev/null +++ b/src/libCom/osi/os/vxWorks/iocClock.h @@ -0,0 +1,20 @@ +/*************************************************************************\ +* 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. +\*************************************************************************/ +/* iocClock.h */ + +/* Author: Marty Kraimer Date: 16JUN2000 */ + +#include "epicsTime.h" + +typedef int (*pepicsTimeGetCurrent)(epicsTimeStamp *pDest); +typedef int (*pepicsTimeGetEvent)(epicsTimeStamp *pDest,int eventNumber); + +void iocClockInit(void); +void iocClockRegister(pepicsTimeGetCurrent getCurrent,pepicsTimeGetEvent getEvent);