• LVGL-TLSF内存管理算法-TLSF_LOG2_CEIL(n)宏详解:计算内存块所属内存池类别


     TLSF_LOG2_CEIL(n) 宏

    这个宏在TLSF(Two-Level Segregated Fit)分配器中经常用于计算内存块的大小类别,TLSF分配器使用一种分级的内存块管理方式,将不同大小的内存块分配到不同的内存池中,TLSF_LOG2_CEIL宏可以帮助确定一个内存块的大小类别,以便将其分配到正确的内存池中。

    其关键点有两部分:

    一、#define TLSF_LOG2_CEIL(n) ((n) & (n - 1) ? TLSF_FLS(n) : TLSF_FLS(n) - 1)

        宏本身,在n等于2的n幂时,需要在TLSF_FLS(n)宏返回的最高位index的基础上减一,缘由是因为判断最高位时是从0开始的,如TLSF_FLS(0x08)返回4,但实际最高位index=3,而当n不等于2的n幂时,index需要向上取整,以保证能兼容该内存块内所有的空间,TLSF_FLS(n)宏返回的最高位恰好满足向上取整index。

    二、#define TLSF_FLS(n) TLSF_FLS32(n)

    TLSF_FLS系列宏是计算n的最高位所在具体位数,如0x88(10001000B)最高位为8,0x07(00000111B)最高位为3

    其它具体可参考下述代码注释:

    1. /*这些宏,TLSF_FLS是最顶层的宏,用于调用TLSF_FLS32来计算一个数的最高位的位置。*/
    2. #ifdef TLSF_64BIT
    3. #define TLSF_FLS(n) ((n) & 0xffffffff00000000ull ? 32 + TLSF_FLS32((size_t)(n) >> 32) : TLSF_FLS32(n))
    4. #else
    5. #define TLSF_FLS(n) TLSF_FLS32(n)
    6. #endif
    7. /*宏TLSF_FLS32 确定n的最高位是否大于16位,如果大于16位,则通过位移进一步判断其在16至32位之间的哪一位,反之如果最高位16位之下则进一步判断8至16位*/
    8. #define TLSF_FLS32(n) ((n) & 0xffff0000 ? 16 + TLSF_FLS16((n) >> 16) : TLSF_FLS16(n))
    9. /*宏TLSF_FLS32 确定n的最高位是否大于8位,如果大于8位,则通过位移进一步判断其在8至16位之间的哪一位,反之如果最高位16位之下则进一步判断4至8位*/
    10. #define TLSF_FLS16(n) ((n) & 0xff00 ? 8 + TLSF_FLS8 ((n) >> 8) : TLSF_FLS8 (n))
    11. /*宏TLSF_FLS32 确定n的最高位是否大于4位,如果大于4位,则通过位移进一步判断其在4至8位之间的哪一位,反之如果最高位16位之下则进一步判断2至4位*/
    12. #define TLSF_FLS8(n) ((n) & 0xf0 ? 4 + TLSF_FLS4 ((n) >> 4) : TLSF_FLS4 (n))
    13. /*宏TLSF_FLS32 确定n的最高位是否大于2位,如果大于2位,则通过位移进一步判断其在2至4位之间的哪一位,反之如果最高位16位之下则进一步判断1至2位*/
    14. #define TLSF_FLS4(n) ((n) & 0xc ? 2 + TLSF_FLS2 ((n) >> 2) : TLSF_FLS2 (n))
    15. /*宏TLSF_FLS32 确定n的最高位是否大于1位,如果大于1位,则通过位移进一步判断其在1和2位之间的哪一位,反之如果最高位16位之下则进一步判断0至1位*/
    16. #define TLSF_FLS2(n) ((n) & 0x2 ? 1 + TLSF_FLS1 ((n) >> 1) : TLSF_FLS1 (n))
    17. #define TLSF_FLS1(n) ((n) & 0x1 ? 1 : 0)
    18. /*
    19. ** Returns round up value of log2(n).
    20. ** Note: it is used at compile time.
    21. * x = Log2(n) => 2^x = n
    22. * LSF_FLS(n)宏旨在计算n的最高位
    23. * TLSF_LOG2_CEIL(n)宏通过位运算的方式来计算一个数的最高位的位置(log2),并且将结果向上取整。
    24. * TLSF_LOG2_CEIL(n)宏在TLSF分配器中的作用是用于确定内存卡大小n所属内存池的类别,即应该将该内存块放到哪个内存池中
    25. */
    26. /*在TLSF(Two-Level Segregated Fit)分配器中,TLSF_LOG2_CEIL宏用于计算一个数n的对数(以2为底)的上限。而TLSF_FLS宏用于返回一个数n的最高位的索引。
    27. 当n是2的幂时,TLSF_FLS宏返回的最高位索引需要减1的原因是,最高位的索引是从0开始计数的,而不是从1开始。例如,对于一个8位的数,最高位的索引是7,而不是8。
    28. 在TLSF_LOG2_CEIL宏中,需要计算n的对数的上限。当n是2的幂时,它的对数的上限是它的最高位的索引加1。因此,为了得到对数的上限,需要将TLSF_FLS宏返回的最高位索引加1。
    29. 综上所述,当n是2的幂时,TLSF_FLS宏返回的最高位索引需要减1,是为了得到对数的上限。*/
    30. #define TLSF_LOG2_CEIL(n) ((n) & (n - 1) ? TLSF_FLS(n) : TLSF_FLS(n) - 1)

    参考: 

    lvgl的内存管理函数

     LVGL-TLSF内存管理算法源码详解(1)-内存池初始化-CSDN博客

  • 相关阅读:
    在线课程管理系统——lunwen
    uniapp 修改引入组件样式 使用/deep/、::v-deep、>>>不生效 解决
    mapbox 导航记录(release-v2.15分支 纯kotlin)
    袋鼠云产品功能更新报告01期丨用诚心倾听您的需求
    Rust Trait简介
    JAVA计算机毕业设计家政服务公司管理信息Mybatis+系统+数据库+调试部署
    react-router v6使用createHashHistory进行history.push时,url改变页面不渲染
    【通信原理】第三章 随机过程——例题
    JVM原理(三):JVM对象回收判定机制与回收算法
    vs studio Ctrl+D 快捷键失效(无法复制行)
  • 原文地址:https://blog.csdn.net/loveliyuyuan/article/details/133028474