Task Release Service

The Task Release Service is a custom user-implemented service responsible for cleaning up the task system context of the tasks terminated by the PxDie() function. The PXROS-HR requires assigning a task as a service task, so the kernel can signal the PXSERVICE_TASK_DIED event to the service task when a task dies.

The Task Release Service has to be started on each core where tasks are intended to be terminated. A task must be assigned as a service task by calling PxServiceTaskInit(), which means that it starts receiving PXSERVICE_TASK_DIED events that are signaled from successful PxDie() calls.

For calling PxServiceTaskInit(), a task must have PXACCESS_SYSTEM_CONTROL task access rights.

The dedicated task implementation

In this case, the Task Release Service is a dedicated task responsible for cleaning up the task system context of the tasks terminated by the PxDie() function. The TaskRS sample implementation, including source code, is part of Utilities supplied with OS installer and can be linked to the project as a source code or library called libtaskrelsrv.a.

The TaskRS has to be started on each core where tasks are intended to be terminated and is responsible for calling the function PxDieService() when the kernel signals by the event PXSERVICE_TASK_DIED that a task has been terminated.

The TaskRS calls PxServiceTaskInit() to announce itself as the service task. This service task will get events to clean up the task system context after a task dies.

The Task Release Service can also be part of a task also having another purpose. The PxDieService() should be called to clean up the terminated tasks. As far as the PxDieService() goes through the PxDieSrv Task Release Queue, the cleanup is not directly dependent on the event PXSERVICE_TASK_DIED. It can also be called periodically, as polling, or after the forced termination.

task release service flow
Fig. 1. Minimal TaskRS implementation flow

Priority influence

The terminated tasks are cleaned after the PXSERVICE_TASK_DIED event is signaled, and the TaskRS gets execution time to process the event. TaskRS is subjected to the same scheduling rules as any other task in the system. Hence, its priority will have a major impact on the delay between the task termination request and the actual cleanup.

Sample implementation

The task-release utility implementation contains a function to create the TaskRS So every core using task termination must first create the task by calling the TaskReleaseService_TaskCreate(priority, events).

Code 1. TaskRS main function sample implementation
static void TaskReleaseService_Task (PxTask_t myId, PxMbx_t myMbx, PxEvents_t actEv)
{
    PxError_t err;

    (void)myId;
    (void)myMbx;
    (void)actEv;

    /* Announce itself as a service task
     * the service task will get events to handle
     * the garbage collection after a task died.
     */
    err = PxServiceTaskInit();
    if (err != PXERR_NOERROR)
    {
        /* The only possibility for a failure maybe
         * PXERR_ACCESS_RIGHT:            Task does not have the right
         *                                PXACCESS_SYSTEM_CONTROL
         * PXERR_TASK_DIESRV_INITIALIZED: Another task is already installed as a service
         *                                task
         * Sleep forever
         */
        PxAwaitEvents(0);
    }

    while (1)
    {
        PxEvents_t Ev;

        /*
         * Wait for the event to support task termination
         */
        Ev = PxAwaitEvents(PXSERVICE_TASK_DIED);

        if (Ev & PXSERVICE_TASK_DIED)
        {
            /*
             * A task has died do the garbage collection
             */
            err = PxDieService();
            if (err != PXERR_NOERROR)
            {
                /* An error could only occur if the internal object handling is
                 * defect (which should never occur) or if the memory classes
                 * of the died task's stack or TCB is corrupted.
                 */
                PxPanic();
            }
        }
    }
}

The following code shows how to create TaskRS in HighTec`s examples. The modified code is based on the TC39x PXROS-HR BSP example. Examples are available from the HighTec Content Manager. The TaskRS is created in the Init task, which is responsible for the application’s initialization.

Code 2. Modified TC39x PXROS-HR BSP example Init task — the creation of the TaskRS
...

/* Wait for the NameServer service task on MASTER_CORE to get initialized.*/
PxError_t errRes = PxGetGlobalServerMbx (PXROS_MASTER_CORE, _PxNameSrvReqMbxId);
if (errRes != PXERR_NOERROR)
    PxPanic();

/* Create the TaskRS */
PxTask_t releaseService = TaskReleaseService_TaskCreate(TASK_RELEASE_SERVICE_PRIO,
                                                        (PxEvents_t) 0);
if (PxTaskIdError(releaseService) != PXERR_NOERROR)
    PxPanic();

/* User Task Deployment
* --------------------
* here each core creates and activates their own set of user tasks
* defined in Task Deployment Table
*/
TaskDeploy(coreId);

...

PxDieService()

PXROS-HR uses a queue (FIFO) of task IDs to be released — "PxDieSrv Task Release Queue" will be used in the following text. This queue is used only by the kernel.

PxDieService() goes through the PxDieSrv Task Release Queue until there is no task to be released, and for each such task, cleans up the task system context. The following steps are done:

  • Invalidates the task

  • Release the task’s private mailbox

  • Remove any allocated task stack memory

  • Remove any allocated task interrupt stack memory

  • Release the stack for the abort mechanism if not null

  • Return the task control block

  • Release the task object