Counting semaphore sleep until a specific count

unknowcoder wrote on Monday, March 05, 2018:


Is there anyway to have a counting semaphore block until a specific count is available? I can do this manually by implementing a timer to sleep and periodically wake to check the count.

I have a scenario where multiple task can process messages but each consumer has a special algorithm that looks for different data pattern. One of the task can only process the buffer when it’s completely full. Therefore I want to block on the counting semaphore at which point when the buffer is completely full only then can I take a look at the buffer and try to extrapolate data.

Also when the task which needs the entire buffer is processing it it needs to take every single semaphore in one go. If the task doesn’t do this then other task can try processing parts of the buffer but I don’t want this. If the algorithm that is looking at the entire buffer finds a pattern that pattern must be processed as it’s more critical.

A little background
The buffer isn’t really a single message it’s a machine learning algorithm that uses an FPGA that hands off information to a the GPP. The GPP has multiple consumer but one of the consumer can only make good prediction if all the data is there. There other consumer which uses variants of the same algorithm to predict special cases.

rtel wrote on Monday, March 05, 2018:

The short answer is no, there is no way of setting a ‘trigger level’ on a counting semaphore.

FreeRTOS V10 introduced stream buffers, which do have a trigger level, but are very light weight and can only have a single reader and a single writer (which could be an interrupt). Perhaps you could refactor to use a stream buffer and a managemet task - the management task looking for whatever patterns are necessary and then unblocking which ever task needs to process the discovered pattern?

unknowcoder wrote on Thursday, March 08, 2018:

Hi Richard,

Would this cause any issue if I add the following feature to the counting semaphore

  • Check the count if the count is exactly equal to max set the uxMessagesWaiting = 0
  • The code will look very similiar to uxQueueMessagesWaiting()
  • It will also have a method to set it back.
  • Thoughts on this?

Actually to be clear this is making the counting semaphore work as a binary semaphore in specific task.

		uxReturn = ( ( Queue_t * ) xQueue )->uxMessagesWaiting;
		if(MAX_COUNT == uxReturn)
		    ( ( Queue_t * ) xQueue )->uxMessagesWaiting = 0;

rtel wrote on Thursday, March 08, 2018:

Not sure of the context, but if it works for your app then why not.