34 #undef DEBUG_GENERAL_TIME 36 #ifdef DEBUG_GENERAL_TIME 37 int generalTimeDebug = 10;
39 if (generalTimeDebug >= n) 78 static const char *
const tsfmt =
"%Y-%m-%d %H:%M:%S.%09f";
83 static int useOsdGetCurrent = 1;
87 static void generalTime_InitOnce(
void *
dummy)
96 printf("General Time Initialized\n");
116 printf(
"generalTimeGetExceptPriority(ignore=%d)\n", ignore);
121 if ((ignore > 0 && ptp->
priority == ignore) ||
122 (ignore < 0 && ptp->priority != -ignore))
133 printf(
"gTGExP provider '%s' returned error\n", ptp->
name);
142 printf(
"gTGExP returning %s from provider '%s'\n",
146 printf(
"gTGExP returning error\n");
164 printf(
"epicsTimeGetCurrent()\n");
175 gtPvt.lastProvidedTime = ts;
176 gtPvt.lastTimeProvider = ptp;
180 *pDest = gtPvt.lastProvidedTime;
186 char last[40], buff[40];
189 >Pvt.lastProvidedTime);
191 printf(
"eTGC provider '%s' returned older time\n" 192 " %s, using %s instead\n", ptp->
name, buff, last);
199 gtPvt.lastTimeProvider =
NULL;
207 printf(
"eTGC returning %s from provider '%s'\n",
211 printf(
"eTGC returning error\n");
220 pDest->
nsec = now%1000000000ul;
240 static int generalTimeGetEventPriority(
epicsTimeStamp *pDest,
int eventNumber,
251 printf(
"generalTimeGetEventPriority(eventNum=%d)\n", eventNumber);
260 status = ptp->
get.
Event(&ts, eventNumber);
262 gtPvt.lastEventProvider = ptp;
270 >Pvt.lastProvidedBestTime)) {
272 gtPvt.lastProvidedBestTime = ts;
276 *pDest = gtPvt.lastProvidedBestTime;
282 char last[40], buff[40];
285 >Pvt.lastProvidedBestTime);
287 printf(
"gTGEvP provider '%s' returned older time\n" 288 " %s, using %s instead\n",
289 ptp->
name, buff, last);
294 >Pvt.eventTime[eventNumber])) {
296 gtPvt.eventTime[eventNumber] = ts;
300 *pDest = gtPvt.eventTime[eventNumber];
306 char last[40], buff[40];
309 >Pvt.lastProvidedBestTime);
311 printf(
"gTGEvP provider '%s' returned older time\n" 312 " %s, using %s instead\n",
313 ptp->
name, buff, last);
320 printf(
"gTGEvP provider '%s' returned error\n", ptp->
name);
323 gtPvt.lastEventProvider =
NULL;
331 printf(
"gTGEvP returning %s from provider '%s'\n",
335 printf(
"gTGEvP returning error\n");
346 return generalTimeGetEventPriority(pDest, eventNumber,
NULL);
393 useOsdGetCurrent = 0;
400 const char *name,
int priority)
409 !strcmp(ptp->
name, name))
424 if (name ==
NULL || getEvent ==
NULL)
436 insertProvider(ptp, >Pvt.eventProviders, gtPvt.eventListLock);
439 printf(
"Registered event provider '%s' at %d\n", name, priority);
447 gtProvider *ptp = findProvider(>Pvt.eventProviders, gtPvt.eventListLock,
455 printf(
"Event provider '%s' is interrupt-callable\n", name);
467 if (name ==
NULL || getTime ==
NULL)
479 insertProvider(ptp, >Pvt.timeProviders, gtPvt.timeListLock);
482 printf(
"Registered time provider '%s' at %d\n", name, priority);
490 gtProvider *ptp = findProvider(>Pvt.timeProviders, gtPvt.timeListLock,
498 printf(
"Time provider '%s' is interrupt-callable\n", name);
515 static int lastResortGetEvent(
epicsTimeStamp *timeStamp,
int eventNumber)
534 printf(
"General time framework not yet initialized.\n");
538 printf(
"Backwards time errors prevented %u times.\n\n",
543 printf(
"Current Time Providers:\n");
545 if ((items =
ellCount(>Pvt.timeProviders))) {
550 message = calloc(items, 80 * 2);
553 printf(
"Out of memory\n");
561 pout += sprintf(pout,
" \"%s\", priority = %d\n",
568 "%Y-%m-%d %H:%M:%S.%06f", &tempTS);
569 pout += sprintf(pout,
"\tCurrent Time is %s.\n",
572 pout += sprintf(pout,
"\tCurrent Time not available\n");
581 printf(
"\tNo Providers registered.\n");
584 printf(
"Event Time Providers:\n");
586 if ((items =
ellCount(>Pvt.eventProviders)))
592 message = calloc(items, 80);
595 printf(
"Out of memory\n");
603 pout += sprintf(pout,
" \"%s\", priority = %d\n",
613 printf(
"\tNo Providers registered.\n");
626 gtPvt.ErrorCounts = 0;
633 int errors = gtPvt.ErrorCounts;
640 if (gtPvt.lastTimeProvider)
641 return gtPvt.lastTimeProvider->name;
647 if (gtPvt.lastEventProvider)
648 return gtPvt.lastEventProvider->name;
The generalTime framework provides a mechanism for several time providers to be present within the sy...
const char * generalTimeCurrentProviderName(void)
Return the nume of the provider that last returned a valid current time, or NULL if none...
int generalTimeRegisterCurrentProvider(const char *name, int priority, TIMECURRENTFUN getTime)
LIBCOM_API void epicsInterruptUnlock(int key)
#define ellCount(PLIST)
Report the number of nodes in a list.
epicsMutexId timeListLock
gtProvider * lastEventProvider
const char * generalTimeHighestCurrentName(void)
Return the name of the registered current time provider that has the highest priority.
epicsMutexId eventListLock
LIBCOM_API epicsUInt64 epicsMonotonicGet(void)
Fetch monotonic counter, returns the number of nanoseconds since some unspecified time...
int(* TIMECURRENTFUN)(epicsTimeStamp *pDest)
union gtProvider::@15 get
Routines to get and set EPICS environment parameters.
#define epicsMutexMustCreate()
Create an epicsMutex semaphore for use from C code.
union gtProvider::@16 getInt
#define epicsTimeOK
Success.
#define NUM_TIME_EVENTS
The number of time events that are validated.
void epicsStdCall epicsMutexUnlock(epicsMutexId pmutexNode)
Release the semaphore.
#define ellPrevious(PNODE)
Find the previous node in list.
LIBCOM_API int epicsInterruptLock(void)
epicsTimeStamp eventTime[NUM_TIME_EVENTS]
epicsUInt32 secPastEpoch
seconds since 0000 Jan 1, 1990
unsigned long long epicsUInt64
int generalTimeAddIntCurrentProvider(const char *name, int priority, TIMECURRENTFUN getTime)
A doubly-linked list library.
void ellAdd(ELLLIST *pList, ELLNODE *pNode)
Adds a node to the end of a list.
int osdTimeGetCurrent(epicsTimeStamp *pDest)
#define generalTimeEventTpRegister
#define ellNext(PNODE)
Find the next node in list.
LIBCOM_API size_t epicsStdCall epicsTimeToStrftime(char *pBuff, size_t bufLength, const char *pFormat, const epicsTimeStamp *pTS)
Convert epicsTimeStamp to string. See epicsTime::strftime()
#define EPICS_THREAD_ONCE_INIT
int epicsTimeGetMonotonic(epicsTimeStamp *pDest)
Get monotonic time into *pDest.
LIBCOM_API int epicsStdCall epicsTimeGreaterThanEqual(const epicsTimeStamp *pLeft, const epicsTimeStamp *pRight)
right was not before left
#define S_time_badArgs
Invalid arguments.
#define STATIC_ASSERT(expr)
Declare a condition that should be true at compile-time.
APIs for the epicsMutex mutual exclusion semaphore.
LIBCOM_API void epicsStdCall epicsThreadOnce(epicsThreadOnceId *id, EPICSTHREADFUNC, void *arg)
int epicsStdCall epicsTimeGetCurrent(epicsTimeStamp *pDest)
Get current time into *pDest.
#define S_time_badEvent
Bad event number.
const char * generalTimeEventProviderName(void)
Return the name of the provider that last returned a valid Time Event time, or NULL of none...
#define S_time_noMemory
Out of memory.
int generalTimeAddIntEventProvider(const char *name, int priority, TIMEEVENTFUN getEvent)
LIBCOM_API void epicsInterruptContextMessage(const char *message)
epicsTimeStamp lastProvidedBestTime
#define LAST_RESORT_PRIORITY
#define epicsTimeEventBestTime
void generalTime_Init(void)
Initialise the framework.
char * epicsStrDup(const char *s)
APIs for the epicsEvent binary semaphore.
epics::pvData::PVStructurePtr dummy
#define S_time_noProvider
No time provider.
int epicsTimeGetCurrentInt(epicsTimeStamp *pDest)
Get current time into *pDest (ISR-safe)
void generalTimeResetErrorCounts(void)
Reset the internal counter of the number of times the time returned was earlier than when previously ...
int generalTimeGetExceptPriority(epicsTimeStamp *pDest, int *pPrio, int ignore)
A C++ and a C facility for communication between threads.
EPICS time stamp, for use from C code.
int epicsStdCall epicsTimeGetEvent(epicsTimeStamp *pDest, int eventNumber)
Get time of event eventNumber into *pDest.
#define ellInit(PLIST)
Initialize a list type.
int(* TIMEEVENTFUN)(epicsTimeStamp *pDest, int event)
void ellInsert(ELLLIST *plist, ELLNODE *pPrev, ELLNODE *pNode)
Inserts a node into a list immediately after a specific node.
#define epicsTimeEventCurrentTime
int installLastResortEventProvider(void)
Install a Time Event time provider that returns the current time for any Time event number...
Routines for code that can't continue or return after an error.
EPICS time-stamps (epicsTimeStamp), epicsTime C++ class and C functions for handling wall-clock times...
C++ and C descriptions for a thread.
#define epicsMutexMustLock(ID)
Claim a semaphore (see epicsMutexLock()).
int generalTimeGetErrorCounts(void)
Return the internal counter of the number of times the time returned was earlier than when previously...
int epicsTimeGetEventInt(epicsTimeStamp *pDest, int eventNumber)
Get time of event eventNumber into *pDest (ISR-safe)
gtProvider * lastTimeProvider
epicsUInt32 nsec
nanoseconds within second
epicsTimeStamp lastProvidedTime
long generalTimeReport(int level)
Provide information about the installed providers and their current best times.
int generalTimeRegisterEventProvider(const char *name, int priority, TIMEEVENTFUN getEvent)
#define ellFirst(PLIST)
Find the first node in list.