BaseType_t xTaskGenericNotify()

in tasks.c [4869:4985]


    BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify,
                                   UBaseType_t uxIndexToNotify,
                                   uint32_t ulValue,
                                   eNotifyAction eAction,
                                   uint32_t * pulPreviousNotificationValue )
    {
        TCB_t * pxTCB;
        BaseType_t xReturn = pdPASS;
        uint8_t ucOriginalNotifyState;

        configASSERT( uxIndexToNotify < configTASK_NOTIFICATION_ARRAY_ENTRIES );
        configASSERT( xTaskToNotify );
        pxTCB = xTaskToNotify;

        taskENTER_CRITICAL();
        {
            if( pulPreviousNotificationValue != NULL )
            {
                *pulPreviousNotificationValue = pxTCB->ulNotifiedValue[ uxIndexToNotify ];
            }

            ucOriginalNotifyState = pxTCB->ucNotifyState[ uxIndexToNotify ];

            pxTCB->ucNotifyState[ uxIndexToNotify ] = taskNOTIFICATION_RECEIVED;

            switch( eAction )
            {
                case eSetBits:
                    pxTCB->ulNotifiedValue[ uxIndexToNotify ] |= ulValue;
                    break;

                case eIncrement:
                    ( pxTCB->ulNotifiedValue[ uxIndexToNotify ] )++;
                    break;

                case eSetValueWithOverwrite:
                    pxTCB->ulNotifiedValue[ uxIndexToNotify ] = ulValue;
                    break;

                case eSetValueWithoutOverwrite:

                    if( ucOriginalNotifyState != taskNOTIFICATION_RECEIVED )
                    {
                        pxTCB->ulNotifiedValue[ uxIndexToNotify ] = ulValue;
                    }
                    else
                    {
                        /* The value could not be written to the task. */
                        xReturn = pdFAIL;
                    }

                    break;

                case eNoAction:

                    /* The task is being notified without its notify value being
                     * updated. */
                    break;

                default:

                    /* Should not get here if all enums are handled.
                     * Artificially force an assert by testing a value the
                     * compiler can't assume is const. */
                    configASSERT( xTickCount == ( TickType_t ) 0 );

                    break;
            }

            traceTASK_NOTIFY( uxIndexToNotify );

            /* If the task is in the blocked state specifically to wait for a
             * notification then unblock it now. */
            if( ucOriginalNotifyState == taskWAITING_NOTIFICATION )
            {
                listREMOVE_ITEM( &( pxTCB->xStateListItem ) );
                prvAddTaskToReadyList( pxTCB );

                /* The task should not have been on an event list. */
                configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL );

                #if ( configUSE_TICKLESS_IDLE != 0 )
                {
                    /* If a task is blocked waiting for a notification then
                     * xNextTaskUnblockTime might be set to the blocked task's time
                     * out time.  If the task is unblocked for a reason other than
                     * a timeout xNextTaskUnblockTime is normally left unchanged,
                     * because it will automatically get reset to a new value when
                     * the tick count equals xNextTaskUnblockTime.  However if
                     * tickless idling is used it might be more important to enter
                     * sleep mode at the earliest possible time - so reset
                     * xNextTaskUnblockTime here to ensure it is updated at the
                     * earliest possible time. */
                    prvResetNextTaskUnblockTime();
                }
                #endif

                if( pxTCB->uxPriority > pxCurrentTCB->uxPriority )
                {
                    /* The notified task has a priority above the currently
                     * executing task so a yield is required. */
                    taskYIELD_IF_USING_PREEMPTION();
                }
                else
                {
                    mtCOVERAGE_TEST_MARKER();
                }
            }
            else
            {
                mtCOVERAGE_TEST_MARKER();
            }
        }
        taskEXIT_CRITICAL();

        return xReturn;
    }