新创建线程时或其他线程主动让某个线程执行,会调用_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);
}