Hi guys,
Just a quick one, can anyone confirm the behaviour of os_evt_get?
I'm wishing to share a buffer between two threads of different priority. When the thread of higher priority wishes to use the buffer, it sends a cease and desist event signal to the other thread.
I'm using Mutex locks but am concerned about the remote possibility of the cease and desist signal arriving in-between the lower priority thread waking up and locking the Mutex.
My thoughts were to lock the Mutex then re-check the event signaling, however the manual states:
"You can use the os_evt_get function to identify the event that caused the os_evt_wait_or function to complete."
Can I be sure that this function will always return the latest set of events, even if they've not yet been used to wake a thread?
Many thanks
I have no answer I'm afraid, but I am quite curious about the outcome because I'm also looking at the best ways of using the RTX management functions to protect access to buffers.
I think this may be one to contact Keil support about.
As you quoted, the description says "You can use the os_evt_get function to identify the event that caused the os_evt_wait_or function to complete." If that is to be taken literally, then that says to me that any bit that was set following an exit from os_evt_wait_or / os_evt_wait_and will not be included in the result of os_evt_get(). I would also assume that any pending flags, i.e. flags that become set while the task is running and not waiting, would cause an immediate return from the next os_evt_wait_or() / os_evt_wait_and(). But I don't know, so I'd be interested in confirmation. I'm assuming therefore that os_evt_get() provides you with a masked copy of the flags that was made immediately prior to return from os_evt_wait_xxx.
I think these functions are really specifically intended for the purpose of waking a task when another task decides it should do some work. For example, to implement a periodic wake-up. I'm not so sure if this mechanism is best used as a signal to guard access to a resource, because there is no function to poll the current states of the event flags; you only get to know which woke the thread from sleep. I don't know how your tasks are designed, but I'm assuming it's possible for your lower-priority task to execute occasionally to do work even at times when it shouldn't access the buffer. Therefore it would be possible for the higher priority task to have sent an event flag to say 'stop accessing the buffer' and the lower priority task presumably won't see this event again until it goes into wait state.
Could it be better to consider a combination of only mutex and semaphore? In fact, guarded with a mutex, could you use a simple 'shared' boolean?
The event function decides what flags that is waking up the thread at the moment it wakes up the thread - it doesn't care about other events that may happen.
But ignore the event. Just lock the mutex, do something, release. Then lock again, do something and relesae.
If the high-prio thread tries to get the mutex, it will have to wait until the low-prio thread releases the mutex. If it catches the mutex, then you can ignore the low-prio thread until the high-prio thread releases the mutex again.
So please explain again - why do you see a need to mix event and mutex to synchronizing the same thing?