需求
uC/os内存管理机制为内存块形式,用户申请内存是需要自己指定内存区内内存块数和内存块大小,看起来很灵活,实际上很不方便,需要使用者记住内存块大小,自己维护内存区,给使用者增加了负担。
TLSF算法能够满足实时性的要求,并且可有效的较小内部碎片。TLSF作为分离式空闲链表算法(Segregated Free Lists)的拓展--将相似的空闲块利用数组或者二叉树进行管理从而使响应时间与空闲块数量相互独立,能够满足实时系统的需求。LINUX使用的兄弟算法,能将碎片控制在内存块大小的1/2之下,而TLSF算法将内存块大小进行更细致的分类,将内部碎片尽量缩小。TLSF在内存释放时则会立即释放并且与相邻的空闲内存进行合并。其他的DSA或许会进行延迟合并,或者根本不合并。这种机制在应用反复申请相同大小的内存时会很有用,但是延迟合并带来的是时间的不可预测,所以TLSF避免了这种现象。
算法思想
TLSF的全称是Two Level Segregated Fit memory allocator,名称就显示了此算法的特点,segregated fit 和 two level。基本的Segregated Fit算法是使用一组链表来管理空闲块,每个链表只包含特定长度范围内的空闲块,而管理这些链表头的数组会非常冗长,TLSF使用了二位数组来管理这些表头,简化了查找定位的过程。在第一层将空闲块大小按照2的次幂进行粗分,因为内存块大小至少为2^4,所以一般分为(16、32、、、、2^31),第二层在第一层的基础上,按照规定好的间隔对内存块进行细分,比如我们可以将2^4~2^5大小的内存块进一步分为(16~20),(20~24),(24~28),(28~32)。分成几个区间可以由用户设定(但一定是2的次方个)。每一级都对应bitmap中的一个位来表示是否有空闲块。
内存状态立体化结构如图
比如上图中第一级的bitmap中第三位为1,那么就有大小为2^6~2^7的空闲块,再查看二级Bitmap,第二位为1说明有大小为2^6+16~2^6+32的空闲块。
那么给定一个内存大小怎么知道他所对应的一二级索引值呢
我们可以观察到,f的值为size的最高有效位的位数。S为偏移量除以区间大小。
算法实现
数据