STL源码剖析:空间配置器

来源:互联网 发布:linux shell 设置变量 编辑:程序博客网 时间:2024/04/30 12:23

看完自己重写了一下,不知道的又看了一遍,里面没有考虑多线程的问题,主要是想实现以下内存池。

Mempool.h


#ifndef MEMPOOL_H_#define MEMPOOL_H_#include <cstddef>#include <new>#include <cstdlib>namespace flysnow {enum {STEP_ = 8};enum {MAX_BYTES_ = 128};enum {FREELIST_NUM_ = MAX_BYTES_/STEP_};class Mempool{private:    union pool_bucket {        union pool_bucket* next_node;        char bucket_addr[1];    };    static size_t up_to_nearest(size_t n) {        return STEP_*((n>>3) + (n%8 ? 1:0));    }    static size_t freelist_index(size_t n) {        return ((n>>3) + (n%8 ? 0:-1));    }    static void* refill(size_t n);    static char* alloc_memory(size_t size,int &pool_node_num);    static pool_bucket* free_list_[FREELIST_NUM_];    static char* start_pool;    static char* end_pool;    static size_t heap_size;public:    static void* allocate(size_t n);    static void deallocate(void *p,size_t n);    static size_t get_heap_size() {return heap_size;}};}#endif


Mempool.cpp

#include "mempool.h"namespace flysnow{char* Mempool::start_pool = 0;char* Mempool::end_pool = 0;size_t Mempool::heap_size = 0;Mempool::pool_bucket* Mempool::free_list_[FREELIST_NUM_] ={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};void* Mempool::allocate(size_t n) {    if(n > MAX_BYTES_){        return malloc(n);    }    pool_bucket *p;    pool_bucket **free_list_index = free_list_ + freelist_index(n);    p = *free_list_index;    if(0 == p) {        void *q = refill(up_to_nearest(n));        return q;    }    *free_list_index = p->next_node;    return p;}void Mempool::deallocate(void *p,size_t n) {    pool_bucket *q = (pool_bucket*)p;    if(n > MAX_BYTES_) {        free(p);        return ;    }    pool_bucket **free_list_index = free_list_ + freelist_index(n);    q->next_node = *free_list_index;    *free_list_index = q;}void* Mempool::refill(size_t n) {    int pool_node_num = 20;    int i;    pool_bucket **free_list_index = free_list_ + freelist_index(n);    char *pool = alloc_memory(n,pool_node_num);    if(1 == pool_node_num) {        return pool;    }    pool_bucket *result = (pool_bucket*)pool;    pool_bucket *current,*next;    pool += n;    *free_list_index = next = (pool_bucket*)pool;    next = (pool_bucket*)pool;    for(i=1; ;++i){        current = next;        next = (pool_bucket*)((char*)next + n);        if(pool_node_num - 1 == i){            current->next_node = NULL;            break;        } else {            current->next_node = next;        }    }    return result;}char* Mempool::alloc_memory(size_t size,int &pool_node_num) {    size_t total_size = size*pool_node_num;    size_t remain_size = end_pool - start_pool;    if(total_size <= remain_size) {        char* result = start_pool;        start_pool += total_size;        return result;    } else if(remain_size >= size) {        pool_node_num = remain_size/size;        size_t return_size = pool_node_num*size;        char *result = start_pool;        start_pool += return_size;        return result;    } else {        size_t get_size = 2*total_size + up_to_nearest(heap_size>>4);        if(remain_size > 0) {            //如果剩余7byte,此处会放在8byte的自由链表中,然而,最后allocate 8byte的            //时候,岂不会出错?            //原来之前get_size分配的内存总是8的倍数,因此不会出现以上情况。。。。            pool_bucket **free_list_index = free_list_ + freelist_index(remain_size);            ((pool_bucket*)start_pool)->next_node = *free_list_index;            *free_list_index = (pool_bucket*)start_pool;        }        start_pool = (char*)malloc(get_size);        if(0 == start_pool) {            pool_bucket **free_list_index;            pool_bucket *p;            for(int i=size;i<=MAX_BYTES_;i+=STEP_) {                free_list_index = free_list_ + freelist_index(i);                p = *free_list_index;                if(0 != p) {                    *free_list_index = p->next_node;                    start_pool = (char*)p;                    end_pool = start_pool + i;                    return (alloc_memory(size,pool_node_num));                }            }            end_pool = 0;            start_pool = (char*)malloc(get_size);        }        heap_size += get_size;        end_pool = start_pool + get_size;        //return (alloc_memory(size,pool_node_num));        char *result = start_pool;        start_pool += total_size;        return result;    }}}


main.cpp

#include <iostream>#include "mempool.h"using namespace std;int main(){    char *p;    for(size_t i=0;i<100000;++i){       p = (char*)flysnow::Mempool::allocate(i%1029+1);       cout<<flysnow::Mempool::get_heap_size()<<' ';    }    cout << endl;    system("PAUSE");    return 0;}



2 0
原创粉丝点击