voidvTaskDelete( TaskHandle_t xTaskToDelete ){
TCB_t * pxTCB;
BaseType_t xDeleteTCBInIdleTask = pdFALSE;
BaseType_t xTaskIsRunningOrYielding;traceENTER_vTaskDelete( xTaskToDelete );taskENTER_CRITICAL();{
获取当前要删除任务的TCB,如果xTaskToDelete 为空则表示要删除当前正在运行的任务,否则就找到对应任务的TCB。
pxTCB =prvGetTCBFromHandle( xTaskToDelete );configASSERT( pxTCB !=NULL);
把当前要删除的任务从ready/delayed 链表中删除,并判断任务优先级的链表任务数是否为0if(uxListRemove(&( pxTCB->xStateListItem ))==( UBaseType_t )0){
如果当前要删除的任务优先级所对应的链表任务数为0,则将该优先级在uxTopReadyPriority中mask掉。
taskRESET_READY_PRIORITY( pxTCB->uxPriority );}else{mtCOVERAGE_TEST_MARKER();}
判断当前的任务是否在一个event的链表,如果是则通过uxListRemove将其移除
if(listLIST_ITEM_CONTAINER(&( pxTCB->xEventListItem ))!=NULL){(void)uxListRemove(&( pxTCB->xEventListItem ));}else{mtCOVERAGE_TEST_MARKER();}/* Increment the uxTaskNumber also so kernel aware debuggers can
* detect that the task lists need re-generating. This is done before
* portPRE_TASK_DELETE_HOOK() as in the Windows port that macro will
* not return. */
uxTaskNumber++;
通过taskTASK_IS_RUNNING_OR_SCHEDULED_TO_YIELD来判断当前的任务是否在运行状态,如果其xTaskRunState被设置为-1则表明其不处于运行状态,正常运行的任务其xTaskRunState值会被设置为所运行的core的id。
xTaskIsRunningOrYielding =taskTASK_IS_RUNNING_OR_SCHEDULED_TO_YIELD( pxTCB );
根据xSchedulerRunning 来判断当前的是否还处于正常的调度状态,该全局变量在vTaskStartScheduler函数被执行时设置为pdTRUE,在vTaskEndScheduler时被设置为pdFALSE
if(( xSchedulerRunning != pdFALSE )&&( xTaskIsRunningOrYielding != pdFALSE )){
为了防止该任务在其他core上还有运行的,所以将该任务添加到xTasksWaitingTermination链表上,等idle task运行时再做清理工作。
vListInsertEnd(&xTasksWaitingTermination,&( pxTCB->xStateListItem ));
标记当前需要做清理的任务数
++uxDeletedTasksWaitingCleanUp;/* Call the delete hook before portPRE_TASK_DELETE_HOOK() as
* portPRE_TASK_DELETE_HOOK() does not return in the Win32 port. */traceTASK_DELETE( pxTCB );
用以标记有任务需要删除,如果需要设置为pdTRUE,则在后面会调用prvDeleteTCB( pxTCB );释放掉这块内存空间。
xDeleteTCBInIdleTask = pdTRUE;/* The pre-delete hook is primarily for the Windows simulator,
* in which Windows specific clean up operations are performed,
* after which it is not possible to yield away from this task -
* hence xYieldPending is used to latch that a context switch is
* required. */#if( configNUMBER_OF_CORES ==1)portPRE_TASK_DELETE_HOOK( pxTCB,&( xYieldPendings[0]));#elseportPRE_TASK_DELETE_HOOK( pxTCB,&( xYieldPendings[ pxTCB->xTaskRunState ]));#endif
在SMP系统给按任务让出CPU,让其他任务去运行
#if( configNUMBER_OF_CORES >1){if(taskTASK_IS_RUNNING( pxTCB )== pdTRUE ){if( pxTCB->xTaskRunState ==( BaseType_t )portGET_CORE_ID()){configASSERT( uxSchedulerSuspended ==0);taskYIELD_WITHIN_API();}else{prvYieldCore( pxTCB->xTaskRunState );}}}#endif/* #if ( configNUMBER_OF_CORES > 1 ) */}else{--uxCurrentNumberOfTasks;traceTASK_DELETE( pxTCB );/* Reset the next expected unblock time in case it referred to
* the task that has just been deleted. */prvResetNextTaskUnblockTime();}}taskEXIT_CRITICAL();/* If the task is not deleting itself, call prvDeleteTCB from outside of
* critical section. If a task deletes itself, prvDeleteTCB is called
* from prvCheckTasksWaitingTermination which is called from Idle task. */if( xDeleteTCBInIdleTask != pdTRUE ){prvDeleteTCB( pxTCB );}/* Force a reschedule if it is the currently running task that has just
* been deleted. */#if( configNUMBER_OF_CORES ==1){if( xSchedulerRunning != pdFALSE ){if( pxTCB == pxCurrentTCB ){configASSERT( uxSchedulerSuspended ==0);taskYIELD_WITHIN_API();}else{mtCOVERAGE_TEST_MARKER();}}}#endif/* #if ( configNUMBER_OF_CORES == 1 ) */traceRETURN_vTaskDelete();}
UBaseType_t uxListRemove( ListItem_t *const pxItemToRemove ){/* The list item knows which list it is in. Obtain the list from the list
* item. */
List_t *const pxList = pxItemToRemove->pxContainer;traceENTER_uxListRemove( pxItemToRemove );
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;/* Only used during decision coverage testing. */mtCOVERAGE_TEST_DELAY();/* Make sure the index is left pointing to a valid item. */if( pxList->pxIndex == pxItemToRemove ){
pxList->pxIndex = pxItemToRemove->pxPrevious;}else{mtCOVERAGE_TEST_MARKER();}
pxItemToRemove->pxContainer =NULL;( pxList->uxNumberOfItems )=( UBaseType_t )( pxList->uxNumberOfItems -1U);traceRETURN_uxListRemove( pxList->uxNumberOfItems );return pxList->uxNumberOfItems;}