Possible bug with xTaskAbortDelay() and task waiting for notification.

I have a task which is waiting indefinitely for lightweight task notification ulTaskNotifyTake( pdTRUE, portMAX_DELAY ); The task is in the suspended state. When I try to abort the delay with xTaskAbortDelay(thattask_) It does not resume running – it stays in the suspended state. Other taks which are waiting indefinitely for an OS object resume running when their delay is aborted. I tracked this to a point in the OS (tasks.c) where it determines if the task is really suspended or waiting indefinitely
            else if( pxStateList == &xSuspendedTaskList )
            {
                /* The task being queried is referenced from the suspended
                list.  Is it genuinely suspended or is it block
                indefinitely? */
                if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL )
                {
                    eReturn = eSuspended;
                }
                else
                {
                    eReturn = eBlocked;
                }
            }
Tasks waiting indefinitely for an OS object return eBlocked whie the task waiting indefinitely for a lightweight notification return eSuspended, and consequently fail this check
        /* A task can only be prematurely removed from the Blocked state if
        it is actually in the Blocked state. */
        if( eTaskGetState( xTask ) == eBlocked )
        {
I encountered this with FreeRTOS 9.0.0 so I tried 10.0.1 but it behaves the same. The MCU is an NXP Kinetis K24. The compiler is IAR 8.22.1 with low optimization. Is this how it is supposed to work or is this a bug? Thanks, Matt

Possible bug with xTaskAbortDelay() and task waiting for notification.

I will look at this, but first some clarification. How did the task get into the suspended state, and is it really in the suspended state or just mistakenly reporting it is. For example, did the task just call ulTaskNotificationTake(, pdTRUE, portMAX_DELAY ), in which case it would actually be in the Blocked state, not the Suspended state. Or did it enter the Blocked state in this way, only to have another task then call vTaskSuspend() to move the task from the Blocked state to a real Suspended state?

Possible bug with xTaskAbortDelay() and task waiting for notification.

Hi Richard, We have a CLI command that prints the task states. With FreeRTOS 9 I had noticed that tasks blocking indefinitely report that they are in the Suspended state – whether they are blocking for an OS object or a lightweight notification. So the task was in in the ‘Suspended’ state only because it called ulTaskNotifyTake() – as were all the other tasks waiting indefinitely for OS objects (queues, etc). The other tasks resume running when their delay is aborted, but the one waiting indefinitely for the lightweight notification stays suspended. However, when I tried FreeRTOS 10 to see if this had been fixed I noticed that our same CLI command now reports the tasks blocking indefinitely as being in the Blocked state not the Suspended state – except for the one blocking indefinitely for the lightweight notification, it still say it’s in the Suspended state. The behavior is essentially as I expect if I block for portMAXDELAY-1 instead of portMAXDELAY. In this case the task waiting for the lightweight notification says it’s blocked instead of suspended and the abort delay works. Thanks, Matt

Possible bug with xTaskAbortDelay() and task waiting for notification.

I replied to this via email but the post didn’t show, so appologies if it now shows twice: I just checked in the following change to the code section you posted before which changes this behaviour. Unfortunately the code view in SourceForge seems to be blank at the moment, hence I’ve just pasted it here, but when SourceForge functions correctly again you will find it here: https://sourceforge.net/p/freertos/code/ ~~~ else if( pxStateList == &xSuspendedTaskList ) { /* The task being queried is referenced from the suspended list. Is it genuinely suspended or is it blocked indefinitely? / if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ) { #if( configUSE_TASK_NOTIFICATIONS == 1 ) { / The task does not appear on the vent list item of and of the RTOS objects, but could still be in the blocked state if it is waiting on its notification rather than waiting on an object. */ if( pxTCB->ucNotifyState == taskWAITING_NOTIFICATION ) { eReturn = eBlocked; } else { eReturn = eSuspended; } } #else { eReturn = eSuspended; } #endif } else { eReturn = eBlocked; } } ~~~

Possible bug with xTaskAbortDelay() and task waiting for notification.

I just checked in the following change to the code section you posted before which changes this behaviour. Unfortunately the code view in SourceForge seems to be blank at the moment, hence I’ve just pasted it here, but when SourceForge functions correctly again you will find it here: https://sourceforge.net/p/freertos/code/ ~~~ else if( pxStateList == &xSuspendedTaskList ) { /* The task being queried is referenced from the suspended list. Is it genuinely suspended or is it blocked indefinitely? / if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ) { #if( configUSE_TASK_NOTIFICATIONS == 1 ) { / The task does not appear on the vent list item of and of the RTOS objects, but could still be in the blocked state if it is waiting on its notification rather than waiting on an object. */ if( pxTCB->ucNotifyState == taskWAITING_NOTIFICATION ) { eReturn = eBlocked; } else { eReturn = eSuspended; } } #else { eReturn = eSuspended; } #endif } else { eReturn = eBlocked; } } ~~~

Possible bug with xTaskAbortDelay() and task waiting for notification.

Hi Richard, That seems to have done the trick – for version 9 anyway (in this case I just copied your change into the source. But I think this section of code is the same for 9 and 10. Let me know if you would also like me to retest with version 10. Thanks, Matt