rtthread_"rt_schedule"优先级调度

RTThread操作系统使用优先级表和优先级组进行线程调度。优先级表包含32个对象,每个对象对应一个优先级链表。高优先级线程可以暂停低优先级线程,同优先级线程通过时间片轮询执行。调度主要由rt_thread_ready_priority_group和rt_thread_priority_table管理,通过位图算法快速找到最高优先级线程。系统初始化时会设置这些数据结构,调度过程包括插入和删除线程,实际调度由rt_schedule函数执行。

3 线程调度scheduler

  rtthread中对于多线程切换是通过优先级表搭配优先级组进行调度的,优先级表中存储所有线程的node,优先级组中存储线程的优先级;

  优先级表通常有32个对象,每个优先级都是一个list_head节点,相同优先级的线程存储在相同优先级链表下;

  rtos中高优先级的线程可以将低优先级的线程suspend,然后让芯片执行高优先级的线程;对于优先级相同的线程rtos通过时间片轮询执行;

  线程调度函数比想象中简单的多,主要分为两个函数,一个是第一次执行调度的函数、一个是之后执行调度的函数;

  3.1 rt_thread_ready_priority_group

    线程就绪优先级组是一个32bits常数,每1bit对应一个优先级,通过对优先级组中最低位的判断可以知道当前线程的最高优先级;

    优先级组用来配合优先级表进行系统调度;

    3.1.1 优先级组定义

//scheduler.c
#if RT_THREAD_PRIORITY_MAX > 32
/* Maximum priority level, 256 */
rt_uint32_t rt_thread_ready_priority_group;
rt_uint8_t rt_thread_ready_table[32];
#else
/* Maximum priority level, 32 */
rt_uint32_t rt_thread_ready_priority_group;        //线程就绪优先级组
#endif

    3.1.2 优先级组查询

      如果对优先级组按bit判断取出最高优先级,rtthread觉得那样浪费时间,所以rtthread采用了一种以内存换效率的数组寻址优先级,搭配逻辑判断使用;

      为什么不32bit全部采用数组寻址,可能全部采用数组寻址内存占用又太大划不来;

//scheduler.c 优先级组调用方式;
    highest_ready_priority = __rt_ffs(rt_thread_ready_priority_group) - 1;
    to_thread = rt_list_entry(rt_thread_priority_table[highest_ready_priority].next, struct rt_thread, tlist);

//kservice.c 
//判断函数中对优先级都进行了+1处理,所以调用函数中又-1处理;
int __rt_ffs(int value)
{
    if (value == 0) 
        return 0;                                                    //优先级组为空,调用函数中-1处理得到-1 error;
    if (value & 0xff)
        return __lowest_bit_bitmap[value & 0xff] + 1;                //bit[7:0],优先级为0也会+1处理;
    if (value & 0xff00)
        return __lowest_bit_bitmap[(value & 0xff00) >> 8] + 9;       //bit[15:8]
    if (value & 0xff0000)
        return __lowest_bit_bitmap[(value & 0xff0000) >> 16] + 17;   //bit[23:16]
    
    return __lowest_bit_bitmap[(value & 0xff000000) >> 24] + 25;     //bit[31:24]
}
//咋一看还以为是什么复杂的东西,其实这个数组纯粹力气活,把可能性(0:255)依次穷举列出,然后再把该数值的最高优先级存入在数值所在位;
//不要觉得这个数组是个力气活就不当回事,人家还有一个高精尖的名字叫“位图算法”;
//下面的优先级是所在字节的实际优先级
const rt_uint8_t __lowest_bit_bitmap[] =
{
    /* 00 */ 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* 10 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* 20 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* 30 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* 40 */ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* 50 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* 60 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* 70 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* 80 */ 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* 90 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* A0 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* B0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* C0 */ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* D0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    /* E0 */ 5, 0, 1, 0, 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值