挂起线程 tx_tsus.c

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( )

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值