Experimental Physics and Industrial Control System
|
On 06/06/2016 05:14 PM, Michael
Westfall wrote:
Hi Andrew,
Thanks for the explanation.
We're converting code from vxWorks to OSI (on top of RTEMS),
and was wondering what to do with the semFlush() calls that
are being used on binary semaphores. Specifically, we're
working on the Allen-Bradley DF1 driver.
Maybe what I should do is have a global counter that each
thread increments before calling epicsEventWait(), and have
the thread that calls epicsEventSignal() repeatedly signal and
decrement the counter till it's zero..
That's probably not that easy. You'd have to increment that counter
and block for an event atomically.
This is exactly what a posix condition variable does. The posix
implementation uses this mechanism
for the epicsEvent implementation (and pthread_cond_broadcast could
be used naturally).
In any case you'll have to be careful: a semaphore has defined
semantics (counts the number
of available resources) these no longer hold in a 'broadcast'
scenario (how many resources
will become available as a result of a broadcast?).
In a situation where you'd want to broadcast an 'event' or
'condition' reflects the semantics
better than a semaphore: assume you have a number of threads which
you want to synchronize
with a condition:
You can have multiple threads waiting for a condition:
/* step 1 */
pthread_mutex_lock( &mtx );
while ( ! event_has_happened ) {
pthread_cond_wait( &cond, &mtx ); /* step 2a, 2b */
}
pthread_mutex_unlock( &mtx );
/* step 3 */
The sender signals the event:
pthread_mutex_lock( &mtx );
event_has_happened = 1;
pthread_cond_broadcast( &cond );
pthread_mutex_unlock( &mtx );
With the above synchronization it is ensured that all receiving
threads
get to step 3. No matter if they were at step 1 (not testing event
yet)
or step 2 past testing 'event_has_happened' and not yet asleep (2a)
or past testing and already asleep (2b) when the sender signalled
the
event.
With your counter approach (assuming you atomically
increment/decrement the counter)
receiver:
waiting++
epicsEventWait();
sender:
while ( waiting-- )
epicsEventSend()
You generate several race conditions:
- any number of receivers that have not yet incremented the
counter
when the sender signals is never woken up.
- unless the underlying semaphore is a counting semaphore there
may
be less threads woken up than 'waiting' counted (if e.g., two
threads
have incremented 'waiting' but are not yet asleep and
epicsEventSend
is executed twice then one event is lost).
You *can* implement an event broadcast with elementary epics devices
(epicsEvent, epicsMutex) but you have to be very careful. Any
textbook
discusses the implementation of one kind of device by using others.
HTH
- Till
Or is there a better way?
|
- References:
- epicsEventSignal() question Michael Westfall
- Re: epicsEventSignal() question Andrew Johnson
- Re: epicsEventSignal() question Michael Westfall
- Navigate by Date:
- Prev:
Re: epicsEventSignal() question Michael Westfall
- Next:
Re: epicsEventSignal() question Johnson, Andrew N.
- Index:
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
<2016>
2017
2018
2019
2020
2021
2022
2023
2024
- Navigate by Thread:
- Prev:
Re: epicsEventSignal() question Michael Westfall
- Next:
Re: epicsEventSignal() question Johnson, Andrew N.
- Index:
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
<2016>
2017
2018
2019
2020
2021
2022
2023
2024
|
ANJ, 15 Jul 2016 |
·
Home
·
News
·
About
·
Base
·
Modules
·
Extensions
·
Distributions
·
Download
·
·
Search
·
EPICS V4
·
IRMIS
·
Talk
·
Bugs
·
Documents
·
Links
·
Licensing
·
|