静态内存分配-链表管理(2)实现
来源:互联网 发布:旅行者1号 知乎 编辑:程序博客网 时间:2024/05/17 06:54
概述
静态内存为开辟若干个Buf,在每个buf增加控制头,该控制头即为链表的节点。如下图所示。
实现
底层数据结构为
struct hstack_mem_pool { u32 used; u8 buf[HSTACK_MEMORY_POOL_BUFFER_SIZE]; } mem_pool[HSTACK_MEMORY_POOL_ITEMS];
此处开辟了HSTACK_MEMORY_POOL_ITEMS个静态内存,每一块静态内存均是由buf和used组成。此处的buf包含了用户使用的buf和控制头(链表)两个部分。
底层Malloc实现:
void *HstackList_MallocIMP(u8 length){ u8 i; if (length > HSTACK_MEMORY_POOL_BUFFER_SIZE) { assert(0); } for (i = 0; i < HSTACK_MEMORY_POOL_ITEMS; i++) { if (cb.mem_pool[i].used == 0) { cb.mem_pool[i].used = 1; return ((void *)(cb.mem_pool[i].buf)); } } return NULL;}
此函数返回了静态buf的首地址,在list层调用该函数,即可申请内存。list层内存申请如下代码
struct hstack_datablock *HstackList_New(u8 length){ struct hstack_list_entity *entity; assert(length); HstackList_LockIMP(); entity = HstackList_MallocIMP(HSTACK_LIST_CTRL_SIZE + length); HstackList_UnLockIMP(); if (entity) { entity->mark = HSTACK_LIST_ENTRY_MARK; HSTACK_LIST_DEBUG_PRINTF("malloc @%08X", (u32)entity); //返回用户的buf使用区 return ((void *)(((u8 *)(entity)) + HSTACK_LIST_CTRL_SIZE)); } HSTACK_LIST_DEBUG_PRINTF("malloc @NULL"); return NULL;}
这个函数申请底层的Buf,同时加上了链表控制头,返回给用户的Buf地址注意要加上Buf控制头的长度。
用户填充完Buf后,可调用插入接口,将数据插入链表中,代码如下:
void HstackList_Insert(struct hstack_datablock *buf, u8 priority){ struct hstack_list_entity *entity; assert(buf); //寻找控制头,和malloc对应 entity = (struct hstack_list_entity *) ((u8 *)buf - HSTACK_LIST_CTRL_SIZE); assert(entity->mark == HSTACK_LIST_ENTRY_MARK); HSTACK_LIST_DEBUG_PRINTF("insert @%08X %s", (u32)entity, (priority ? "PRI high" : "PRI low")); HstackList_LockIMP(); if (SIMPLEQ_EMPTY(&list_cb.tx_head)) { SIMPLEQ_INSERT_HEAD(&list_cb.tx_head, entity, field); list_cb.priority = entity; } else { if (priority) { SIMPLEQ_INSERT_AFTER( &list_cb.tx_head, list_cb.priority, entity, field); list_cb.priority = entity; } else { SIMPLEQ_INSERT_TAIL(&list_cb.tx_head, entity, field); } } HstackList_UnLockIMP(); return;}
该函数为将items插入链表中结构,插入的链表是有优先级的,来高优先级的要插入之前高优先级的后面,否则就插入尾部。list_cb.priority为记录出入之前优先级最高的item。
用户可使用下面这个函数定时查询静态内存中是否有数据:
struct hstack_datablock *HstackList_PeekHead(void){ struct hstack_list_entity *entity; HstackList_LockIMP(); entity = SIMPLEQ_FIRST(&list_cb.tx_head); HstackList_UnLockIMP(); if (entity) { HSTACK_LIST_DEBUG_PRINTF("peek head @%08X", (u32)entity); return ((struct hstack_datablock *) ((u8 *)entity + HSTACK_LIST_CTRL_SIZE)); } else { HSTACK_LIST_DEBUG_PRINTF("peek head @NULL"); return NULL; }}
该函数定时查询静态内存链表中是否有数据,如果有数据的话,返回数据Buf指针给上层使用。
用户使用完静态内存后,一定要释放,释放的代码如下:
struct hstack_datablock *HstackList_RemoveHead(void){ struct hstack_list_entity *entity; HstackList_LockIMP(); entity = SIMPLEQ_FIRST(&list_cb.tx_head); if (entity) { HSTACK_LIST_DEBUG_PRINTF("remove @%08X", (u32)entity); SIMPLEQ_REMOVE_HEAD(&list_cb.tx_head, field); HstackList_FreeIMP(entity); } else { HSTACK_LIST_DEBUG_PRINTF("remove @NULL"); } HstackList_UnLockIMP(); return ((struct hstack_datablock *) ((u8 *)entity + HSTACK_LIST_CTRL_SIZE));}
调用该函数即可释放已经使用过的内存。
用途
应用场景为多任务使用同一资源,例如多个任务同时调用网络发送任务,此时可将多任务的发送数据存入静态内存,网络定时查询是否有数据要发送。
0 0
- 静态内存分配-链表管理(2)实现
- 静态内存分配-链表管理(1)单向量表讲解
- 基于链表的方法实现静态内存管理
- 内存分配管理(一)
- 内存管理 - 11.8 在栈上的静态分配
- Windows内存管理(1)--分配内核内存 和 使用链表
- Windows内存管理(1)--分配内核内存 和 使用链表
- Windows内存管理(1)--分配内核内存 和 使用链表
- 模拟内存分配(链表实现)
- Java内存管理(一、内存分配)
- Java内存管理(一、内存分配)
- .Java内存管理(一、内存分配)
- Java内存管理(一、内存分配)
- Java内存管理(内存分配)
- Java内存管理(一、内存分配)
- Java内存管理(一、内存分配)
- (十一)C语言静态内存分配
- 内存分配静态数组
- TensorFlow学习笔记(一):快速安装与使用TensorFlow
- 自己实现一个可以折叠展开的TextView
- 从源码出发了解RxJava的使用(中)
- 大丰收呀
- 静态链表
- 静态内存分配-链表管理(2)实现
- 关于GLSurfaceView 渲染的那些事
- swig(Lua)对STL/C++ library的支持
- POJ:1328 特别注意flag的使用地点
- 用alibba的jar包返回json格式化
- runTime运用的场景
- 高通平台android 环境配置编译及开发经验总结
- Binary Tree Inorder Traversal
- 异常处理--error