jdurand wrote on Wednesday, May 23, 2012:

I’m in the process of moving all my projects from another RTOS to FreeRTOS and have a question on deleting

In the old RTOS if I tried to delete a task that had already been deleted, then it would just return a FAIL.  Looking at the code here, I can’t really tell what will happen if I delete the same task more than once (ie: if the handle is no longer valid).

I have a work-around but want to know if there’s a clean way of handling this.

richard_damon wrote on Thursday, May 24, 2012:

In FreeRTOS a task handle is really a pointer to the TCB for the task. When you delete the task, that TCB is freed, and any subsequent access invokes “undefined behavior”. If you delete it again, it will be freed again, which for many libraries will corrupt the free store, so not a good idea.

I would suggest that you store the handle in a variable that you can zero after you delete the task, and that way you can check if the task has already been deleted.

kpettit1 wrote on Thursday, May 24, 2012:

Hi jdurand,

Richard is of course the expert on FreeRTOS, but I can say that deleting a task more than once with vTaskDelete would be a bad thing for the following reasons:

1.  The vTaskDelete routine performs linked list manipulation that would cause corruption during the 2nd (or 3rd, etc.) call to vTaskDelete, even if the task were still valid.
2.  You don’t know when the task is actually deleted as this occurs in the idle task as a “clean-up operation”.  This means the task handle may be invalid the 2nd time you call it.
3.  When the task is deleted, the TCB and stack are both freed, thus putting their memory regions back into the heap.  That memory could have been reallocated and over-written before the 2nd vTaskDelete is called, so it isn’t possible to track valid / invalid task status in the TCB.

The way I usually handle deletion of tasks is probably a bit different that usual.  In my port layer, I always initialize my task’s initial stack frames with a valid return address to a “catch function” that performs a “vTaskDelete” followed by a for (;:wink: loop.  Then when I want my task to end, I send it via a mutex or global variable, and the task simply ‘returns’.  Note that is ONLY works because I modify the port layer for my applications (I use mostly ARM processors, so this mean setting the LR (Link Register) in the initial stack frame).

If you *absolutely* had to have a way of support multiple deletes from within the OS, it probably wouldn’t be too hard to extend task.c to add a new xList to track valid xTaskHandles and modify vTaskDelete to first search that new list before attempting to delete the task.  You would also need to add a new xListItem to the TCB and be sure to remove the xTaskHandle from the list from the prvDeleteTCB function.