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 | 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 |
<== Date ==> | <== Thread ==> |
---|
Subject: | Re: epicsEventSignal() question |
From: | Michael Westfall <[email protected]> |
To: | Andrew Johnson <[email protected]> |
Cc: | [email protected] |
Date: | Mon, 6 Jun 2016 21:14:04 -0300 |
Hi Mike,
On 06/06/2016 01:39 PM, Michael Westfall wrote:
> The EPICS Application Developer's Guide says this about event signalling:
> "If multiple threads are waiting on the same event, only one of them
> will be woken when the event is signalled."
>
> How would one go about signalling ALL threads waiting on a particular
> event?
>
> This would be the equivalent of vxWorks semFlush().
Well, not quite. A semFlush() on VxWorks triggers a "thundering herd"
https://en.wikipedia.org/wiki/Thundering_herd_problem but doesn't seem
to allow any task to proceed, since it doesn't actually change the state
of the semaphore. We currently only support uni-processor (UP) on
VxWorks as well, so only one thread can actually proceed at once anyway.
If this were a binary semaphore you would therefore need to call
semGive() [which one to call first?] but only one of the waiting threads
could then return from the semTake() that they would be waiting in since
only one thread can own the semaphore at once; the others would all go
back to sleep even if they were all able to test the semaphore at the
same time (on a UP machine of course they can't).
If it's a counting semaphore instead, you could call semGive() multiple
times to allow multiple threads to return from their semTake() calls,
since there's no API for semGiveMany(int n), but that's going to wake
them up one at a time, not all at once.
The only way I can think of to wake up multiple threads at once would be
using a reader/writer semaphore, and have the semaphore owned by a
writer [taken using semWTake()] with all of the waiting threads sitting
in semRTake(). In this circumstance when the writer calls semGive() it
should then wake up and allow all of the waiting readers to proceed.
EPICS doesn't provide an API for a reader/writer semaphore, in fact we
don't currently provide any way of signalling to wake up more than one
thread at once. On a UP OS like VxWorks you can simulate it using a
regular epicsEvent (which is a binary semaphore on VxWorks) and have
each waiting thread check an associated "broadcast" flag immediately
after epicsEventWait() returns, and if that is set immediately call
epicsEventSignal() with the same ID to wake up the next thread.
This should have almost the same effect as waking all the threads at
once given that only one can actually be running on a UP system anyway,
although the epicsEventSignal() does trigger a system call so isn't free.
Why do you want to do this?
- Andrew
--
Arguing for surveillance because you have nothing to hide is no
different than making the claim, "I don't care about freedom of
speech because I have nothing to say." -- Edward Snowdon