/** * The heap is made up as a list of structs of this type. * This does not have to be aligned since for getting its size, * we only use the macro SIZEOF_STRUCT_MEM, which automatically aligns. */ structmem { /** index (-> ram [next]) of the next struct */ mem_size_t next; /** index (-> ram [prev]) of the previous struct */ mem_size_t prev; /** 1: this area is used; 0: this area is unused */ u8_t used; #if MEM_OVERFLOW_CHECK /** this keeps track of the user allocation size for guard checks */ mem_size_t user_size; #endif };
/** If you want to relocate the heap to external memory, simply define * LWIP_RAM_HEAP_POINTER as a void-pointer to that location. * If so, make sure the memory at that location is big enough (see below on * how that space is calculated). */ #ifndef LWIP_RAM_HEAP_POINTER /** the heap. we need one struct mem at the end and some room for alignment */ LWIP_DECLARE_MEMORY_ALIGNED(ram_heap, MEM_SIZE_ALIGNED + (2U * SIZEOF_STRUCT_MEM)); #define LWIP_RAM_HEAP_POINTER ram_heap #endif/* LWIP_RAM_HEAP_POINTER */
初始化
初始化阶段 mem_init 执行以下操作,
检查 struct mem 大小是否满足 MEM_ALIGNMENT
对齐
对齐 heap 起始地址
初始化第一个空闲块
初始化末尾 哨兵块
设置 lfree 指向起始空闲块
初始化内存统计
创建互斥锁,保护多线程并发访问
变量
含义
ram
heap 起始地址,对齐后的地址
ram_end
heap 末尾的哨兵块
lfree
当前最低地址的空闲块,用于加速搜索
初始化完成后,堆结构如图所示
1 2 3 4 5 6 7 8 9 10 11
ram | v +--------------------------+------------------+ | struct mem, used = 0 | free memory | +--------------------------+------------------+ | v +------------------+ | ram_end sentinel | +------------------+
内存分配与释放
分配 (mem_malloc):
将请求大小对齐到 MEM_ALIGNMENT。
若小于 MIN_SIZE_ALIGNED(默认 12
字节),则提升到最小尺寸。
从 lfree
开始遍历链表,寻找第一个足够大的空闲块(首次适应算法)。
分割:如果空闲块足够大(能再放一个
struct mem + MIN_SIZE_ALIGNED),则切出所需大小,剩余部分成为新的空闲块;否则将整个空闲块分配(产生内部碎片)。
讨论
评论