From fa2a1395a00ee231abecdcbd861fac98b6cd95d2 Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Wed, 22 Dec 1999 23:12:51 +0000 Subject: [PATCH] o created tsStamp.h o include tsStamp.h into tsDefs.h o use assert() instead of C++ exceptions on certain os --- src/libCom/fdmgr/fdManager.cpp | 10 +- src/libCom/fdmgr/fdManager.h | 3 +- src/libCom/fdmgr/fdmgr.cpp | 158 ++++++++++++------- src/libCom/osi/os/WIN32/osdTime.cpp | 217 ++++++++++++++++++++------ src/libCom/osi/os/vxWorks/osdTime.cpp | 33 ++-- src/libCom/timer/osiTimer.cpp | 8 +- 6 files changed, 308 insertions(+), 121 deletions(-) diff --git a/src/libCom/fdmgr/fdManager.cpp b/src/libCom/fdmgr/fdManager.cpp index 43acbb7ff..942785b0c 100644 --- a/src/libCom/fdmgr/fdManager.cpp +++ b/src/libCom/fdmgr/fdManager.cpp @@ -310,8 +310,14 @@ epicsShareFunc void fdManager::installReg (fdReg ®) this->maxFD = tsMax(this->maxFD, reg.getFD()+1); this->regList.add (reg); reg.state = fdReg::pending; - if (this->fdTbl.add (reg)!=0) { - throw fdInterestSubscriptionAlreadyExits(); + + int status = this->fdTbl.add (reg); + if (status!=0) { +# ifdef noExceptionsFromCXX + assert (0); +# else + throw fdInterestSubscriptionAlreadyExits (); +# endif } } diff --git a/src/libCom/fdmgr/fdManager.h b/src/libCom/fdmgr/fdManager.h index 524be7b10..320287ed9 100644 --- a/src/libCom/fdmgr/fdManager.h +++ b/src/libCom/fdmgr/fdManager.h @@ -39,7 +39,7 @@ #include "shareLib.h" // reset share lib defines #include "tsDLList.h" #include "resourceLib.h" -#include "osiTime.h" +#include "tsStamp.h" #include "osiSock.h" static const unsigned hashTableIndexBits = 8; @@ -210,6 +210,5 @@ inline osiTimerQueue & fdManager::timerQueueRef () const return this->timerQueue; } - #endif // fdManagerH_included diff --git a/src/libCom/fdmgr/fdmgr.cpp b/src/libCom/fdmgr/fdmgr.cpp index 208253d02..c98844e82 100644 --- a/src/libCom/fdmgr/fdmgr.cpp +++ b/src/libCom/fdmgr/fdmgr.cpp @@ -70,14 +70,22 @@ epicsShareFunc fdRegForOldFdmgr::fdRegForOldFdmgr (const SOCKET fdIn, const fdRe pParam (pParamIn) { if (pFuncIn==NULL) { - throw noFunctionSpecified (); +# ifdef noExceptionsFromCXX + assert (0); +# else + throw noFunctionSpecified (); +# endif } } epicsShareFunc fdRegForOldFdmgr::~fdRegForOldFdmgr () { if (this->pFunc==NULL) { - throw doubleDelete (); +# ifdef noExceptionsFromCXX + assert (0); +# else + throw doubleDelete (); +# endif } } @@ -137,7 +145,11 @@ osiTimerForOldFdmgr::osiTimerForOldFdmgr (oldFdmgr &fdmgrIn, pFunc (pFuncIn), pParam(pParamIn) { if (pFuncIn==NULL) { - throw noFunctionSpecified (); +# ifdef noExceptionsFromCXX + assert (0); +# else + throw noFunctionSpecified (); +# endif } this->fdmgr.resTbl.add (*this); @@ -146,7 +158,11 @@ osiTimerForOldFdmgr::osiTimerForOldFdmgr (oldFdmgr &fdmgrIn, osiTimerForOldFdmgr::~osiTimerForOldFdmgr () { if (this->pFunc==NULL) { - throw doubleDelete (); +# ifdef noExceptionsFromCXX + assert (0); +# else + throw doubleDelete (); +# endif } this->pFunc = NULL; @@ -173,13 +189,17 @@ extern "C" epicsShareFunc fdctx * epicsShareAPI fdmgr_init (void) { oldFdmgr *pfdm; - try { +# ifdef noExceptionsFromCXX pfdm = new oldFdmgr(); - } - catch (...) - { - return NULL; - } +# else + try { + pfdm = new oldFdmgr(); + } + catch (...) + { + pfdm = NULL; + } +# endif return (fdctx *) pfdm; } @@ -196,27 +216,31 @@ extern "C" epicsShareFunc fdmgrAlarmId epicsShareAPI fdmgr_add_timeout ( return fdmgrNoAlarm; } - try { - while (true) { + while (true) { +# ifdef noExceptionsFromCXX pTimer = new osiTimerForOldFdmgr (*pfdm, delay, pFunc, pParam); - if (pTimer) { - id = pTimer->getId (); - if (id!=fdmgrNoAlarm) { - break; - } - else { - delete pTimer; - } +# else + try { + pTimer = new osiTimerForOldFdmgr (*pfdm, delay, pFunc, pParam); } - else { - id = fdmgrNoAlarm; + catch (...) + { + pTimer = NULL; + } +# endif + if (pTimer) { + id = pTimer->getId (); + if (id!=fdmgrNoAlarm) { break; } + else { + delete pTimer; + } + } + else { + id = fdmgrNoAlarm; + break; } - } - catch (...) - { - id = fdmgrNoAlarm; } return id; @@ -227,18 +251,25 @@ extern "C" epicsShareFunc int epicsShareAPI fdmgr_clear_timeout (fdctx *pfdctx, oldFdmgr *pfdm = static_cast (pfdctx); osiTimerForOldFdmgr *pTimer; - try { +# ifdef noExceptionsFromCXX pTimer = pfdm->resTbl.remove (id); - if (pTimer!=NULL) { - delete pTimer; +# else + try { + pTimer = pfdm->resTbl.remove (id); } - } - catch (...) - { + catch (...) + { + pTimer = NULL; + } +# endif + + if (pTimer==NULL) { return -1; } - - return 0; + else { + delete pTimer; + return 0; + } } extern "C" epicsShareFunc int epicsShareAPI fdmgr_add_callback ( @@ -260,18 +291,24 @@ extern "C" epicsShareFunc int epicsShareAPI fdmgr_add_callback ( return -1; } - try { +# ifdef noExceptionsFromCXX pfdrbc = new fdRegForOldFdmgr (fd, fdiToFdRegType[fdi], onceOnly, *pfdm, pFunc, pParam); - } - catch (...) - { - return -1; - } +# else + try { + pfdrbc = new fdRegForOldFdmgr (fd, fdiToFdRegType[fdi], onceOnly, *pfdm, pFunc, pParam); + } + catch (...) + { + pfdrbc = NULL; + } +# endif if (pfdrbc==NULL) { return -1; } - return 0; + else { + return 0; + } } extern "C" epicsShareFunc int epicsShareAPI fdmgr_clear_callback ( @@ -284,21 +321,25 @@ extern "C" epicsShareFunc int epicsShareAPI fdmgr_clear_callback ( return -1; } - try { +# ifdef noExceptionsFromCXX pFDR = pfdm->lookUpFD (fd, fdiToFdRegType[fdi]); - } - catch (...) - { - return -1; - } +# else + try { + pFDR = pfdm->lookUpFD (fd, fdiToFdRegType[fdi]); + } + catch (...) + { + pFDR = NULL; + } +# endif if (pFDR==NULL) { return -1; } - - delete pFDR; - - return 0; + else { + delete pFDR; + return 0; + } } extern "C" epicsShareFunc int epicsShareAPI fdmgr_pend_event (fdctx *pfdctx, struct timeval *ptimeout) @@ -306,12 +347,17 @@ extern "C" epicsShareFunc int epicsShareAPI fdmgr_pend_event (fdctx *pfdctx, str oldFdmgr *pfdm = static_cast (pfdctx); double delay = ptimeout->tv_sec + ptimeout->tv_usec / static_cast (osiTime::uSecPerSec); - try { +# ifdef noExceptionsFromCXX pfdm->process (delay); - } - catch (...) { - return -1; - } +# else + try { + pfdm->process (delay); + } + catch (...) { + return -1; + } +# endif + return 0; } diff --git a/src/libCom/osi/os/WIN32/osdTime.cpp b/src/libCom/osi/os/WIN32/osdTime.cpp index 75b9ca643..e3efab94d 100644 --- a/src/libCom/osi/os/WIN32/osdTime.cpp +++ b/src/libCom/osi/os/WIN32/osdTime.cpp @@ -28,7 +28,8 @@ // EPICS // #define epicsExportSharedSymbols -#include +#include "osiTime.h" +#include "errlog.h" // // performance counter last value, ticks per sec, @@ -55,28 +56,65 @@ static const SYSTEMTIME epicsEpochST = { 0 // milli sec }; +static const LONGLONG FILE_TIME_TICKS_PER_SEC = 10000000L; +static HANDLE osdTimeMutex = NULL; static LONGLONG epicsEpoch; -static LONGLONG FILE_TIME_TICKS_PER_SEC = 10000000L; +static int osdTimeSych (); /* - * synchronize() + * epicsWin32ThreadEntry() */ -void osiTime::synchronize() +static DWORD WINAPI osdTimeSynchThreadEntry (LPVOID) +{ + static const DWORD tmoTenSec = 10 * osiTime::mSecPerSec; + int status; + + while (1) { + Sleep (tmoTenSec); + status = osdTimeSych (); + if (status!=tsStampOK) { + errlogPrintf ("osdTimeSych (): failed?\n"); + } + } +} + +// +// osdTimeInit () +// +static void osdTimeInit () { - static int init = 0; - LONGLONG new_sec_offset, new_frac_offset; LARGE_INTEGER parm; - LONGLONG secondsSinceBoot; - FILETIME currentTimeFT; - LONGLONG currentTime; BOOL win32Stat; + int unixStyleStatus; // // one time initialization of constants // - if (!init) { + if (!osdTimeMutex) { + DWORD threadId; + HANDLE handle; FILETIME epicsEpochFT; + HANDLE mutex; + + mutex = CreateMutex (NULL, TRUE, "osdTimeMutex"); + if (mutex==NULL) { + return; + } + if ( GetLastError () == ERROR_ALREADY_EXISTS ) { + static const DWORD tmoTwentySec = 20 * osiTime::mSecPerSec; + DWORD semStatus; + + // + // synchronize with some other thread + // that is already in this routine + // + semStatus = WaitForSingleObject (osdTimeMutex, tmoTwentySec); + if ( semStatus == WAIT_OBJECT_0 ) { + ReleaseMutex (mutex); + } + return; + } // // initialize elapsed time counters @@ -85,7 +123,8 @@ void osiTime::synchronize() // counters (Intel and Mips processors do) // if (QueryPerformanceFrequency (&parm)==0) { - throw unableToFetchCurrentTime (); + CloseHandle (mutex); + return; } perf_freq = parm.QuadPart; @@ -94,14 +133,59 @@ void osiTime::synchronize() // win32Stat = SystemTimeToFileTime (&epicsEpochST, &epicsEpochFT); if (win32Stat==0) { - throw unableToFetchCurrentTime (); + CloseHandle (mutex); + return; } parm.LowPart = epicsEpochFT.dwLowDateTime; parm.HighPart = epicsEpochFT.dwHighDateTime; epicsEpoch = parm.QuadPart; - init = 1; + unixStyleStatus = osdTimeSych (); + if (unixStyleStatus!=tsStampOK) { + CloseHandle (mutex); + return; + } + + osdTimeMutex = mutex; + ReleaseMutex (mutex); + assert (win32Stat); + + // + // spawn off a thread which periodically resynchronizes the offset + // + handle = CreateThread (NULL, 4096, osdTimeSynchThreadEntry, + NULL, 0, &threadId); + if (handle==NULL) { + errlogPrintf ("osdTimeInit(): unable to start time synch thread\n");; + } } +} + +// +// osdTimeSych () +// +static int osdTimeSych () +{ + static const DWORD tmoTwentySec = 20 * osiTime::mSecPerSec; + LONGLONG new_sec_offset, new_frac_offset; + LARGE_INTEGER parm; + LONGLONG secondsSinceBoot; + FILETIME currentTimeFT; + LONGLONG currentTime; + BOOL win32Stat; + DWORD win32SemStat; + + if (!osdTimeMutex) { + osdTimeInit (); + if (!osdTimeMutex) { + return tsStampERROR; + } + } + + win32SemStat = WaitForSingleObject (osdTimeMutex, tmoTwentySec); + if ( win32SemStat != WAIT_OBJECT_0 ) { + return tsStampERROR; + } // // its important that the following two time queries @@ -112,7 +196,8 @@ void osiTime::synchronize() // this one is second because QueryPerformanceFrequency() // has forced its code to load if (QueryPerformanceCounter (&parm)==0) { - throw unableToFetchCurrentTime (); + ReleaseMutex (osdTimeMutex); + return tsStampERROR; } perf_last = parm.QuadPart; @@ -176,7 +261,6 @@ void osiTime::synchronize() new_frac_offset = 0; } - #if 0 // // calculate the change @@ -195,42 +279,62 @@ void osiTime::synchronize() // perf_sec_offset = new_sec_offset; perf_frac_offset = new_frac_offset; + + win32Stat = ReleaseMutex (osdTimeMutex); + if (!win32Stat) { + return tsStampERROR; + } + + return tsStampOK; } // // osiTime::osdGetCurrent () // -osiTime osiTime::osdGetCurrent () +extern "C" epicsShareFunc int epicsShareAPI tsStampGetCurrent (TS_STAMP *pDest) { + static const DWORD tmoTwentySec = 20 * osiTime::mSecPerSec; LONGLONG time_cur, time_sec, time_remainder; LARGE_INTEGER parm; - unsigned long sec, nsec; + BOOL status; - /* - * lazy init - */ - if (perf_sec_offset<0) { - osiTime::synchronize(); + // + // lazy init + // + if (!osdTimeMutex) { + osdTimeInit (); + if (!osdTimeMutex) { + return tsStampERROR; + } } - /* - * dont need to check status since it was checked once - * during initialization to see if the CPU has HR - * counters (Intel and Mips processors do) - */ - QueryPerformanceCounter (&parm); - time_cur = parm.QuadPart; - if (perf_last > time_cur) { /* must have been a timer roll-over */ + status = WaitForSingleObject (osdTimeMutex, tmoTwentySec); + if ( status != WAIT_OBJECT_0 ) { + return tsStampERROR; + } - /* - * must have been a timer roll-over - * It takes 9.223372036855e+18/perf_freq sec - * to roll over this counter (perf_freq is 1193182 - * sec on my system). This is currently about 245118 years. - * - * attempt to add number of seconds in a 64 bit integer - * in case the timer resolution improves - */ + // + // dont need to check status since it was checked once + // during initialization to see if the CPU has HR + // counters (Intel and Mips processors do) + // + status = QueryPerformanceCounter (&parm); + if (!status) { + ReleaseMutex (osdTimeMutex); + return tsStampERROR; + } + time_cur = parm.QuadPart; + if (perf_last > time_cur) { + + // + // must have been a timer roll-over + // It takes 9.223372036855e+18/perf_freq sec + // to roll over this counter (perf_freq is 1193182 + // sec on my system). This is currently about 245118 years. + // + // attempt to add number of seconds in a 64 bit integer + // in case the timer resolution improves + // perf_sec_offset += MAXLONGLONG / perf_freq; perf_frac_offset += MAXLONGLONG % perf_freq; if (perf_frac_offset>=perf_freq) { @@ -241,9 +345,9 @@ osiTime osiTime::osdGetCurrent () time_sec = time_cur / perf_freq; time_remainder = time_cur % perf_freq; - /* - * add time (sec) since the EPICS epoch - */ + // + // add time (sec) since the EPICS epoch + // time_sec += perf_sec_offset; time_remainder += perf_frac_offset; if (time_remainder>=perf_freq) { @@ -253,9 +357,28 @@ osiTime osiTime::osdGetCurrent () perf_last = time_cur; - sec = (unsigned long) (time_sec%ULONG_MAX); - nsec = (unsigned long) ((time_remainder*nSecPerSec)/perf_freq); - return osiTime (sec, nsec); + pDest->secPastEpoch = (unsigned long) (time_sec%ULONG_MAX); + pDest->nSec = (unsigned long) ((time_remainder*osiTime::nSecPerSec)/perf_freq); + + status = ReleaseMutex (osdTimeMutex); + if (!status) { + return tsStampERROR; + } + + return tsStampOK; +} + +// +// tsStampGetEvent () +// +extern "C" epicsShareFunc int epicsShareAPI tsStampGetEvent (TS_STAMP *pDest, unsigned eventNumber) +{ + if (eventNumber==tsStampEventCurrentTime) { + return tsStampGetCurrent (pDest); + } + else { + return tsStampERROR; + } } // @@ -287,7 +410,7 @@ struct tm *gmtime_r (const time_t *pAnsiTime, struct tm *pTM) win32Success = SetThreadPriority (thisThread, oldPriority); if (!win32Success) { - throw osiTime::internalFailure(); + return NULL; } return p; @@ -322,7 +445,7 @@ struct tm *localtime_r (const time_t *pAnsiTime, struct tm *pTM) win32Success = SetThreadPriority (thisThread, oldPriority); if (!win32Success) { - throw osiTime::internalFailure (); + return NULL; } return p; diff --git a/src/libCom/osi/os/vxWorks/osdTime.cpp b/src/libCom/osi/os/vxWorks/osdTime.cpp index 2bb50d54b..b9692b573 100644 --- a/src/libCom/osi/os/vxWorks/osdTime.cpp +++ b/src/libCom/osi/os/vxWorks/osdTime.cpp @@ -3,24 +3,31 @@ #define epicsExportSharedSymbols #include "osiTime.h" -// -// osiTime::synchronize() -// -void osiTime::synchronize() -{ -} - // // osiTime::osdGetCurrent () // -osiTime osiTime::osdGetCurrent () +extern "C" epicsShareFunc int tsStampGetCurrent (TS_STAMP *pDest) { - struct timespec ts; int status; + struct timespec ts; - status = clock_gettime(CLOCK_REALTIME, &ts); - if (status!=0) { - throw unableToFetchCurrentTime (); + status = clock_gettime (CLOCK_REALTIME, &ts); + if (status) { + return -1; + } + *pDest = osiTime (ts); + return 0; +} + +// +// tsStampGetEvent () +// +extern "C" epicsShareFunc int epicsShareAPI tsStampGetEvent (TS_STAMP *pDest, unsigned eventNumber) +{ + if (eventNumber==tsStampEventCurrentTime) { + return tsStampGetCurrent (pDest); + } + else { + return tsStampERROR; } - return osiTime (ts); } diff --git a/src/libCom/timer/osiTimer.cpp b/src/libCom/timer/osiTimer.cpp index beffa9ed9..9d9f21df3 100644 --- a/src/libCom/timer/osiTimer.cpp +++ b/src/libCom/timer/osiTimer.cpp @@ -39,6 +39,7 @@ #include #include +#include #define epicsExportSharedSymbols #include "osiTimer.h" @@ -204,7 +205,12 @@ epicsShareFunc void osiTimer::destroy() // epicsShareFunc double osiTimer::delay() const { - throw noDelaySpecified(); +# ifdef noExceptionsFromCXX + assert (0); +# else + throw noDelaySpecified (); +# endif + return DBL_MAX; } epicsShareFunc void osiTimer::show (unsigned level) const