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的内存管理函数

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
TLSF(Two-Level Segregated Fit)内存分配算法是一种通用的动态内存分配算法,专门设计用于满足实时要求。它具有以下特点: 1. 算法复杂度为O(1):TLSF算法通过使用两级位图和分级空闲块链表的数据结构来管理动态内存池和其中的空闲块。这种设计使得malloc、free、realloc和memalign等操作的时间复杂度都为O(1),即常数时间。 2. 低碎片化:TLSF算法采用Good-Fit的策略进行内存分配,即选择最合适大小的空闲块进行分配。这样可以减少内存碎片化,提高内存利用率。 3. 支持动态添加和删除内存池区域:TLSF算法支持在运行时动态地增加或删除多块不连续的内存,将它们作为一个内存堆使用。这种灵活性使得TLSF算法适用于各种内存管理场景。 下面是一个使用TLSF内存分配算法的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include "tlsf.h" int main() { // 创建一个TLSF内存池 void* pool = malloc(1024 * 1024); // 分配1MB的内存作为内存池 tlsf_pool tlsf = tlsf_create_with_pool(pool, 1024 * 1024); // 分配内存 void* ptr1 = tlsf_malloc(tlsf, 100); // 分配100字节的内存 void* ptr2 = tlsf_malloc(tlsf, 200); // 分配200字节的内存 // 使用分配的内存 sprintf(ptr1, "Hello"); sprintf(ptr2, "World"); // 打印分配的内存 printf("ptr1: %s\n", (char*)ptr1); printf("ptr2: %s\n", (char*)ptr2); // 释放内存 tlsf_free(tlsf, ptr1); tlsf_free(tlsf, ptr2); // 销毁TLSF内存池 tlsf_destroy(tlsf); // 释放内存池 free(pool); return 0; } ``` 这段代码演示了如何使用TLSF内存分配算法进行内存分配和释放。首先,我们创建一个TLSF内存池,并使用tlsf_malloc函数分配内存。然后,我们使用分配的内存进行操作,并最后使用tlsf_free函数释放内存。最后,我们销毁TLSF内存池并释放内存池。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值