I have a Queue Set that contains two queues. I use these as a high and low priority queue, and until now my process for servicing them has been:
call xQueueSelectFromSet to see if there’s any data available
call xQueueReceive on the high priority queue to see if it was the one with data
if not, call xQueueReceive on the low priority queue
But today I was looking at the comments for xQueueCreateSet and saw this: “Note 4: A receive (in the case of a queue) or take (in the case of a semaphore) operation must not be performed on a member of a queue set unless a call to xQueueSelectFromSet() has first returned a handle to that set member.”
Is it invalid to do things the way I’ve been doing so far (and haven’t any issue with)? What is the risk? Is there a better way to manage queue priority?
The key requirement is that you should take an item out of a Queue when the QueueSet gives you an indication that there is data available.
While normally you take the data from the queue indicated, taking from one in preference to the other should cause problems.
The key fact is that there is one location in the queue set for every possible location in any of the queues in the set, and there should be as many locations used in the queue set as are used in the queues themselves.
“taking from one in preference to the other should cause problems.”
Sorry, could you clarify here? “Should” cause problems?
Your method is fine. The real issue is making sure the queue set is up to date with the state of the queues. So things like not consuming data from one of the queues OR consuming data when the set hasn’t signalled there is data will cause problems.
I’ll also note that by checking the queues in a priority order, you’re adding unnecessary calls but that might not matter to you.
If you want the priority architecture, so messages to the high-priority queue are handled first, and processing can allow for messages to build in the queues, then I can’t see a way to do that with fewer calls. Just because the oldest message in the queues (at least per the tracking of the Queue Set) is a low-priority message, doesn’t mean that there isn’t a High-Priorty message available.
The Queue Set provides a Queue Handle to allow a pure FIFO Multi-Queue processing, but using the Queue Set as just a “Counter” for messages available is valid, even if slightly wasteful of resources. One could set up a Counting Semaphore which each producer signals just after adding its item to one of the Queues, and the reader waits on it until SOMETHING is available. However, you still need to ask the queues in priority order for the data.
The QueueSet just provides a convenient wrapping of that logic.
You make a good point. I was assuming the queues were emptied at almost all times. That’s an incorrect assumption.
If - and only if - the queues were empty at all other times than receiving a single message could you get away with just calling
xQueueSelectFromSet to determine which queue to receive from.
Otherwise you’ll need to look in priority order as you’ve mentioned.