科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道应用软件SGI STL 内存池

SGI STL 内存池

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

将SGI STL的内存池抠了出来,win32平台.

作者:赵宇龙 来源:CSDN 2008年3月25日

关键字: 内存池 STL SGI Web开发 软件

  • 评论
  • 分享微博
  • 分享邮件

// mem_pool.h

#ifndef mem_pool_h
#define mem_pool_h

#pragma once

#define ALIGN     512
#define MAX_BLOCK_SIZE   20 * 1024
#define BLOCK_LIST_NUM   MAX_BLOCK_SIZE / ALIGN

class mem_pool
{
 CRITICAL_SECTION alloc_lock;
 union obj{
  union obj* free_list_link;
  char client_data[1];
 };
 obj* free_list [BLOCK_LIST_NUM];

 static inline size_t round_up(size_t bytes){
  return (bytes + ALIGN - 1) & ~(ALIGN - 1);
 }

 static inline size_t free_list_index(size_t bytes){
  return (bytes + ALIGN - 1) / ALIGN - 1;
 }

 char* start_free;
 char* end_free;
 size_t heap_size;

 char* chunk_alloc(size_t size, int& nobjs);
 void* refill(size_t n);
public:
 mem_pool(void);
 ~mem_pool(void);

 void* allocate(size_t n);
 void deallocate(void* p, size_t n);
 inline size_t mem_size(){return heap_size;}
};

#endif


 

// mem_pool.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "mem_pool.h"

mem_pool::mem_pool(void){
 InitializeCriticalSection(&alloc_lock);
 heap_size = 0;
 start_free = 0;
 end_free = 0;
 memset(free_list, 0, sizeof(free_list));
}

mem_pool::~mem_pool(void){
 DeleteCriticalSection(&alloc_lock);
}

char* mem_pool::chunk_alloc(size_t size, int& nobjs){
 char* result;
 size_t total_bytes = size * nobjs;
 size_t bytes_left = end_free - start_free;

 if(bytes_left >= total_bytes){
  result = start_free;
  start_free += total_bytes;
  return result;
 }

 if(bytes_left >= size){
  nobjs = bytes_left / size;
  total_bytes = size * nobjs;
  result = start_free;
  start_free += total_bytes;
  return result;
 }

 if(bytes_left > 0){
  obj **my_free_list = free_list + free_list_index(bytes_left);
  ((obj*) start_free)->free_list_link = *my_free_list;
  *my_free_list = (obj*) start_free;
 }

 size_t bytes_to_get = 2 * total_bytes + round_up(heap_size >> 4);
 start_free = (char *) malloc(bytes_to_get);

 if(start_free != 0){
  heap_size += bytes_to_get;
  end_free = start_free + bytes_to_get;
  return chunk_alloc(size, nobjs);
 }

 int i = free_list_index(size) + 1;
 obj **my_free_list, *p;
 for(; i < BLOCK_LIST_NUM;  ++i){
  my_free_list = free_list + i;
  p = *my_free_list;

  if(0 != p){
   *my_free_list = p->free_list_link;
   start_free = (char *) p;
   end_free = start_free + (i + 1) * ALIGN;
   return chunk_alloc(size, nobjs);
  }
 }

 end_free = 0;
 return 0;
}

void* mem_pool::refill(size_t n){
 int nobjs = 20;
 char* chunk = chunk_alloc(n, nobjs);
 obj** my_free_list;
 obj* result;
 obj *current_obj, *next_obj;
 int i;

 if(1 == nobjs) return chunk;
 my_free_list = free_list + free_list_index(n);

 result = (obj *) chunk;
 -- nobjs;
 *my_free_list = next_obj = (obj *) (chunk + n);

 for(i = 1; ; ++ i){
  current_obj = next_obj;
  next_obj = (obj *) ((char*) next_obj + n);

  if(nobjs == i){
   current_obj->free_list_link = 0;
   break;
  }
  current_obj->free_list_link = next_obj;
 }

 return result;
}

void* mem_pool::allocate(size_t n){
 obj** my_free_list;
 obj* result;

 if(n <= 0) return 0;
 if(n > MAX_BLOCK_SIZE)
  return malloc(n);

 EnterCriticalSection(&alloc_lock);
 try{
  my_free_list = free_list + free_list_index(n);
  result = *my_free_list;
  if(result == 0){
   result = (obj *) refill(round_up(n));
  }else{
   *my_free_list = result->free_list_link;
  }
 }catch(...){
  result = 0;
 }
 LeaveCriticalSection(&alloc_lock);

 return result;
}

void mem_pool::deallocate(void* p, size_t n){
 obj *q = (obj *)p;
 obj** my_free_list;

 if(n > MAX_BLOCK_SIZE){
  free(p);
  return;
 }

 my_free_list = free_list + free_list_index(n);

 EnterCriticalSection(&alloc_lock);
 q->free_list_link = *my_free_list;
 *my_free_list = q;
 LeaveCriticalSection(&alloc_lock);

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章