From: Andrew Johnson [mailto:email@example.com]
> On 2011-07-18 firstname.lastname@example.org wrote:
> > the entire purpose of
> > wait_for_epics_ready() is to ensure I can generate I/O Intr events without
> > losing them. I wonder whether I should use initHookAfterInterruptAccept
> > instead ... don't suppose it makes much difference.
> It sounds like your interrupt routine should just be checking
> interruptAccept and only generating I/O Intr events when it sees it true.
Well, that's not the complete story for me. I'm actually using quite an unusual update model that's worked very well for me, the goal is to separate memory updates from EPICS. Here is my flow of control:
1. Internal update event signalled (interrupt routine or some any other event) starts this flow, but definitely *not* in interrupt context
2.a Wait for EPICS ready (as discussed)
2.b Wait for a READY record to process (primed on first pass with a "full" event, of course, or merge into 2.a)
3. Update internal data structures ready to be ready by EPICS records
4. Trigger one I/O Intr record
5.a Triggered record uses fanout to process multiple records to read data structures updated in step (3)
5.b Last processed record in fanout chain processes record in step (2.b) (must be last, or interlocking with (3) is broken)
Step 2.b is really an epicsEventWait() call.
This rather odd mechanism is my attempt at an atomic update to a collection of records. The processing code is easy, just (2), (3), (4), and the record processing is managed with a single I/O Intr record triggering what amounts to a single compound update -- each record processed at step (5.a) is reading from the data structures prepared at step (3).
Think of (2) as locking a mutex on (3), and (4) as releasing the mutex.
There is I think one vulnerability: (4) => (5.b) => (2.b). I have in the past occasionally seen my processing stuck at stage (2.b), but not for some years now I think. This mechanism is used throughout the Libera EPICS driver, and at the moment I'm abstracting it for use elsewhere. Of course this mechanism will fail miserably if (4) doesn't actually do anything, hence the original problem. In this context if somebody has reset interruptAccept I guess I'm dead :(
> > ... scanPause() ... iocPause() ...
> Ralph has explained why it's there
Ah, hadn't seen Ralph's mail. That makes sense, so my code won't work properly with redundancy, that's fine. I guess I'd have to use the appropriate hook events.
> BTW, your wait_for_epics_ready() routine doesn't need to call malloc()
> [which is worth avoiding on vxWorks < 6.x for memory fragmentation reasons],
> it could allocate the waiter object on the stack since it's not going to return
> until after the object has been de-queued anyway.
Nice catch! Alas, doesn't really fix the malloc issue as I still have to temporarily allocate an epicsEventId object, there's no hook for doing that on the stack. I think in my application I can combine (2.a) and (2.b) above, and so recycle the event object.
Your comments on broadcast events make sense to me, thanks. Interestingly our vxWorks system does seem to have a pthreads implementation, but I've no idea how complete it is -- google is suggesting a variety of implementations of varying quality... Think I'm happy to stick with what OSI provides here.
- EPICS OSI and events michael.abbott
- RE: EPICS OSI and events Mark Rivers
- RE: EPICS OSI and events michael.abbott
- Re: EPICS OSI and events Andrew Johnson
- Navigate by Date:
RE: Delay problem in ca_array_put() command Jeff Hill
Re-release pcas as pcaspy Wang Xiaoqiang
- Navigate by Thread:
Re: EPICS OSI and events Andrew Johnson
Alarm Handler and $ALARMCOUNTFILTER keith.baker