lwip之内存管理
来源:互联网 发布:手机淘宝的微淘在哪里 编辑:程序博客网 时间:2024/05/23 16:43
1、C library内存管理
c库自带内存分配和释放函数malloc和free:
void *malloc(long NumBytes):该函数分配了NumBytes个字节,并返回了指向这块内存的指针。如果分配失败,则返回一个空指针(NULL)。
void free(void *FirstByte): 该函数是将之前用malloc分配的空间还给程序或者是操作系统,也就是释放了这块内存,让它重新得到自由。
2、lwip内存池管理
1)相关宏定义
(a)内存策略宏开关
//使用C library中函数malloc和free实现内存堆分配和释放MEM_LIBC_MALLOC==1 //使用lwip内存堆分配策略实现内存池分配MEMP_MEM_MALLOC==1//使用lwip内存池分配策略实现内存堆的分配,需额外定义新的内存池MEM_USE_POOLS==1MEMP_USE_CUSTOM_POOLS==1MEM_USE_POOLS_TRY_BIGGER_POOL==1//新内存池定义格式如下: /* Define three pools with sizes 256, 512, and 1512 bytes * LWIP_MALLOC_MEMPOOL_START * LWIP_MALLOC_MEMPOOL(20, 256) * LWIP_MALLOC_MEMPOOL(10, 512) * LWIP_MALLOC_MEMPOOL(5, 1512) * LWIP_MALLOC_MEMPOOL_END */
(b)内存字节、地址对齐宏定义
#define MEM_ALIGNMENT 4 /*cpu alignment*///(e.g. LWIP_MEM_ALIGN_SIZE(3) and LWIP_MEM_ALIGN_SIZE(4) will both yield 4 for MEM_ALIGNMENT == 4)#define LWIP_MEM_ALIGN_SIZE(size) (((size) + MEM_ALIGNMENT - 1) & ~(MEM_ALIGNMENT-1))// (e.g. if buffer is u8_t[] and actual data will be u32_t*)#define LWIP_MEM_ALIGN_BUFFER(size) (((size) + MEM_ALIGNMENT - 1))// ADDR % MEM_ALIGNMENT == 0#define LWIP_MEM_ALIGN(addr) ((void *)(((mem_ptr_t)(addr) + MEM_ALIGNMENT - 1) & ~(mem_ptr_t)(MEM_ALIGNMENT-1)))
(c)内存池全局变量声明
#define MEMP_SIZE 0#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x))/** This array holds the first free element of each pool. Elements form a linked list. */static struct memp *memp_tab[MEMP_MAX];//不同类型内存池的大小static const u16_t memp_sizes[MEMP_MAX] = {#define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEM_ALIGN_SIZE(size),#include "lwip/memp_std.h"};//不同类型内存池的数量static const u16_t memp_num[MEMP_MAX] = {#define LWIP_MEMPOOL(name,num,size,desc) (num),#include "lwip/memp_std.h"};//调试专用描述符static const char *memp_desc[MEMP_MAX] = {#define LWIP_MEMPOOL(name,num,size,desc) (desc),#include "lwip/memp_std.h"};//定义内存池数组,开辟静态内存空间static u8_t memp_memory[MEM_ALIGNMENT - 1 #define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) )#include "lwip/memp_std.h"
(d)未用到功能的宏设置
#define MEMP_STATS 0#define MEMP_SEPARATE_POOLS 0#define MEMP_OVERFLOW_CHECK 0#define MEMP_SANITY_CHECK 0
2)内存池实现
(a)结构体声明
//内存池类型枚举typedef enum {#define LWIP_MEMPOOL(name,num,size,desc) MEMP_##name,#include "lwip/memp_std.h" MEMP_MAX} memp_t;//内存池操作结构体struct memp { struct memp *next;};
(b)各种类型内存池数量及其大小的定义(部分)
LWIP_MEMPOOL(RAW_PCB,MEMP_NUM_RAW_PCB, sizeof(struct raw_pcb), "RAW_PCB")LWIP_MEMPOOL(UDP_PCB, MEMP_NUM_UDP_PCB, sizeof(struct udp_pcb), "UDP_PCB")LWIP_MEMPOOL(TCP_PCB,MEMP_NUM_TCP_PCB, sizeof(struct tcp_pcb), "TCP_PCB")#define LWIP_PBUF_MEMPOOL(name, num, payload, desc) LWIP_MEMPOOL(name, num, MEMP_ALIGN_SIZE(sizeof(struct pbuf)) + MEMP_ALIGN_SIZE(payload)), desc)LWIP_PBUF_MEMPOOL(PBUF, MEMP_NUM_PBUF, 0, "PBUF_REF/ROM")LWIP_PBUF_MEMPOOL(PBUF_POOL,PBUF_POOL_SIZE, PBUF_POOL_BUFSIZE,"PBUF_POOL")
(c)内存池初始化memp_init
初始化内存池结构示意图
void memp_init(void){ struct memp *memp; u16_t i, j; memp = (struct memp *)LWIP_MEM_ALIGN(memp_memory); /* for every pool: */ for (i = 0; i < MEMP_MAX; ++i) { memp_tab[i] = NULL; /* create a linked list of memp elements */ for (j = 0; j < memp_num[i]; ++j) { memp->next = memp_tab[i]; memp_tab[i] = memp; memp = (struct memp *)(void *)((u8_t *)memp + MEMP_SIZE + memp_sizes[i]); } }}
(d)内存池分配memp_malloc
void *memp_malloc(memp_t type){ struct memp *memp; SYS_ARCH_DECL_PROTECT(old_level); SYS_ARCH_PROTECT(old_level); memp = memp_tab[type];//申请一个type类型的内存池 if (memp != NULL) { memp_tab[type] = memp->next; memp = (struct memp*)(void *)((u8_t*)memp + MEMP_SIZE); } else { MEMP_STATS_INC(err, type); } SYS_ARCH_UNPROTECT(old_level); return memp;}
(e)内存池释放memp_free
void memp_free(memp_t type, void *mem){ struct memp *memp; SYS_ARCH_DECL_PROTECT(old_level); if (mem == NULL) { return; } memp = (struct memp *)(void *)((u8_t*)mem - MEMP_SIZE); SYS_ARCH_PROTECT(old_level); MEMP_STATS_DEC(used, type); //切换表头 memp->next = memp_tab[type]; memp_tab[type] = memp; SYS_ARCH_UNPROTECT(old_level);}
3、lwip内存堆管理
1)、miscellaneous声明
//内存堆管理结构体struct mem { mem_size_t next; //字节索引号 mem_size_t prev; u8_t used;};//mem_size_t声明#if MEM_SIZE > 64000Ltypedef u32_t mem_size_t;#define MEM_SIZE_F U32_F#elsetypedef u16_t mem_size_t;#define MEM_SIZE_F U16_F#endif /* MEM_SIZE > 64000 *///自定义最小、最大申请内存大小#define MIN_SIZE 12#define MEM_SIZE (10*1024)//对齐声明#define MIN_SIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(MIN_SIZE)#define SIZEOF_STRUCT_MEM LWIP_MEM_ALIGN_SIZE(sizeof(struct mem))#define MEM_SIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEM_SIZE)//全局变量声明,静态数组声明u8_t ram_heap[MEM_SIZE_ALIGNED + (2*SIZEOF_STRUCT_MEM) + MEM_ALIGNMENT];#define LWIP_RAM_HEAP_POINTER ram_heapstatic u8_t *ram;static struct mem *ram_end;static struct mem *lfree;
2)、内存堆初始化mem_init
void mem_init(void){ struct mem *mem; /* align the heap */ // LWIP_RAM_HEAP_POINTER <=> ram_heap ram = (u8_t *)LWIP_MEM_ALIGN(LWIP_RAM_HEAP_POINTER); /* initialize the start of the heap */ mem = (struct mem *)(void *)ram; mem->next = MEM_SIZE_ALIGNED; mem->prev = 0; mem->used = 0; /* initialize the end of the heap */ ram_end = (struct mem *)(void *)&ram[MEM_SIZE_ALIGNED]; ram_end->used = 1; ram_end->next = MEM_SIZE_ALIGNED; ram_end->prev = MEM_SIZE_ALIGNED; //initialize the lowest-free pointer to the start of the heap lfree = (struct mem *)(void *)ram; MEM_STATS_AVAIL(avail, MEM_SIZE_ALIGNED); if(sys_mutex_new(&mem_mutex) != ERR_OK) { LWIP_ASSERT("failed to create mem_mutex", 0); }}
初始化及分配2个内存块的结构示意图如:
3)、内存堆分配mem_malloc
void *mem_malloc(mem_size_t size){ mem_size_t ptr, ptr2; struct mem *mem, *mem2; LWIP_MEM_ALLOC_DECL_PROTECT(); if (size == 0) { return NULL; } /* Expand the size of the allocated memory region so that we can adjust for alignment. */ size = LWIP_MEM_ALIGN_SIZE(size);//检查申请空间的大小 if(size < MIN_SIZE_ALIGNED) { size = MIN_SIZE_ALIGNED; } if (size > MEM_SIZE_ALIGNED) { return NULL; } sys_mutex_lock(&mem_mutex); LWIP_MEM_ALLOC_PROTECT(); for (ptr = (mem_size_t)((u8_t *)lfree - ram); ptr < MEM_SIZE_ALIGNED - size; ptr = ((struct mem *)(void *)&ram[ptr])->next) { mem = (struct mem *)(void *)&ram[ptr]; // 判断该空闲内存块未用且容量是否大于size if ((!mem->used) && (mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) { //判断该空闲块容量是否大于size + MIN_SIZE_ALIGNED if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >= (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)) { //申请size大小内存块后,组织剩下的空闲内存 ptr2 = ptr + SIZEOF_STRUCT_MEM + size; /* create mem2 struct */ mem2 = (struct mem *)(void *)&ram[ptr2]; mem2->used = 0; mem2->next = mem->next; mem2->prev = ptr; // and insert it between mem and mem->next mem->next = ptr2; mem->used = 1; if (mem2->next != MEM_SIZE_ALIGNED) { ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2; }MEM_STATS_INC_USED(used, (size + SIZEOF_STRUCT_MEM)); } else { //空闲块容量大于size,小于size + MIN_SIZE_ALIGNE时,直接占用该内存块 mem->used = 1; MEM_STATS_INC_USED(used, mem->next - (mem_size_t)((u8_t *)mem - ram)); } //移动lfree指针 if (mem == lfree) { struct mem *cur = lfree;// Find next free block after mem and update lowest free pointer while (cur->used && cur != ram_end) { cur = (struct mem *)(void *)&ram[cur->next]; } lfree = cur; } LWIP_MEM_ALLOC_UNPROTECT(); sys_mutex_unlock(&mem_mutex); return (u8_t *)mem + SIZEOF_STRUCT_MEM; } } MEM_STATS_INC(err); LWIP_MEM_ALLOC_UNPROTECT(); sys_mutex_unlock(&mem_mutex); return NULL;}
多次分配内存堆后的结构示意图
4)、内存堆释放mem_free
void mem_free(void *rmem){ struct mem *mem; LWIP_MEM_FREE_DECL_PROTECT(); if (rmem == NULL) { return; } if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) { SYS_ARCH_DECL_PROTECT(lev); /* protect mem stats from concurrent access */ SYS_ARCH_PROTECT(lev); MEM_STATS_INC(illegal); SYS_ARCH_UNPROTECT(lev); return; } /* protect the heap from concurrent access */ /* Get the corresponding struct mem ... */ mem = (struct mem *)(void *)((u8_t *)rmem - SIZEOF_STRUCT_MEM); mem->used = 0; if (mem < lfree) { /* the newly freed struct is now the lowest */ lfree = mem; } MEM_STATS_DEC_USED(used, mem->next - (mem_size_t)(((u8_t *)mem - ram))); //finally, see if prev or next are free also // 合并相邻空闲块 plug_holes(mem); LWIP_MEM_FREE_UNPROTECT();}
合并相邻空闲块函数plug_holes
static void plug_holes(struct mem *mem){ struct mem *nmem; struct mem *pmem; //检测释放内存块指向的下一个内存块 nmem = (struct mem *)(void *)&ram[mem->next]; if (mem != nmem && nmem->used == 0 && (u8_t *)nmem != (u8_t *)ram_end) { if (lfree == nmem) { lfree = mem; } mem->next = nmem->next; ((struct mem *)(void *)&ram[nmem->next])->prev = (mem_size_t)((u8_t *)mem - ram); } //检测释放内存块指向的上一个内存块 pmem = (struct mem *)(void *)&ram[mem->prev]; if (pmem != mem && pmem->used == 0) { if (lfree == mem) { lfree = pmem; } pmem->next = mem->next; ((struct mem *)(void *)&ram[mem->next])->prev = (mem_size_t)((u8_t *)pmem - ram); }}
0 0
- lwip之内存管理
- LwIP之内存管理和配置
- 操作系统之内存管理
- Android之内存管理
- OC之内存管理
- cocos2dx 之内存管理
- c++之内存管理
- OC之内存管理
- jvm之内存管理
- 操作系统之内存管理
- 简单之内存管理
- OC之内存管理
- cocos2dx 之内存管理
- Android之内存管理
- OC之内存管理
- OC之内存管理
- 虚拟机之内存管理
- iOS之内存管理
- rsyslog 模板
- springmvc原理
- C++ 重载操作符 operator
- |Hdu 2222|AC自动机|Keywords Search
- 感悟001:关于分享,CTRL+C,CTRL+V
- lwip之内存管理
- JVM参数理解
- 关于第三方登录,你应该知道的
- 【OTT】Fandango introuduce
- Gson的两种解析用法
- matlab 声道分离合并与组合
- spring SpringMVC MyBatis 搭建项目 MavenWeb项目
- HTTP Specification_1.1 译文
- Android View 绘制流程