bacula之内存池实现
来源:互联网 发布:断食减肥知乎 编辑:程序博客网 时间:2024/05/16 08:48
关于内存池方面的文章很多,bacula中的实现相比与STL中的内存池与MemCached的内存池实现要简单的多。主要思想是,把申请的内存块大小分为固定大小的四块,另外用户也可自由申请指定大小的内存。
mem_pool.h/*memory pool design*/#ifndef __MEM_POOL_H_#define __MEM_POOL_H_ 1#include<stdio.h>#include<stdlib.h>#include<pthread.h>#include<assert.h>#include<time.h>#include<string.h>#define int32_t int#define PM_NOPOOL 0 /* nonpooled memory */#define PM_NAME 1 /* system name */#define PM_FNAME 2 /* file name buffer */#define PM_MESSAGE 3 /* daemon message */#define PM_EMSG 4 /* error message */#define PM_MAX PM_EMSG /* Number of types */#define MAX_NAME_LENGTH 128 /*the length of name */#define NLEN (MAX_NAME_LENGTH+2)/* Memory allocation control structures and storage. */struct mbufhead { int32_t ablen; /* Buffer length in bytes */ int32_t pool; /* pool type*/ struct mbufhead *next; /* pointer to next free buffer */};struct s_pool_ctl { char type[7]; int32_t size; /* default size */ int32_t max_allocated; /* the max space which has been allocated by*/ int32_t max_used; /* the max buffer which is used */ int32_t in_use; /* number in use */ struct mbufhead *free_buf; /* pointer to free buffers */};#define ALIGN_SIZE (sizeof(double))#define BALIGN(x) (((x)+ALIGN_SIZE-1)&~(ALIGN_SIZE-1)) // 与8字节对齐#define M_HEAD_SIZE BALIGN(sizeof(struct mbufhead))char *get_pool_memory( int pool); //得到指定类型的内存char *get_memory( int32_t size); /*nonpool type*/int32_t sizeof_pool_memory(char *obuf); // 检查内存的大小char *realloc_pool_memory( char *obuf, int32_t size);void free_pool_memory( char *obuf);void print_pool_memory_stats();void garbage_collect_memory_pool(); //定时回收垃圾内存void close_pool_memory(); // 关闭内存池#endif
.mem_pool.c
#include "mem_pool.h"static struct s_pool_ctl pool_ctl[] = { {"NoPool", 256, 256, 0, 0, NULL }, /* PM_NOPOOL no pooling */ {"NAME ", NLEN, NLEN,0, 0, NULL }, /* PM_NAME System name */ {"FNAME ",256, 256, 0, 0, NULL }, /* PM_FNAME filename buffers */ {"MSG ", 512, 512, 0, 0, NULL }, /* PM_MESSAGE message buffer */ {"EMSG ",1024, 1024, 0, 0, NULL } /* PM_EMSG error message buffer */};static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;char *get_pool_memory( int pool){ struct mbufhead *buf; if (pool > PM_MAX) { printf("MemPool index %d larger than max %d\n", pool, PM_MAX); } P(&mutex); /* if it has free buffer */ if (pool_ctl[pool].free_buf) { buf = pool_ctl[pool].free_buf; pool_ctl[pool].free_buf = buf->next; pool_ctl[pool].in_use++; if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) { pool_ctl[pool].max_used = pool_ctl[pool].in_use; } V(&mutex); printf("sm_get_pool_memory reuse %p to %s:%d\n", buf, __FILE__, __LINE__); //snew_owner(__FILE__, __LINE__, (char *)buf); return (char *)((char *)buf+M_HEAD_SIZE); } /* or,it will generate a new buffer */ if ((buf = (struct mbufhead *)malloc(pool_ctl[pool].size+M_HEAD_SIZE)) == NULL) { V(&mutex); printf("Out of memory requesting %d bytes\n", pool_ctl[pool].size); } buf->ablen = pool_ctl[pool].size; buf->pool = pool; pool_ctl[pool].in_use++; if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) { pool_ctl[pool].max_used = pool_ctl[pool].in_use; } V(&mutex); printf("sm_get_pool_memory give %p to %s:%d\n", buf, __FILE__, __LINE__); return (char *)((char *)buf+M_HEAD_SIZE);}/* Get nonpool memory of size requested */char *get_memory( int32_t size){ struct mbufhead *buf; int pool = 0; if ((buf = (struct mbufhead *)malloc(size+M_HEAD_SIZE)) == NULL) { printf("Out of memory requesting %d bytes\n", size); } buf->ablen = size; buf->pool = pool; buf->next = NULL; pool_ctl[pool].in_use++; if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) pool_ctl[pool].max_used = pool_ctl[pool].in_use; return (char *)(((char *)buf)+M_HEAD_SIZE);}/* Return the size of a memory buffer */int32_t sizeof_pool_memory(char *obuf){ char *cp = (char *)obuf; assert(obuf); /*check*/ cp -= M_HEAD_SIZE; return ((struct mbufhead *)cp)->ablen;}/* Realloc pool memory buffer ,size must be greater than before*/char *realloc_pool_memory( char *obuf, int32_t size){ assert(obuf); if (size <= sizeof_pool_memory(obuf)) { return obuf; } char *cp = (char *)obuf; void *buf; int pool; assert(obuf); P(&mutex); cp -= M_HEAD_SIZE; buf = realloc(cp, size+M_HEAD_SIZE); if (buf == NULL) { V(&mutex); printf("Out of memory requesting %d bytes\n", size); } ((struct mbufhead *)buf)->ablen = size; pool = ((struct mbufhead *)buf)->pool; if (size > pool_ctl[pool].max_allocated) { pool_ctl[pool].max_allocated = size; } V(&mutex); return (char *)(((char *)buf)+M_HEAD_SIZE);}/* Free a memory buffer */void free_pool_memory(char *obuf){ struct mbufhead *buf; int pool; assert(obuf); P(&mutex); buf = (struct mbufhead *)((char *)obuf - M_HEAD_SIZE); pool = buf->pool; pool_ctl[pool].in_use--; if(pool == 0) { free((char *)buf); /* free nonpooled memory */ } else { /* otherwise link it to the free pool chain */ struct mbufhead *next; /* Don't let him free the same buffer twice */ for (next=pool_ctl[pool].free_buf; next; next=next->next) { if (next == buf) { printf("free_pool_memory %p pool=%d from %s:%d\n", buf, pool,__FILE__,__LINE__); printf("bad free_pool_memory %p pool=%d from %s:%d\n", buf, pool,__FILE__, __LINE__); V(&mutex); /* unblock the pool */ assert(next != buf); /* attempt to free twice */ } } buf->next = pool_ctl[pool].free_buf; pool_ctl[pool].free_buf = buf; } printf("free_pool_memory %p pool=%d from %s:%d\n", buf, pool, __FILE__, __LINE__); V(&mutex);}/* Release all pooled memory */void close_pool_memory(){ struct mbufhead *buf, *next; int count = 0; unsigned long long int bytes = 0; //bcheck(__FILE__, __LINE__, false); P(&mutex); int i=0; for (i=1; i<=PM_MAX; i++) { buf = pool_ctl[i].free_buf; while (buf) { next = buf->next; count++; //bytes += sizeof_pool_memory((char *)buf); bytes+=buf->ablen; free((char *)buf); buf = next; } pool_ctl[i].free_buf = NULL; } printf("Freed mem_pool count=%d size=%llu\n", count, bytes); V(&mutex);}/* * Clean up memory pool periodically * */static time_t last_garbage_collection = 0;const int garbage_interval = 24 * 60 * 60; /* garbage collect every 24 hours *//* create a thread to excute it */void garbage_collect_memory_pool(){ time_t now; printf( "garbage collect memory pool\n"); P(&mutex); if (last_garbage_collection == 0) { last_garbage_collection = time(NULL); V(&mutex); return; } now = time(NULL); if (now >= last_garbage_collection + garbage_interval) { last_garbage_collection = now; V(&mutex); close_pool_memory(); } else { V(&mutex); }}/* Print staticstics on memory pool usage */void print_pool_memory_stats(){ printf("Pool Maxsize Maxused Inuse\n"); int i=0; for (; i<=PM_MAX; i++) printf("%5s %7d %7d %5d\n", pool_ctl[i].type, pool_ctl[i].max_allocated, pool_ctl[i].max_used, pool_ctl[i].in_use); }
测试程序
int main(){ char *s; s=get_pool_memory(3); printf("sizeof_pool_memory:%d\n",sizeof_pool_memory(s)); print_pool_memory_stats(); char *s1=get_pool_memory(1); char *s2=get_memory(100); print_pool_memory_stats(); free_pool_memory(s1); free_pool_memory(s2); s=realloc_pool_memory(s,536); free_pool_memory(s); print_pool_memory_stats(); close_pool_memory(); print_pool_memory_stats(); char *s3=get_pool_memory(3); print_pool_memory_stats(); sscanf("zhoupj","%s",s3); printf("%s\n",s3); pm_strcat(&s3, "hello"); printf("%s\n",s3); pm_strcpy(&s3, "XYZSDF") ; printf("%s\n",s3);}
相关程序
.mutex.c#include "mem_pool.h"/* * These are mutex routines that do error checking * for deadlock and such. Normally not turned on. *//* enclose P V operation */void P(pthread_mutex_t *m){ int errstat; if ((errstat = pthread_mutex_trylock(m))) { printf("Possible mutex deadlock.\n"); /* We didn't get the lock, so do it definitely now */ if ((errstat=pthread_mutex_lock(m))) { printf("Mutex lock failure.\n"); } else { printf("Possible mutex deadlock resolved.\n"); } }}void V(pthread_mutex_t *m){ int errstat; /* Note, this trylock *should* fail if the mutex is locked */ if ((errstat=pthread_mutex_trylock(m)) == 0) { printf("Mutex unlock not locked.\n"); } if ((errstat=pthread_mutex_unlock(m))) { printf("Mutex unlock failure. \n"); }}
- bacula之内存池实现
- 服务端之内存池
- nginx源码分析之内存池实现原理
- {linux程序}之内存池
- 游戏服务端之内存池
- Boost之内存池学习
- 高性能之内存池
- nginx 数据结构之内存池
- 游戏服务端之内存池
- 操作系统实现之内存分页机制.虚拟空间
- 操作系统实现之内存分页机制.虚拟空间
- 内存管理之内存池的设计
- delphi,IOCP之内存分配池[1]
- 内存管理之内存池的设计
- IOCP之内存分配池[1]
- 经典数据结构之内存池技术
- 我的服务端之内存池
- 我的服务端之内存池
- 七夕,染红了我的相思
- Informix存储过程 详解
- ubuntu SSH Secure Shell Client 中文乱码
- Xcode4.5.1破解iOS免证书开发真机调试与ipa发布
- Activity的运行模式简单介绍
- bacula之内存池实现
- 为什么要选择PHP开发网站,PHP有什么优势?
- 关于RTP打包h264的时间戳要注意的问题
- 在SQLite中使用事务
- flex DataGrid与CheckBox的使用,表头也加上CheckBox
- C#中如何快速地将一个表(datatable)的内容复制给另一个表
- Spket在Eclipse/MyEclipse下的安装和配置
- android相关知识简介
- HDOJ - 2371 矩阵乘法