General time changes.

This commit is contained in:
W. Eric Norum
2008-04-14 20:08:39 +00:00
parent 5e51fdaa91
commit 6254f0d730
3 changed files with 25 additions and 210 deletions

View File

@@ -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)

View File

@@ -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);
}

View File

@@ -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);