Binary Semaphore and Cooperative Scheduler

mutty00 wrote on Saturday, January 24, 2015:

Hi,

I successfully adopt FreeRTOS since 2006 for many products in my company.
I’m currently use version 7.0.1 and cooperative mode: everthing is perfect for me with this configuration.

In the past days I received update notification for version 8.2.0 and I’ve tried and update ( I was very interested in some new features like direct notification and deferred interrupt handling).

Unfortunately I’ve immediately some issue with queque and semaphore management with the new 8.2.0 release.

Looking at change history I’ve seen that since revision 7.6.0, semaphores in cooperative mode changes a bit their behaviour and don’t include an automatical yield request when needed. ( in fact this is more correct in a cooperative configuration ).

Anyway in all my application I use them in this “old style” way used in releases since 7.6.0.

Now I’ve seen that If I switch to preemptive mode semaphores restarts to work fine for me, and my whole application seems to works.
So initially I thonugh that this could be the solution.

But now I’ve very concerned to switch to preemptive because of my code have no protection on data shared between different tasks: I’ve some task that quickly update a group of data and some other that read them.
I’ve neever had any case of data corruption in cooperative mode, but I’m not sure that this is the same with preemption, without adding additional protection on data access.

Have you some suggestion for me to solve this ???

In queue.c file definiton of queueYIELD_IF_USING_PREEMPTION() is null in coopetative mode.
What happen if I enable portYIELD_WITHIN_API() also for cooperative mode ???
I’ll recover the old style bevaviour or I’ve other side effects doing this ???

Someone could help me ??? Thank you in advance.

rtel wrote on Saturday, January 24, 2015:

As you say, since V7.6.0 the behaviour has been more as might be ‘expected’.

I would not recommend updating the FreeRTOS source in order to revert to the old behaviour, although your suggestion of redefining queueYIELD_IF_USING_PREEMPTION() is probably workable.

The intention however is that you explicitly call taskYIELD() when you want to switch to another task. So where previously you may have just had a call to xSemaphoreGive(), now you would have a call to xSemaphoreGive() followed immediately by taskYIELD() - and your application should then work as before.

You raise an interesting questions in my mind though, and that is how the task notifications work in co-operative mode. Task notifications will still yield whether using co-operative mode or not - maybe that should be changed to also use the YIELD_IF_USING_PREEMPTION version.

Regards.

mutty00 wrote on Sunday, January 25, 2015:

Thank you for your fast reply.

Before try to switch to preemptive mode I already tried to manually add a taskYIELD() call after each xSemaphoreGive() in my code and I can confirm that this works.

But I still have a doubt: Task switch after an xSemaphoreGive() is only needed if some other task have taken the semaphore when the current task ( i.e. the one that have just executed the xSemaphoreGive() ) use it.
If no one is waiting for the semaphore you waste a contex switch a you slow down the execution of the current task ( in cooperative mode even if the current task have low priority its action is completed even if there are higher priority task that not need semaphore ready ). This should be a little problem for my system.

Looking at the queue.c code I can see that in preempitive mode ( and also in cooperative mode before version 7.6.0 ) taskYIELD inside API is correcly done olny if some condition are true:

if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )
{
queueYIELD_IF_USING_PREEMPTION();
}
else
{
mtCOVERAGE_TEST_MARKER();
}

At this point my question is , how I can detect if a yield is really necessary from my task after an xSemaphoreGive call without introducing modification in the API code ?? There is a way ??

Waiting for your comments…

PS:

According the other question you raised: I’ve tested task notification only using xTaskNotifyFromISR within an interrupt function that allows context switch ( with portENTER_SWITCHING_ISR() and portEXIT_SWITCHING_ISR() macros ) and probably I’ve also already switched to preemptive mode for the test, so I can’t confirm you which is the behaviour of the system, but I can try tomorrow.

By the way, I don’t know if this could be of any interest for this topic but my porting is for AVR32 UC3C microcontroller.

Thank you.

rtel wrote on Sunday, January 25, 2015:

xSemaphoreGive() only tells you if giving the semaphore was successful
or not, not if giving the semaphore cause a higher priority task to
unblock. In most new ports you could use xSemaphoreGiveFromISR()
instead even from a task - that does let you know if giving the
semaphore caused a higher priority task to leave the blocked state. In
the AVR32 port (which is rather old and now maintained by Atmel) it
might be the case that you could only call xSemaphoreGiveFromISR() from
a task if you placed the call in a critical section.

Regards.

mutty00 wrote on Sunday, January 25, 2015:

Ok, this should be the solution.

I’ll try to compare code of xQueueGiveFromISR and xQueueGenericReceive that wrap xSemaphoreGiveFromISR and xSemaphoreGive to see if is enough to call SemaphoreGiveFormISR() inside a critical section from a non ISR task.

Thank you for your support.

alainm3 wrote on Sunday, January 25, 2015:

Hi,

IMHO the easyest way to protect data accessed from two tasks is to use a
MUTEX. I don’t understand why this was not suggested.

Have a look at some examples, it is sooo easy!
And if you haven’t, by the manual it is full of this kind of examples.

BTW, I don’t receive a % on said manuals :wink:

Alain

Em 24-01-2015 14:09, mutty00 escreveu:

Hi,

I successfully adopt FreeRTOS since 2006 for many products in my company.
I’m currently use version 7.0.1 and cooperative mode: everthing is
perfect for me with this configuration.

In the past days I received update notification for version 8.2.0 and
I’ve tried and update ( I was very interested in some new features
like direct notification and deferred interrupt handling).

Unfortunately I’ve immediately some issue with queque and semaphore
management with the new 8.2.0 release.

Looking at change history I’ve seen that since revision 7.6.0,
semaphores in cooperative mode changes a bit their behaviour and don’t
include an automatical yield request when needed. ( in fact this is
more correct in a cooperative configuration ).

Anyway in all my application I use them in this “old style” way used
in releases since 7.6.0.

Now I’ve seen that If I switch to preemptive mode semaphores restarts
to work fine for me, and my whole application seems to works.
So initially I thonugh that this could be the solution.

But now I’ve very concerned to switch to preemptive because of my code
have no protection on data shared between different tasks: I’ve some
task that quickly update a group of data and some other that read them.
I’ve neever had any case of data corruption in cooperative mode, but
I’m not sure that this is the same with preemption, without adding
additional protection on data access.

Have you some suggestion for me to solve this ???

In queue.c file definiton of queueYIELD_IF_USING_PREEMPTION() is null
in coopetative mode.
What happen if I enable portYIELD_WITHIN_API() also for cooperative
mode ???
I’ll recover the old style bevaviour or I’ve other side effects doing
this ???

Someone could help me ??? Thank you in advance.


Binary Semaphore and Cooperative Scheduler
https://sourceforge.net/p/freertos/discussion/382005/thread/4e34d076/?limit=25#dc9b


Sent from sourceforge.net because you indicated interest in
https://sourceforge.net/p/freertos/discussion/382005/
https://sourceforge.net/p/freertos/discussion/382005

To unsubscribe from further messages, please visit
https://sourceforge.net/auth/subscriptions/
https://sourceforge.net/auth/subscriptions