a bug in vTaskResume

aresqi wrote on Wednesday, June 22, 2005:

When we are in a SuspendAll state and call vTaskResume, we should put the TaskToResume on xPendingReadyList instead of pxReadyTasksLists

so at line 834 in task.c

            taskENTER_CRITICAL();
            {
                xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority );
                vListRemove( &( pxTCB->xGenericListItem ) );
                prvAddTaskToReadyQueue( pxTCB );
            }
            taskEXIT_CRITICAL();

====== can be change to  =======>>>>

            taskENTER_CRITICAL();
            {
                if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )
                {
                    xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority );
                    vListRemove( &( pxTCB->xGenericListItem ) );
                    prvAddTaskToReadyQueue( pxTCB );
               }
               else
               {
                   vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) );
               }

            }
            taskEXIT_CRITICAL();

rtel wrote on Wednesday, June 22, 2005:

Thanks for your feedback.

From my first look it seems you are right here.  When the scheduler is locked, cases where events ready are task are covered, but there is nothing stopping an application readying a task.  Seems to be a whole in the tests that need filling.

Thanks,
Richard.

nobody wrote on Wednesday, June 22, 2005:

think here calling TaskRemume when the scheduler is locked will cause the resumed task to be added to the ready list but no yield will happen.  the task switch will happen next tick or next call to yield.  This means not to serious.  task will run again but possibly in wrong sequence.

rtel wrote on Wednesday, June 22, 2005:

I have added the following text to the "known issues with current build" list (on the FreeRTOS.org WEB site) and in a bug tracker.

"The functions vTaskSuspendAll() and xTaskResumeAll() are available to suspend and resume the scheduler. The functions vTaskSuspend() and vTaskResume() are available to suspend and resume individual tasks.

If the scheduler is not suspended when a call to vTaskResume() is made, the task being resumed will start to execute immediately if it’s priority is higher than the currently executing task.

In the case where the scheduler is suspended when a call to vTaskResume() is made - if the task being resumed has a priority higher than the currently executing task then it should start to run immediately upon the scheduler being unsuspended.

However, in the second case the task will not start executing when the scheduler is unsuspended, but only following the next RTOS tick or the next call to a yielding function"

aresqi wrote on Wednesday, June 22, 2005:

>This means not to serious. task will run again but possibly in wrong sequence.

yes, you are right.

but , if we put the higher priority resuming task in xPendingReadyList , after we call xTaskResumeAll, this higher priority task can be schedued in correct sequence.

i think it’s better

aresqi wrote on Wednesday, June 22, 2005:

i find vTaskPrioritySet()  may be have the same problem when scheduler is locked.

in addition , there is also a optimisation  in vTaskPrioritySet()

in current vTaskPrioritySet(), taskYIELD() will be called every time no matter it’s necessary. we can set a flag portBASE_TYPE xYieldRequired .

xYieldRequired = pdFALSE;

if (pxTask == pxCurrentTCB) && (uxNewPriority < pxCurrentTCB->uxPriority)  // if lower the current task’s priority
__xYieldRequired = pdTRUE;
else if (pxTask != pxCurrentTCB) && (uxNewPriority > pxCurrentTCB->uxPriority)  // if upper another task’s priority and higher than the current task’s priority
__xYieldRequired = pdTRUE;

if (xYieldRequired)
__taskYIELD();

rtel wrote on Wednesday, June 29, 2005:

Fixed in V3.2.0!