现在的位置: 首页 > 综合 > 正文

HM 内存池设计(2) HM6.0内存池设计

2013年05月06日 ⁄ 综合 ⁄ 共 11299字 ⁄ 字号 评论关闭

用于HM6.0代码中的内存池。

相对于(1)的改进:

a.chunk的大小从64bytes开始,到64KB.max_free_chunk[MAX_INDEX] 表示各个size的数目。

const uint32_t chunk_size[MAX_INDEX]={
/*    64 B,128B,256B,320B,512B,    */
    1    ,2     ,4      ,5   ,   8,
/*    1  K,2  K,4  K,8  K,16 K,  */
    1<<4,1<<5,1<<6,1<<7,1<<8,
/*    32 K,64 K,                   */
    1<<9,1<<10};//最小内存块BOUNDARY_SIZE(64B)的多少倍

 

b.预先分配一块大的内存LARGE_BLOCK,大于64KB的从LARGE_BLOCK分配,LARGE_BLOCK不足时再向系统分配。分配时找到一个比要分配的大小 大的MemLargeBlock,从末尾分配空间出去。释放时,空闲的LARGE_BLOCK块以双向链表表示,按照地址从低到高的顺序排列插入链表,并检查能否与前后MemLargeBlock合并。

c.HM6.0大于64KB的全局内存(GlobleLargeMem),未采用b.的策略,而是事先计算好了大小分配好。

 

源代码:

 1 /*
 2  ============================================================================
 3  Name        : mempool.h
 4  Author      : mlj
 5  Version     : 0.1
 6  ============================================================================
 7  */
 8 
 9 #ifndef MEMPOOL_
10 #define MEMPOOL_
11 #include <stdint.h>
12 
13 #define MEM_ANALYSIS //统计memory的信息
14 #define  MAX_INDEX 12 
15 
16 #define     FIX_BLOCK        (0x01<<7)  //MemBlock
17 #define     LARGE_BLOCK        (0x01<<6)  //MemLargeBlock
18 #define     SYSTEM_BLOCK    (0x01<<5)  //不是从内存池得到的,直接释放给系统
19 #define     FREED_BLOCK     (0x01<<4) //BlockInfo的低第4bit,表示是否已经释放过了。防止连续重复释放造成混乱
20 
21 typedef uint8_t BlockInfo;//BlockInfo 段数据类型,bit7-5表示Block类型,
22 typedef struct MemBlock
23 {
24     uint32_t    index;//size
25     uint32_t    nfree;//可用的最小内存单元数
26     uint32_t    nfirst;//下一个最小可用内存单元编号
27     struct MemBlock*    pNextBlock;//下一个index值相同的MemBlock
28 }MemBlock;
29 
30 typedef struct MemLargeBlock
31 {
32     char         *beginp;          /**< pointer to begin of memory */
33     char         *endp;                 /**< pointer to end of  memory [beginp,endp)*/ 
34 
35     struct MemLargeBlock *prev;
36     struct MemLargeBlock *next;
37 #ifdef MEM_ANALYSIS
38 #endif
39 }MemLargeBlock;
40 
41 typedef struct MemPool
42 {
43     MemLargeBlock    *head;//双向链表
44     MemBlock *freeblock[MAX_INDEX];
45     char *pMemory;
46     char *pLargeMemory;
47 }MemPool;
48 
49 typedef struct GlobleLargeMem
50 {
51     char *pLarge;
52     char *pLarge_aligned;
53     uint32_t pLarge_size;
54     uint32_t pLarge_aligned_size;
55     uint32_t pLarge_usedsize;
56     uint32_t pLarge_aligned_usedsize;
57 }GlobleLargeMem;
58 extern GlobleLargeMem  myGloble;
59 extern MemPool mypool;
60 void* MemPool_malloc(uint32_t in_size);
61 void* MemPool_calloc(uint32_t count,uint32_t size);
62 void MemPool_free(void* _Memory);
63 void MemPool_destroy(MemPool *pool);
64 void MemPool_create(MemPool *pool,uint32_t iPicWith,uint32_t iPicHeght);
65 
66 void GlobleLargeMem_Create(GlobleLargeMem* globle_mem,uint32_t iPicWith,uint32_t iPicHeght,uint32_t GOPsize,uint32_t MaxDecPicBuffering);
67 void GlobleLargeMem_Destory(GlobleLargeMem* globle_mem);
68 char* GlobleLargeMem_malloc(uint32_t size);
69 char* GlobleLargeMem_Xmalloc(uint32_t size);
70 void GlobleLargeMem_free(void *p);
71 void GlobleLargeMem_Xfree(void *p);
72 
73 #endif
mempool.c

  1 /*
2 ============================================================================
3 Name : mempool.c
4 Author : mlj
5 Version : 0.1
6 ============================================================================
7 */
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <memory.h>
11 #include "mempool.h"
12
13 uint32_t max_free_chunk[MAX_INDEX]={
14 571+10, 506+10, 6209+10, 324+10, 428+10, 2452+10,
15 749+10, 666+5, 317+5, 315+5, 1, 2};//各块数目
16 const uint32_t chunk_size[MAX_INDEX]={
17 /* 64 B,128B,256B,320B,512B, */
18 1 ,2 ,4 ,5 , 8,
19 /* 1 K,2 K,4 K,8 K,16 K, */
20 1<<4,1<<5,1<<6,1<<7,1<<8,
21 /* 32 K,64 K, */
22 1<<9,1<<10};//最小内存块BOUNDARY_SIZE(64B)的多少倍
23
24 MemPool mypool;
25 #ifdef MEM_ANALYSIS
26 uint32_t max_used[MAX_INDEX]={0};//达到的用到的chunk数目最大值
27 uint32_t system_malloc=0;//额外从系统malloc的大小
28 int32_t Malloc_Free_check[MAX_INDEX] = {0};
29 #endif
30 #define BOUNDARY_INDEX 6
31 #define BOUNDARY_SIZE (1 << BOUNDARY_INDEX) // 最小内存块大小64B
32
33 #define CHUNK_HEAD_SIZE ( sizeof(MemBlock*)+ sizeof(uint32_t)+sizeof(BlockInfo) )
34 #define CHUNK_DATA_SIZE(index) ( BOUNDARY_SIZE*(chunk_size[index])) // 4096*(1<<19) 默认为int 类型,会越界 ( 1<<(chunk_size[index]+BOUNDARY_INDEX))
35 #define MEMBLOCK_SIZE(index) ( sizeof(MemBlock) + max_free_chunk[(index)]*( CHUNK_HEAD_SIZE + CHUNK_DATA_SIZE(index) ) )
36
37 #define APR_ALIGN(size, boundary) (((size)+ ((boundary) - 1)) &~((boundary) - 1))
38 #define LARGE_BLOCK_SIZE (((uint32_t)1<<20)*19) //10M
39
40 void MemBlock_init(MemBlock *block,uint32_t max_free_chunk)
41 {
42 uint32_t i = 0;
43 char *p = NULL;
44 block->nfree = max_free_chunk;
45 block->nfirst = 0;
46 block->pNextBlock = NULL;
47
48 p = (char*)block;
49 ((char*)p) += sizeof(MemBlock); //第0个chunk头地址
50 for(i=0;i<block->nfree;i++)
51 {
52 ( *((MemBlock**)p) ) = (MemBlock*)block; //chunk 头四个字节存放所在的MemBlock的地址
53 ((char*)p) += sizeof(MemBlock*);
54 *((uint32_t*)p) = i+1; //存放下一个可用的chunk的index
55 ((char*)p) += sizeof(uint32_t);
56 *((BlockInfo*)p) = FIX_BLOCK; //设置block类型及index
57 ((char*)p) += sizeof(BlockInfo)+CHUNK_DATA_SIZE(block->index);
58 }
59 }
60
61 _inline void MemLargeBlock_init(MemLargeBlock *block,uint32_t size)
62 {
63 block->beginp = (char *)block;
64 block->endp = ((MemLargeBlock*)block)->beginp + size;
65 block->prev = (MemLargeBlock*)block;
66 block->next = (MemLargeBlock*)block;
67 }
68
69 void* MemLargeBlock_malloc(uint32_t size)
70 {
71 MemLargeBlock *pblock = mypool.head;
72 do
73 {
74 uint32_t blockfreesize = pblock->endp - pblock->beginp - sizeof(MemLargeBlock);
75 if ( (sizeof(MemLargeBlock) + sizeof(BlockInfo) + size) <= blockfreesize)
76 {
77 char* pmalloc = pblock->endp - sizeof(MemLargeBlock) - sizeof(BlockInfo)- size;//分配出去的空间之前有两个字段
78 pblock->endp = pmalloc;
79 MemLargeBlock_init((MemLargeBlock*)pmalloc,(sizeof(MemLargeBlock) + sizeof(BlockInfo) + size));
80 *( (BlockInfo*)((char*)pmalloc + sizeof(MemLargeBlock) ) ) = LARGE_BLOCK;
81 return ((char*)pmalloc + sizeof(MemLargeBlock) + sizeof(BlockInfo) );
82 }
83 pblock = pblock->next;
84 } while (pblock != mypool.head);
85
86 if (pblock == mypool.head) //链表中没有这么大的内存
87 {
88 char *pmalloc = (char*) malloc(sizeof(BlockInfo) + size);
89 #ifdef MEM_ANALYSIS
90 system_malloc+=sizeof(BlockInfo) + size;//额外从系统malloc的大小
91 #endif
92 if (pmalloc)
93 {
94 *( (BlockInfo*)((char*)pmalloc ) ) = SYSTEM_BLOCK;
95 return ((char*)pmalloc + sizeof(BlockInfo) );
96 }
97 else
98 {
99 printf("memory malloc failed!size:%d \n",size);
100 exit(0);
101 }
102
103 }
104 return NULL;
105 }
106
107 void MemLargeBlock_free(void* _Memory)
108 {
109 MemLargeBlock *pblock = (MemLargeBlock*) ( (char*)_Memory - sizeof(MemLargeBlock) - sizeof(BlockInfo) );
110 MemLargeBlock *pblock2 = mypool.head;
111 pblock->prev = pblock->next =NULL;
112 //空闲块插入链表,并且合并,链表按照地址从低到高的顺序排列
113 if (pblock->beginp>=pblock2->prev->endp)//在最后一个节点之后
114 {
115 if (pblock->beginp == pblock2->prev->endp)
116 {
117 pblock2->prev->endp = pblock->endp;
118 }
119 else//插到最后
120 {
121 pblock->next = pblock2;
122 pblock->prev = pblock2->prev;
123 pblock2->prev->next = pblock;
124 pblock2->prev = pblock;
125 }
126 return;
127 }
128
129 do
130 {
131 if ( pblock->endp<=pblock2->next->beginp )//在pblock2 与 pblock2->next之间
132 {
133 if ( pblock->endp == pblock2->next->beginp && pblock->beginp == pblock2->endp ) //与两者都相邻
134 {
135 pblock2->endp = pblock2->next->endp; //三块合并
136 pblock2->next->next->prev = pblock2;
137 pblock2->next = pblock2->next->next;
138 }
139 else if(pblock->beginp == pblock2->endp ) //与pblock2相邻
140 {
141 pblock2->endp = pblock->endp; //直接加到pblock2之后
142 }
143 else if ( pblock->endp == pblock2->next->beginp ) //与pblock2->next相邻
144 {
145 pblock->endp = pblock2->next->endp;//与pblock2->next合并,
146 pblock2->next->next->prev = pblock;
147 pblock->prev = pblock2;
148 pblock->next = pblock2->next->next;
149 pblock2->next = pblock;
150 }
151 else // 在两者之间,但无相邻
152 {
153 pblock2->next->prev = pblock;
154 pblock->prev = pblock2;
155 pblock->next = pblock2->next;
156 pblock2->next = pblock;
157 }
158 return;
159 }
160 pblock2 = pblock2->next;
161
162 } while (pblock2->next != mypool.head);
163 }
164 void MemPool_create(MemPool *pool,uint32_t iPicWith,uint32_t iPicHeght)
165 {
166 size_t pool_size = 0;//
167 size_t i;
168 char* p = NULL;
169 {//根据图像大小,初始化max_free_chunk[MAX_INDEX]
170 if (iPicWith==416&&iPicHeght==240)
171 {
172 uint32_t temp_free_chunk[MAX_INDEX]={
173 571+10, 506+10, 6209+10, 324+10, 428+10, 2452+10,
174 749+10, 666+5, 317+5, 315+5, 1, 2};//各块数目(编码20帧测得结果),再加10或5,随编码帧数所需会有1-2的抖动
175 memcpy(max_free_chunk,temp_free_chunk,MAX_INDEX*sizeof(uint32_t));
176 }
177 else if (iPicWith==1280&&iPicHeght==720)
178 {
179 uint32_t temp_free_chunk[MAX_INDEX]={
180 955+10, 2528+10,50717+10, 1283+10, 2548+10,19514+10,
181 4979+10, 4909+5, 2443+5, 2447+5, 4, 2};//各块数目
182 memcpy(max_free_chunk,temp_free_chunk,MAX_INDEX*sizeof(uint32_t));
183 }
184 else
185 {
186 fprintf(stdout,"Mempool(max_free_chunk) of the pic size does not set!May malloc memory from system\n");
187 fprintf(stdout,"set macro MEM_ANALYSIS and add the size in MemPool_create() \n");
188 }
189 }
190 for (i=0;i<MAX_INDEX;i++)
191 {
192 pool_size += MEMBLOCK_SIZE(i);
193 }
194 pool_size += LARGE_BLOCK_SIZE;
195 p = (char *)malloc(pool_size);
196 if(p == NULL)
197 {
198 printf("memory malloc failed!/n");
199 exit(0);
200 }
201
202 //memset(p,0,pool_size);
203 pool->pMemory = p;
204
205 for (i=0;i<MAX_INDEX;i++)
206 {
207 pool->freeblock[i] = (MemBlock*) (p);
208 pool->freeblock[i]->index = i;
209 MemBlock_init(pool->freeblock[i],max_free_chunk[i]);
210 ((char*)p) += MEMBLOCK_SIZE(i);//注意转为char* 在加偏移
211 }
212
213 pool->pLargeMemory = (char*)p;
214 pool->head = (MemLargeBlock *)(pool->pLargeMemory);
215 MemLargeBlock_init(pool->head,LARGE_BLOCK_SIZE);
216
217 }
218
219 void MemPool_destroy(MemPool *pool)
220 {
221 size_t i;
222 #ifdef MEM_ANALYSIS
223 size_t pool_size = 0;
224 for (i=0;i<MAX_INDEX;i++)
225 {
226 pool_size += MEMBLOCK_SIZE(i);
227 }
228 printf("MemPool analysis:\n");
229 printf("FIX_BLOCK malloc memory size :%dKB %dM\n",pool_size>>10,pool_size>>20);
230 printf("LARGE_BLOCK malloc memory size :%dKB %dM\n",LARGE_BLOCK_SIZE>>10,LARGE_BLOCK_SIZE>>20);
231 printf("system malloc memory size:%dKB %dM\n",system_malloc>>10,system_malloc>>20);
232 printf("index :");
233 for (i=0;i<MAX_INDEX/2;i++)
234 {
235 printf("%5d ",i);
236 }
237 printf("\nmax_used:");
238 for (i=0;i<MAX_INDEX/2;i++)
239 {
240 printf("%5d,",max_used[i]);
241 }
242 printf("\nblock_len:");
243 for (i=0;i<MAX_INDEX/2;i++)
244 {
245 uint32_t block_len = 0;
246 MemBlock* pblock = NULL;
247 pblock = mypool.freeblock[i];
248 do
249 {
250 block_len++;
251 }while (pblock=pblock->pNextBlock);
252 printf("%5d ",block_len);
253 }
254
255 printf("\nindex :");
256 for (i=MAX_INDEX/2;i<MAX_INDEX;i++)
257 {
258 printf("%5d ",i);
259 }
260 printf("\nmax_used:");
261 for (i=MAX_INDEX/2;i<MAX_INDEX;i++)
262 {
263 printf("%5d,",max_used[i]);
264 }
265 printf("\nblock_len:");
266 for (i=MAX_INDEX/2;i<MAX_INDEX;i++)
267 {
268 uint32_t block_len = 0;
269 MemBlock* pblock = NULL;
270 pblock = mypool.freeblock[i];
271 do
272 {
273 block_len++;
274 }while (pblock=pblock->pNextBlock);
275 printf("%5d ",block_len);
276 }
277 for (i=0;i<MAX_INDEX;i++)
278 printf("\nMalloc_Free_check[%d]:%d ",i,Malloc_Free_check[i]);
279 #endif
280
281 for (i=0;i<MAX_INDEX;i++)
282 {
283 MemBlock* pblock = NULL;
284 pblock = mypool.freeblock[i];
285 while (pblock->pNextBlock)
286 {
287 MemBlock* tmp = pblock->pNextBlock;
288 BlockInfo blocktype = *( (BlockInfo*)((char*)tmp - sizeof(BlockInfo)) );
289 pblock->pNextBlock = tmp->pNextBlock;
290 if (blocktype&SYSTEM_BLOCK)//来自系统分配
291 {
292 free((char*)tmp - sizeof(BlockInfo));
293 }
294 }
295 }
296 free(pool->pMemory);
297 pool->pMemory = NULL;
298 }
299
300 void* MemPool_malloc(size_t in_size)
301 {
302 size_t size;
303 size_t index;
304
305 if (in_size > CHUNK_DATA_SIZE(MAX_INDEX-1)) {
306 printf("malloc large size:%d KB\n",in_size>>10);
307 return MemLargeBlock_malloc(in_size); //大于最大固定大小内存块(64K)的处理
308 }
309 /* Find the index for this size
310 */
311 index = MAX_INDEX;
312 if (in_size <= BOUNDARY_SIZE)
313 {
314 size = BOUNDARY_SIZE;
315 index = 0;
316 }
317 else
318 {
319 size = APR_ALIGN(in_size,BOUNDARY_SIZE);
320 index = 1; //从1开始找index ,while(index<MAX_INDEX)
321 size = size>>BOUNDARY_INDEX;//size = size/BOUNDARY_SIZE,BOUNDARY_SIZE的倍数
322 while(index<MAX_INDEX)
323 {
324 if ( size>(chunk_size[index-1]) && size<=(chunk_size[index]) ) //
325 {
326 break;
327 }
328 index++;
329 }
330 }
331
332 if (index<MAX_INDEX)
333 {
334 MemBlock* pblock = NULL;
335 pblock = mypool.freeblock[index];
336 //寻找block链表上第一个存在空闲chunk的block
337 do
338 {
339 if (pblock->nfree>0) //找到,退出
340 {
341 break;
342 }
343 else if (pblock->pNextBlock == NULL) //已满,下一memblock又不存在
344 {
345 char *p = NULL;
346 if (max_free_chunk[index] == 0)
347 {
348 max_free_chunk[index] = 1;
349 }
350
351 p = (char*) MemLargeBlock_malloc(MEMBLOCK_SIZE(index));//从LARGE_BLOCK 分配,暂时不释放,destroy pool是释放
352 if (p == NULL)
353 {
354 printf("memory malloc(from large block) failed!/n");
355 exit(0);
356 }

抱歉!评论已关闭.