11 #if _POSIX_C_SOURCE>=200112L 17 #include <epicsGuard.h> 18 #include <epicsEvent.h> 19 #include <epicsMutex.h> 20 #include <epicsThread.h> 21 #include <epicsTypes.h> 22 #include <epicsTime.h> 23 #include <generalTimeSup.h> 28 typedef epicsGuard<epicsMutex>
Guard;
29 typedef epicsGuardRelease<epicsMutex>
UnGuard;
94 if(clock_gettime(CLOCK_REALTIME, &now)!=0) {
102 now.tv_nsec = 999999000;
104 if(clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &now, NULL)!=0) {
105 wakeupsrc.wait(10.0);
111 }
catch(std::exception& e){
112 errlogPrintf(
"Soft timestamp source can't reset event: %s\n", e.what());
113 wakeupsrc.wait(10.0);
124 epicsThreadRunableMethod<Impl, &Impl::runTimeout>
timeoutRun;
128 epicsThreadRunableMethod<Impl, &Impl::runSrc> softsrcRun;
129 mrf::auto_ptr<epicsThread> softsrc;
131 epicsEvent wakeupsrc;
144 :impl(new
Impl(this, period))
162 epicsUInt32 tosend=0;
174 if(ok && valid && impl->
resync) {
175 impl->
next = ts.secPastEpoch+POSIX_TIME_AT_EPICS_EPOCH+1;
187 impl->
lastError = double(tosend) - (ts.secPastEpoch+POSIX_TIME_AT_EPICS_EPOCH);
196 epicsThreadGetStackSize(epicsThreadStackSmall)));
205 for(
unsigned i = 0; i < 32; tosend <<= 1, i++) {
207 if( tosend & 0x80000000 )
211 }
catch(std::exception& e){
212 errlogPrintf(
"Soft timestamp source can't send shift event: %s\n", e.what());
221 return impl->
okCnt>=5;
234 mrf::auto_ptr<epicsThread> cleanup;
237 if(enable && !impl->softsrc.get()) {
239 impl->stopsrc =
false;
240 impl->softsrc.reset(
new epicsThread(impl->softsrcRun,
242 epicsThreadGetStackSize(epicsThreadStackSmall),
243 epicsThreadPriorityHigh));
244 impl->softsrc->start();
248 }
else if(!enable && impl->softsrc.get()) {
249 impl->stopsrc =
true;
250 cleanup = PTRMOVE(impl->softsrc);
259 throw std::runtime_error(
"Soft timestamp source not supported");
267 return !!impl->softsrc.get();
278 raw.secPastEpoch = impl->
next - POSIX_TIME_AT_EPICS_EPOCH;
283 std::vector<char> buf(40);
285 buf.resize(time.strftime(&buf[0], buf.size(),
"%a, %d %b %Y %H:%M:%S"));
288 return std::string(&buf[0], buf.size());
TimeStampSource(double period)
std::string nextSecond() const
void softSecondsSrc(bool enable)
enable sending of event 125 by software timer. Simulation of external HW clock
virtual void setEvtCode(epicsUInt32 evtCode)=0
mrf::auto_ptr< epicsThread > timeout
bool isSoftSeconds() const
TimeStampSource *const owner
void tickSecond()
Call just after the start of each second.
#define MRF_EVENT_TS_SHIFT_0
Impl(TimeStampSource *owner, double period)
void resyncSecond()
Call to re-initialize timestamp counter from system time.
#define MRF_EVENT_TS_SHIFT_1
#define ER_PROVIDER_PRIORITY
Priority given to EVR's timestamp/event provider.
epicsGuardRelease< epicsMutex > UnGuard
#define MRF_EVENT_TS_COUNTER_RST
virtual void postSoftSecondsSrc()
bool validSeconds() const
Whether tickSecond() has been called for the past 5 seconds.
virtual ~TimeStampSource()
epicsThreadRunableMethod< Impl, &Impl::runTimeout > timeoutRun
double deltaSeconds() const
last difference between
epicsGuard< epicsMutex > Guard