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

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

/*这些宏,TLSF_FLS是最顶层的宏,用于调用TLSF_FLS32来计算一个数的最高位的位置。*/
#ifdef TLSF_64BIT
    #define TLSF_FLS(n) ((n) & 0xffffffff00000000ull ? 32 + TLSF_FLS32((size_t)(n) >> 32) : TLSF_FLS32(n))
#else
    #define TLSF_FLS(n) TLSF_FLS32(n)
#endif
/*宏TLSF_FLS32 确定n的最高位是否大于16位,如果大于16位,则通过位移进一步判断其在16至32位之间的哪一位,反之如果最高位16位之下则进一步判断8至16位*/
#define TLSF_FLS32(n) ((n) & 0xffff0000 ? 16 + TLSF_FLS16((n) >> 16) : TLSF_FLS16(n))
/*宏TLSF_FLS32 确定n的最高位是否大于8位,如果大于8位,则通过位移进一步判断其在8至16位之间的哪一位,反之如果最高位16位之下则进一步判断4至8位*/
#define TLSF_FLS16(n) ((n) & 0xff00     ?  8 + TLSF_FLS8 ((n) >>  8) : TLSF_FLS8 (n))
/*宏TLSF_FLS32 确定n的最高位是否大于4位,如果大于4位,则通过位移进一步判断其在4至8位之间的哪一位,反之如果最高位16位之下则进一步判断2至4位*/
#define TLSF_FLS8(n)  ((n) & 0xf0       ?  4 + TLSF_FLS4 ((n) >>  4) : TLSF_FLS4 (n))
/*宏TLSF_FLS32 确定n的最高位是否大于2位,如果大于2位,则通过位移进一步判断其在2至4位之间的哪一位,反之如果最高位16位之下则进一步判断1至2位*/
#define TLSF_FLS4(n)  ((n) & 0xc        ?  2 + TLSF_FLS2 ((n) >>  2) : TLSF_FLS2 (n))
/*宏TLSF_FLS32 确定n的最高位是否大于1位,如果大于1位,则通过位移进一步判断其在1和2位之间的哪一位,反之如果最高位16位之下则进一步判断0至1位*/
#define TLSF_FLS2(n)  ((n) & 0x2        ?  1 + TLSF_FLS1 ((n) >>  1) : TLSF_FLS1 (n))
#define TLSF_FLS1(n)  ((n) & 0x1        ?  1 : 0)
/*
** Returns round up value of log2(n).
** Note: it is used at compile time.
* x = Log2(n) => 2^x = n
* LSF_FLS(n)宏旨在计算n的最高位
* TLSF_LOG2_CEIL(n)宏通过位运算的方式来计算一个数的最高位的位置(log2),并且将结果向上取整。
* TLSF_LOG2_CEIL(n)宏在TLSF分配器中的作用是用于确定内存卡大小n所属内存池的类别,即应该将该内存块放到哪个内存池中
*/
/*在TLSF(Two-Level Segregated Fit)分配器中,TLSF_LOG2_CEIL宏用于计算一个数n的对数(以2为底)的上限。而TLSF_FLS宏用于返回一个数n的最高位的索引。

当n是2的幂时,TLSF_FLS宏返回的最高位索引需要减1的原因是,最高位的索引是从0开始计数的,而不是从1开始。例如,对于一个8位的数,最高位的索引是7,而不是8。

在TLSF_LOG2_CEIL宏中,需要计算n的对数的上限。当n是2的幂时,它的对数的上限是它的最高位的索引加1。因此,为了得到对数的上限,需要将TLSF_FLS宏返回的最高位索引加1。

综上所述,当n是2的幂时,TLSF_FLS宏返回的最高位索引需要减1,是为了得到对数的上限。*/
#define TLSF_LOG2_CEIL(n) ((n) & (n - 1) ? TLSF_FLS(n) : TLSF_FLS(n) - 1)

参考: 

lvgl的内存管理函数

你可能感兴趣的:(算法,TLSF,LVGL,内存管理)