UINT _tx_thread_suspend(
//指向线程的指针
TX_THREAD *thread_ptr);
如果挂起线程是当前执行线程(自我挂起),需要从就绪队列中选择出下一个最高优先级线程为执行线程,自我挂起说明当前线程是最高优先级线程:
1.如果当前线程就绪队列还有其它线程,那么选择同一个就绪队列中下一个线程.
2.如果当前线程是就绪队列中唯一线程,那么找出下一个最高优先级就绪队列,选择其中第一个线程为执行线程。
3.选择下一个最高级就绪队列时,需要考虑tx_preempt_threshold
局部变量:
流程:
1. 禁止中断
2.开启抢占
3.检查tx_suspending是否为TX_TRUE。如果不为TX_TRUE,说明线程已经resume,不需要做任何操作。若为TX_TRUE
(1) 清除suspending flag
(2) priority记录该线程优先级
(3) 若同优先级就绪队列中还有其他线程,把该线程从队列中删除
1) 若该线程是就绪队列中第一个线程,那么可能是当前正执行的线程
更新priority list的头指针
a) 若该线程之前被抢占过,并设置了preempted map,清除掉
b) 若该线程为执行线程,需要重新选择最高优先级线程为执行线程。
//由于该线程为执行线程,说明所在的就绪队列为最高优先级。
//所以选择的就是就绪队列中的下一个线程
(4) 若同优先级就绪队列只有该线程
//如果是其他线程调用该线程,只需要从就绪优先级位图priority map中删除需要挂起的线程
//如果是自我挂起(当前执行线程是最高优先级线程),需选出下一个最高优先级线程
1) priority_list[priority] = NULL
2) 清除对应位图bit
3) 若设置抢占阈值,清除preempted map
4) 挑选下一个最高优先级线程,妙啊!
//为了减少计算,采用了分组方式进行判断。
//分为五组,优先级0-7、8-15、26-23、24-31、无就绪优先级
//lowest_bit[ ]:lowest_bit[0(0b00)]=0、lowest_bit[1(0b01)]=0、lowest_bit[2(0b10)]=1、lowest_bit[3(0b11)]=0
a) 选出下一个最高优先级
_tx_thread_highest_priority存储下一个最高优先级
以第一个if(TX_THREAD_GROUP_0)为例:
TX_THREAD_GROUP_0_MASK为0x000000FF,与priority_map与后即筛选出优先级0-7,若优先级0-7有线程,则满足条件。priority为0。
假设priority_map为0010 0011 1000 0001 1111 0000 1010 0100,则_tx_thread_highest_priority=0+_tx_thread_lowest_bit[……1010 0100]=0+2=2
b) 若无就绪优先级
i) highest_priority=32
ii) 执行线程为NULL
iii) 恢复中断
iv) 若是由其他线程调用的,system_return( )
v) return 返回caller
5) 自我挂起
a) 设置最高优先级(前面计算出来的)线程为执行线程
b) 如果preempted_map不为0,说明之前发生了基于抢占阈值的抢占,那么下一个执行线程选择必须考虑抢占阈值
i) 禁止抢占
ii) 恢复中断
iii) 禁止中断
iv) 恢复抢占
v) 计算出被抢占的最高优先级(和之前算下一个最高优先级一样的算法)
vi) 如果选择出的被抢占的最高优先级线程的抢占阈值小于(数值小于,即优先级大)最高优先级,那么设置执行线程为被抢占的最高优先级线程
4.恢复中断
5.若当前线程不为执行线程(即发生了中断),system_return( )