新創建線程時或其他線程主動讓某個線程執行,會調用_tx_thread_resume,把新的線程加入調度list,並選擇出下一個需要執行的線程。基本原理:選出系統中最高優先級線程爲執行線程
1,恢復線程正在掛起過程中,只需要修改線程狀態爲就緒
2,線程已經掛起或新創建的線程,那麼加入到就緒list中
3,就緒list爲基於優先級的數組列表
4,先根據優先級找到_tx_thread_priority_list[priority]對應list,再插入尾部
5,如果系統中沒有執行的線程,那麼設置恢復線程爲執行線程,並且設置系統中最高優先級_tx_thread_highest_priority 爲恢復線程優先級
6,系統中已經存在執行線程,那麼比較優先級,如果恢復線程優先級大於_tx_thread_highest_priority ,設置恢復線程爲執行線程,並且設置系統中最高優先級_tx_thread_highest_priority 爲恢復線程優先級
7,如果恢復線程優先級小於系統中最高優先級,那麼不需要處理,已經插入就緒列表中。
8,如果上述選擇出了新的執行線程,就返回true,可以進行搶佔
_tx_thread_resume(TX_THREAD *thread_ptr)
入參 | 意義 |
---|---|
thread_ptr | 將要恢復線程的線程控制塊指針 |
UINT _tx_thread_resume(TX_THREAD *thread_ptr)
{
TX_INTERRUPT_SAVE_AREA
UINT preemption; /* Preempt condition flag */
REG_1 UINT priority; /* Thread priority */
REG_2 TX_THREAD *head_ptr; /* Thread priority head pointer */
REG_2 TX_THREAD *tail_ptr; /* Thread priority tail pointer */
/* Initialize the preemption flag to false. */
preemption = TX_FALSE;
/* Lockout interrupts while the thread is being resumed. */
#def 禁止中斷,防止被搶佔
TX_DISABLE
/* Decrease the preempt disabled count. */
_tx_thread_preempt_disable--;
/* Determine if the thread is in the process of suspending. If so, the thread
control block is already on the linked list so nothing needs to be done. */
#def 線程正在掛起過程中,那麼線程已經在調度列表了,不是新創建線程。只需要改變線程狀態爲TX_READY
if (thread_ptr -> tx_suspending)
{
/* Make sure the type of suspension under way is not a terminate or
thread completion. In either of these cases, do not void the
interrupted suspension processing. */
if ((thread_ptr -> tx_state != TX_COMPLETED) &&
(thread_ptr -> tx_state != TX_TERMINATED))
{
/* Clear the suspending flag. */
thread_ptr -> tx_suspending = TX_FALSE;
/* Restore the state to ready. */
#def 轉爲就緒態
thread_ptr -> tx_state = TX_READY;
}
}
/* Check to make sure the thread has not already been resumed. */
else if (thread_ptr -> tx_state != TX_READY)
{
/* Check for a delayed suspend flag. */
if (thread_ptr -> tx_delayed_suspend)
{
/* Clear the delayed suspend flag and change the state. */
thread_ptr -> tx_delayed_suspend = TX_FALSE;
thread_ptr -> tx_state = TX_SUSPENDED;
}
else
{
/* Log the thread status change. */
TX_EL_THREAD_STATUS_CHANGE_INSERT(thread_ptr, TX_READY);
/* Make this thread ready. */
/* Change the state to ready. */
#def 轉爲就緒態
thread_ptr -> tx_state = TX_READY;
/* Pickup priority of thread. */
priority = thread_ptr -> tx_priority;
/* Determine if there are other threads at this priority that are
ready. */
#def 獲取對應優先級列表頭指針,把線程插入優先級list尾
head_ptr = _tx_thread_priority_list[priority];
#def 優先級list中已經有線程
if (head_ptr)
{
/* Yes, there are other threads at this priority already ready. */
/* Just add this thread to the priority list. */
tail_ptr = head_ptr -> tx_ready_previous;
tail_ptr -> tx_ready_next = thread_ptr;
head_ptr -> tx_ready_previous = thread_ptr;
thread_ptr -> tx_ready_previous = tail_ptr;
thread_ptr -> tx_ready_next = head_ptr;
}
else
{
#def 優先級list爲空,恢復線程爲第一個線程
/* First thread at this priority ready. Add to the front of the
list. */
_tx_thread_priority_list[priority] = thread_ptr;
thread_ptr -> tx_ready_next = thread_ptr;
thread_ptr -> tx_ready_previous = thread_ptr;
/* Or in the thread's priority bit. */
#def 設置優先級位圖對應bit位爲1
_tx_thread_priority_map = _tx_thread_priority_map | thread_ptr -> tx_priority_bit;
/* Check to see if this is a higher priority thread. */
#def _tx_thread_execute_ptr爲當前執行線程或將要執行線程(也就是就緒隊列中優先級最高線程) ,如果爲空,說明沒有任何線程執行,把恢復線程直接設置爲將要執行線程,且爲最高優先級
if (_tx_thread_execute_ptr == TX_NULL)
{
/* No other thread is ready. Setup the highest priority and
the execute thread pointer. */
_tx_thread_execute_ptr = thread_ptr;
_tx_thread_highest_priority = priority;
}
else if (priority < _tx_thread_highest_priority)
{
#def 恢復線程優先級大於於就緒隊列中最高優先級,設置最高優先級爲恢復線程優先級
/* A new highest priority thread is present. */
/* Update the highest priority variable. */
_tx_thread_highest_priority = priority;
/* Determine if preemption is allowed. */
#def 優先級大於最高優先級的搶佔閾值
if (priority < _tx_thread_execute_ptr -> tx_preempt_threshold)
{
/* Determine if this thread had preemption threshold set. */
if (_tx_thread_execute_ptr -> tx_preempt_threshold !=
_tx_thread_execute_ptr -> tx_priority)
{
/* Remember that this thread was preempted by a thread
above the thread's threshold. */
_tx_thread_preempted_map = _tx_thread_preempted_map |
_tx_thread_execute_ptr -> tx_priority_bit;
}
/* Yes, modify the execute thread pointer. */
#def 設置恢復線程爲執行線程
_tx_thread_execute_ptr = thread_ptr;
}
}
}
}
}
/* Restore interrupts. */
TX_RESTORE
/* Determine if preemption should take place. */
#def 如果上面選擇出了新的線程_tx_thread_execute_ptr,並且系統初始化完成,那麼返回可以搶佔。
if ((_tx_thread_current_ptr != _tx_thread_execute_ptr) && (_tx_thread_system_state == 0))
/* Yes, set the preemption flag. */
preemption = TX_TRUE;
/* Return preemption flag. */
return(preemption);
}