zoukankan      html  css  js  c++  java
  • 【转载】uCOS2 关于进程调度的O(1)算法

    uCOS2唯一值得学习的一个地方就是关于进程调度的O(1)算法

          最简单也是最愚蠢的方法是维护一个链表List。

          这种方法的问题是:当一个Thread就绪时,如果根据其优先级插入List,则算法的时间复杂度为O(n)。

          Linux采用了Bitmap,uCOS2也不例外。当然uCOS2的处理更简单,因为uCOS2必须在系统编译时配置好支持的Thread最大数量,用来分配Bitmap。

          例如:

          支持64, 则分配8字节的Bitmap,如果支持256,则分配16字节的Bitmap。

          Bitmap的每一个Bit代表thread的状态,如果Bit为1则表示就绪,0则表示挂起。

          以64为例:

        

           在Bitmap中如何快速找到为1的BIT,再转换成THREAD的优先级?

           如果采用扫描的方式,按位与操作不是好方法,这里涉及循环和计数。所以操作时间和THREAD数量又成O(N)了。

           所以uCOS2采用了分组的方法:8个字节64BIT,分为8*8,如图。

           用OSRdyGrp变量的BIT来指示哪个分组里有就绪的THREAD,然后在提取出来该分组,再从该分组中找到优先级最高的THREAD。

           线程优先级Priority和分组的关系如图。也就是X,Y如何组成Priority。

      还有一个问题:如何找到优先级最高的线程?Priority值越小,Thread优先级越高。

      比如OSRdyGrp = 0x10001000,OSRdyTbl[3]=0x10001000.

           很明显OSRdyGrp的BIT4和OSRdyTbl[3]的BIT4代表的Thread 27才是我们想要的。

       

      为了解决这个问题,uCOS2又采用的了一个快速转换表OSMapTbl。

           该转换表原理如下: 0x10001000 --->转换表---->3

                                            0x00001000 --->转换表--->3

            1字节8BIT,有256种BIT组合,但是组合方式返回的值是可以提前算好,存在OSMapTbl中。

          比如OSRdyGrp=0x11111111和OSRdyGrp=0x00000001都应该返回0. [0代表第一个分组]

           所以OSMapTbl如下:

          

    INT8U const OSUnMapTbl[256] = {
    0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x00 to 0x0F */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x10 to 0x1F */
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x20 to 0x2F */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x30 to 0x3F */
    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x40 to 0x4F */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x50 to 0x5F */
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x60 to 0x6F */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x70 to 0x7F */
    7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x80 to 0x8F */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x90 to 0x9F */
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xA0 to 0xAF */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xB0 to 0xBF */
    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xC0 to 0xCF */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xD0 to 0xDF */
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xE0 to 0xEF */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 /* 0xF0 to 0xFF */
    };  可以看出OSMapTbl[0]和OSMapTbl[255]都是0。

           

    本文链接:http://www.cnblogs.com/cposture/p/4291540.html                       

  • 相关阅读:
    Python解析excel文件并存入sqlite数据库
    python简单爬虫
    Python开发简单记事本
    Django初体验——搭建简易blog
    LeetCode — (1)
    机器学习(九)—FP-growth算法
    机器学习(八)—Apriori算法
    linux下debug工具
    linux同步与通信
    后台开发之IO缓冲区管理
  • 原文地址:https://www.cnblogs.com/cposture/p/4291540.html
Copyright © 2011-2022 走看看