Chinaunix首页 | 论坛 | 博客
  • 博客访问: 714216
  • 博文数量: 79
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 1338
  • 用 户 组: 普通用户
  • 注册时间: 2012-06-12 08:51
个人简介

XMU->九天揽月->五湖抓鳖->DSP->driver->kernel/OpenWRT->ISP/RTOS

文章分类

全部博文(79)

文章存档

2020年(2)

2018年(3)

2016年(7)

2015年(42)

2014年(25)

分类: LINUX

2015-03-23 19:56:27

bufferpool.h 
  1. #ifndef BUFFERPOOL_HEADER
  2. #define BUFFERPOOL_HEADER

  3. #define BPBD_NUM 1000
  4. #define BPBD_LENGTH 2048

  5. unsigned long bpool_alloc(void);
  6. int bpool_free(unsigned long addr);
  7. int bpool_init(unsigned long addr);
  8. void bpool_destroy(void);

  9. #endif
bufferpool.c
  1. /****************************************************************
  2.     bufferpool
  3.     栈式bufferpool管理
  4.     引入一个 bdflag_array,用来避免用户重复释放buffer
  5. ****************************************************************/
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <stdint.h>
  9. #include <stdlib.h>
  10. #include <stddef.h>
  11. #include <fcntl.h>
  12. #include <unistd.h>
  13. #include <pthread.h>
  14. #include <errno.h>
  15. #include <sys/mman.h>
  16. #include <sys/stat.h>
  17. #include <linux/limits.h>

  18. #include "bufferpool.h"

  19. #define BPOOL_LOCK       pthread_spin_lock(&bpool_info->lock)
  20. #define BPOOL_UNLOCK     pthread_spin_unlock(&bpool_info->lock)
  21. #define BPBD_INUSE_FLAG  0xdead
  22. #define BPBD_AVAIL_FLAG  0xbeef

  23. typedef struct bpoolinfo
  24. {
  25.     //unsigned long base_phy;
  26.     unsigned long base;
  27.     unsigned int capacity;
  28.     unsigned int length;
  29.     int curr; // -1 full BPBD_NUM -1 0
  30.     unsigned int bd_array[BPBD_NUM]; // store bd offset
  31.     unsigned int bdflag_array[BPBD_NUM]; // bdflasg list sort by index/offset
  32.     pthread_spinlock_t lock;
  33.     unsigned int checksum;
  34. } BPOOL_INFO_S;

  35. static BPOOL_INFO_S *bpool_info = NULL;

  36. /* buffer pool init */
  37. int bpool_init(unsigned long addr)
  38. {
  39.     unsigned int i = 0;

  40.     if (!addr)
  41.     {
  42.         printf(" %s-%d, addr invalid! \n", __FUNCTION__, __LINE__);
  43.         return -1;
  44.     }

  45.     /* align to BD_LENGTH */
  46.     if (addr % BPBD_LENGTH)
  47.         addr += BPBD_LENGTH - addr % BPBD_LENGTH;

  48.     /* init bp info */
  49.     bpool_info = (BPOOL_INFO_S*)malloc(sizeof(BPOOL_INFO_S));
  50.     if (!bpool_info)
  51.     {
  52.         printf(" %s-%d, alloc bpool_info fail! \n", __FUNCTION__, __LINE__);
  53.         return -1;
  54.     }

  55.     bpool_info->base = addr;
  56.     bpool_info->capacity = BPBD_NUM;
  57.     bpool_info->length = BPBD_LENGTH;
  58.     bpool_info->curr = bpool_info->capacity -1;
  59.     
  60.     /* fill the bd array */
  61.     for (i = 0; i < bpool_info->capacity; i++)
  62.     {
  63.         bpool_info->bd_array[i] = i * BPBD_LENGTH;
  64.         bpool_info->bdflag_array[i] = BPBD_AVAIL_FLAG;
  65.     }
  66.     
  67.     /* init bpool lock */
  68.     (void)pthread_spin_init(&bpool_info->lock, 0);
  69.     
  70.     printf("\n buffer pool info: \n");
  71.     printf(" base 0x%lx \n", bpool_info->base);
  72.     printf(" capacity 0x%lx \n", bpool_info->capacity);
  73.     printf(" buffer length 0x%lx \n", bpool_info->length);
  74.     printf(" buffer curr 0x%lx \n", bpool_info->curr);

  75.     return 0;
  76. }

  77. /* alloc BD form bpool */
  78. unsigned long bpool_alloc(void)
  79. {
  80.     int curr;
  81.     unsigned long addr = 0;

  82.     if (bpool_info->curr == -1)
  83.     {
  84.         return 0;
  85.     }
  86.     
  87.     BPOOL_LOCK;
  88.     bpool_info->bdflag_array[bpool_info->bd_array[bpool_info->curr] / BPBD_LENGTH] = BPBD_INUSE_FLAG;
  89.     addr = bpool_info->bd_array[bpool_info->curr] + bpool_info->base;
  90.     bpool_info->curr--;
  91.     BPOOL_UNLOCK;
  92.     
  93.     return addr;
  94. }

  95. /* free bd */
  96. int bpool_free(unsigned long addr)
  97. {
  98.     if ((addr < bpool_info->base)
  99.         || (addr > bpool_info->base + (bpool_info->capacity - 1) * bpool_info->length))
  100.     {
  101.         printf(" %s-%d, addr invalid!\n", __FUNCTION__, __LINE__);
  102.         return -1;
  103.     }
  104.     
  105.     if (bpool_info->curr == (bpool_info->capacity - 1))
  106.     {
  107.         printf(" %s-%d, free exception, bpool is full! \n", __FUNCTION__, __LINE__);
  108.         return -1;
  109.     }

  110.     /* addr align to BtyPBD_LENGTH */
  111.     if (addr % BPBD_LENGTH)
  112.         addr -= addr % BPBD_LENGTH;

  113.     /* if free confilict */
  114.     if (BPBD_AVAIL_FLAG == bpool_info->bdflag_array[(addr - bpool_info->base) / BPBD_LENGTH])
  115.     {
  116.         printf(" %s-%d, free exception, confilict 0x%lx! \n", __FUNCTION__, __LINE__, addr);
  117.         return -1;
  118.     }
  119.         
  120.     BPOOL_LOCK;
  121.     bpool_info->curr++;
  122.     bpool_info->bd_array[bpool_info->curr] = addr - bpool_info->base;
  123.     bpool_info->bdflag_array[bpool_info->bd_array[bpool_info->curr] / BPBD_LENGTH] = BPBD_AVAIL_FLAG;
  124.     BPOOL_UNLOCK;

  125.     return 0;
  126. }

  127. /* bpool destroy */
  128. void bpool_destroy(void)
  129. {
  130.     free((void*)bpool_info);
  131.     bpool_info = NULL;

  132.     return;
  133. }
main.c
  1. #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池除了有速度上的提升,更重要的是避免处理导致的内存碎片化。

阅读(1464) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~