bufferpool.h
-
#ifndef BUFFERPOOL_HEADER
-
#define BUFFERPOOL_HEADER
-
-
#define BPBD_NUM 1000
-
#define BPBD_LENGTH 2048
-
-
unsigned long bpool_alloc(void);
-
int bpool_free(unsigned long addr);
-
int bpool_init(unsigned long addr);
-
void bpool_destroy(void);
-
-
#endif
bufferpool.c
-
/****************************************************************
-
bufferpool
-
栈式bufferpool管理
-
引入一个 bdflag_array,用来避免用户重复释放buffer
-
****************************************************************/
-
#include <stdio.h>
-
#include <string.h>
-
#include <stdint.h>
-
#include <stdlib.h>
-
#include <stddef.h>
-
#include <fcntl.h>
-
#include <unistd.h>
-
#include <pthread.h>
-
#include <errno.h>
-
#include <sys/mman.h>
-
#include <sys/stat.h>
-
#include <linux/limits.h>
-
-
#include "bufferpool.h"
-
-
#define BPOOL_LOCK pthread_spin_lock(&bpool_info->lock)
-
#define BPOOL_UNLOCK pthread_spin_unlock(&bpool_info->lock)
-
#define BPBD_INUSE_FLAG 0xdead
-
#define BPBD_AVAIL_FLAG 0xbeef
-
-
typedef struct bpoolinfo
-
{
-
//unsigned long base_phy;
-
unsigned long base;
-
unsigned int capacity;
-
unsigned int length;
-
int curr; // -1 full BPBD_NUM -1 0
-
unsigned int bd_array[BPBD_NUM]; // store bd offset
-
unsigned int bdflag_array[BPBD_NUM]; // bdflasg list sort by index/offset
-
pthread_spinlock_t lock;
-
unsigned int checksum;
-
} BPOOL_INFO_S;
-
-
static BPOOL_INFO_S *bpool_info = NULL;
-
-
/* buffer pool init */
-
int bpool_init(unsigned long addr)
-
{
-
unsigned int i = 0;
-
-
if (!addr)
-
{
-
printf(" %s-%d, addr invalid! \n", __FUNCTION__, __LINE__);
-
return -1;
-
}
-
-
/* align to BD_LENGTH */
-
if (addr % BPBD_LENGTH)
-
addr += BPBD_LENGTH - addr % BPBD_LENGTH;
-
-
/* init bp info */
-
bpool_info = (BPOOL_INFO_S*)malloc(sizeof(BPOOL_INFO_S));
-
if (!bpool_info)
-
{
-
printf(" %s-%d, alloc bpool_info fail! \n", __FUNCTION__, __LINE__);
-
return -1;
-
}
-
-
bpool_info->base = addr;
-
bpool_info->capacity = BPBD_NUM;
-
bpool_info->length = BPBD_LENGTH;
-
bpool_info->curr = bpool_info->capacity -1;
-
-
/* fill the bd array */
-
for (i = 0; i < bpool_info->capacity; i++)
-
{
-
bpool_info->bd_array[i] = i * BPBD_LENGTH;
-
bpool_info->bdflag_array[i] = BPBD_AVAIL_FLAG;
-
}
-
-
/* init bpool lock */
-
(void)pthread_spin_init(&bpool_info->lock, 0);
-
-
printf("\n buffer pool info: \n");
-
printf(" base 0x%lx \n", bpool_info->base);
-
printf(" capacity 0x%lx \n", bpool_info->capacity);
-
printf(" buffer length 0x%lx \n", bpool_info->length);
-
printf(" buffer curr 0x%lx \n", bpool_info->curr);
-
-
return 0;
-
}
-
-
/* alloc BD form bpool */
-
unsigned long bpool_alloc(void)
-
{
-
int curr;
-
unsigned long addr = 0;
-
-
if (bpool_info->curr == -1)
-
{
-
return 0;
-
}
-
-
BPOOL_LOCK;
-
bpool_info->bdflag_array[bpool_info->bd_array[bpool_info->curr] / BPBD_LENGTH] = BPBD_INUSE_FLAG;
-
addr = bpool_info->bd_array[bpool_info->curr] + bpool_info->base;
-
bpool_info->curr--;
-
BPOOL_UNLOCK;
-
-
return addr;
-
}
-
-
/* free bd */
-
int bpool_free(unsigned long addr)
-
{
-
if ((addr < bpool_info->base)
-
|| (addr > bpool_info->base + (bpool_info->capacity - 1) * bpool_info->length))
-
{
-
printf(" %s-%d, addr invalid!\n", __FUNCTION__, __LINE__);
-
return -1;
-
}
-
-
if (bpool_info->curr == (bpool_info->capacity - 1))
-
{
-
printf(" %s-%d, free exception, bpool is full! \n", __FUNCTION__, __LINE__);
-
return -1;
-
}
-
-
/* addr align to BtyPBD_LENGTH */
-
if (addr % BPBD_LENGTH)
-
addr -= addr % BPBD_LENGTH;
-
-
/* if free confilict */
-
if (BPBD_AVAIL_FLAG == bpool_info->bdflag_array[(addr - bpool_info->base) / BPBD_LENGTH])
-
{
-
printf(" %s-%d, free exception, confilict 0x%lx! \n", __FUNCTION__, __LINE__, addr);
-
return -1;
-
}
-
-
BPOOL_LOCK;
-
bpool_info->curr++;
-
bpool_info->bd_array[bpool_info->curr] = addr - bpool_info->base;
-
bpool_info->bdflag_array[bpool_info->bd_array[bpool_info->curr] / BPBD_LENGTH] = BPBD_AVAIL_FLAG;
-
BPOOL_UNLOCK;
-
-
return 0;
-
}
-
-
/* bpool destroy */
-
void bpool_destroy(void)
-
{
-
free((void*)bpool_info);
-
bpool_info = NULL;
-
-
return;
-
}
main.c
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <time.h>
#include "bufferpool.h"
/* bpool 测试程序 */
int main(int argc, char* argv[])
{
unsigned long base = 0;
int ret = 0;
unsigned long addr1;
clock_t start, finish;
double duration;
unsigned int cnt=10000000;
unsigned int i=0;
printf(" ###################### bpool debug mainapp! \n");
/* 提前申请bpool空间,暂时用 malloc 代替 */
base = (unsigned long)malloc((BPBD_NUM + 1)*BPBD_LENGTH);
if (!base)
{
printf(" %s malloc fail! \n", argv[0]);
return -1;
}
if(bpool_init(base))
{
printf(" %s bpool_init fail! \n", argv[0]);
free((void*)base);
return -1;
}
start = clock();
i=cnt;
while (i--)
{
addr1 = bpool_alloc();
*(unsigned int*)(addr1) = i;
bpool_free(addr1);
}
finish = clock();
duration = (double)(finish - start)/CLOCKS_PER_SEC;
printf( "\r\n bpool test 10000000 time use %f \r\n", duration);
free((void*)base);
bpool_destroy();
return 0;
}
对于大量频繁使用buffer的业务,buffer池除了有速度上的提升,更重要的是避免处理导致的内存碎片化。
阅读(1454) | 评论(0) | 转发(0) |