General time changes.
This commit is contained in:
@@ -40,14 +40,13 @@
|
||||
#include "epicsGeneralTime.h"
|
||||
|
||||
static void VxTimeSyncTime(void *param);
|
||||
long VxTime_Init(int priority);
|
||||
static int VxTimeGetCurrent(epicsTimeStamp *pDest);
|
||||
static void VxTime_StartSync(int junk);
|
||||
|
||||
long VxTime_Report(int level);
|
||||
|
||||
typedef struct VxTimePvt {
|
||||
BOOL synced; /* if never synced, we can't use it */
|
||||
int synced; /* if never synced, we can't use it */
|
||||
epicsMutexId lock;
|
||||
epicsTimerId sync_timer;
|
||||
epicsTimeStamp lastReportedTS;
|
||||
@@ -80,17 +79,10 @@ static void VxTimeSyncTime(void *param)
|
||||
epicsTimerStartDelay(pVxTimePvt->sync_timer, SYNC_PERIOD);
|
||||
}
|
||||
|
||||
long VxTime_Init(int priority)
|
||||
long VxTime_InitOnce(int priority)
|
||||
{
|
||||
taskLock();
|
||||
if(pVxTimePvt) {
|
||||
taskUnlock();
|
||||
return OK;
|
||||
}
|
||||
pVxTimePvt = callocMustSucceed(1,sizeof(VxTimePvt),"VxTime_Init");
|
||||
taskUnlock();
|
||||
|
||||
bzero((char *)pVxTimePvt, sizeof(VxTimePvt));
|
||||
memset(pVxTimePvt, 0, sizeof(VxTimePvt));
|
||||
pVxTimePvt->synced = FALSE;
|
||||
pVxTimePvt->lock = epicsMutexCreate();
|
||||
pVxTimePvt->priority = priority;
|
||||
@@ -107,7 +99,27 @@ long VxTime_Init(int priority)
|
||||
epicsThreadGetStackSize(epicsThreadStackMedium),
|
||||
(FUNCPTR) VxTime_StartSync, 0,0,0,0,0,0,0,0,0,0);
|
||||
|
||||
return OK;
|
||||
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)
|
||||
@@ -192,7 +204,7 @@ long VxTime_Report(int level)
|
||||
pVxTimePvt->lastSyncedVxTime.tv_nsec);
|
||||
printf("Timer = %p\n", pVxTimePvt->sync_timer);
|
||||
}
|
||||
return OK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void VxTime_StartSync(int junk)
|
||||
|
||||
@@ -1,180 +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 */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <vxWorks.h>
|
||||
#include <bootLib.h>
|
||||
#include <tickLib.h>
|
||||
#include <sysLib.h>
|
||||
#include <sntpcLib.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <envLib.h>
|
||||
|
||||
#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;
|
||||
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();
|
||||
/* 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;
|
||||
}
|
||||
|
||||
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(nticks<piocClockPvt->ticksToSkip) {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -1,17 +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.h */
|
||||
|
||||
/* Author: Marty Kraimer Date: 16JUN2000 */
|
||||
|
||||
#include "epicsTime.h"
|
||||
#include "epicsGeneralTime.h"
|
||||
|
||||
void iocClockInit(void);
|
||||
Reference in New Issue
Block a user