but if scheduler is locked or there is no higher or the other same priority task in readylist , we have to return to the current task again. In these cases, portSAVE_CONTEXT() and portRESTORE_CONTEXT() waste much system resources.
so i think we should let vTaskSwitchContext() return a value to solve this problem like this:
signed portBASE_TYPE vTaskSwitchContext()
{
…
…
if we have switched to another task
return pdTRUE;
else
return pdFALSE
}
thus vPortYield() maybe change to
void vPortYield( void )
{
signed portBASE_TYPE xReturn;
…
portENTER_CRITICAL();
xReturn = vTaskSwitchContext();
portEXIT_CRITICAL();
if (xReturn == pdFALSE) return;
portSAVE_CONTEXT();
portRESTORE_CONTEXT();
…
}
And this change doesn’t afffect vPortYieldFromTick or other ISRs.
this definately will not work. SwitchContext must come between save_context and restore_context otherwise you save the context of one task into the tcb of another.
as
1\ task a is running.
2\ tick happens
3\ SwitchContext decides another task (b) should run and switches the current tcb.
4\ as your code SwitchContext returns true and save_context is called.
5\ save_context saves task a context into task b stack.
6\ restore_context then immediately removes task a context from task b stack.
now task a is running but the current tcb is pointing to task b.
But i think it’s better we need a method to avoid portSAVE_CONTEXT() and portRESTORE_CONTEXT() when scheduler is locked or there is no higher or the other same priority task in readylist.
of course , my method will not work , i know now. But it will has another way to do this.