SGI 空间配置器

template <int inst>
class __malloc_alloc_template 
{
private:
    static void* oom_malloc(size_t);
    static void* oom_realloc(void*, size_t);
    static void (*__malloc_alloc_oom_handler)();
public:
    static void* allocate(size_t n)
    {
        void* result = malloc(n);
        if (0 == result) result = oom_malloc(n);
        return result;
    }

    static void deallocate(void* p, size_t /* n */)
    {
        free(p);
    }

    static void* reallocate(void* p, size_t /* old_sz */, size_t new_sz)
    {
        void* result = realloc(p, new_sz);
        if (0 == result) result = oom_realloc(p, new_sz);
        return result;
    }

    static void (*set_malloc_handler(void (*f)()))()
    {
        void (*old)() = __malloc_alloc_oom_handler;
        __malloc_alloc_oom_handler = f;
        return(old);
    }
};

void (* _malloc_alloc_template<inst>::__malloc_alloc_oom_handler)() = 0;

template <int inst>
void* __malloc_alloc_template<inst>::oom_malloc(size_t n)
{
    void (*my_malloc_handler)();
    void* result;

    for (;;) 
    {
        my_malloc_handler = __malloc_alloc_oom_handler;
        if (0 == my_malloc_handler) { __THROW_BAD_ALLOC; }
        (*my_malloc_handler)();
        result = malloc(n);
        if (result) return(result);
    }
}

template <int inst>
void* __malloc_alloc_template<inst>::oom_realloc(void* p, size_t n)
{
    void (*my_malloc_handler)();
    void* result;

    for (;;) 
    {
        my_malloc_handler = __malloc_alloc_oom_handler;
        if (0 == my_malloc_handler) { __THROW_BAD_ALLOC; }
        (*my_malloc_handler)();
        result = realloc(p, n);
        if (result) return(result);
    }
}

 

template<class T, class Alloc>
class simple_alloc {

public:
    static T *allocate(size_t n)
                { return 0 == n? 0 : (T*) Alloc::allocate(n * sizeof (T)); }
    static T *allocate(void)
                { return (T*) Alloc::allocate(sizeof (T)); }
    static void deallocate(T *p, size_t n)
                { if (0 != n) Alloc::deallocate(p, n * sizeof (T)); }
    static void deallocate(T *p)
                { Alloc::deallocate(p, sizeof (T)); }
};


enum { ALIGN = 8};//小型区块的上调边界
enum { MAXBYTES = 128};//小型区块的上限,超过的区块由malloc分配
enum { NFREELISTS = MAX_BYTES / ALIGN };//free-lists的个数为16

template <bool threads, int inst>
class __default_alloc_template {
private:
    //free-lists的节点构造
    union obj
    {
        union obj *next;
        char client[1];
    };

        static obj *free_list[NFREELISTS];
    private:
        static char *start_free;  //内存池起始位置
        static char *end_free;    //内存池结束位置
        static size_t heap_size;  堆的大小
    private:
        //将bytes上调至8的倍数
        static size_t ROUND_UP(size_t bytes)
        {
            return ((bytes + _ALIGN - 1) & ~( ALIGN - 1));
        }

        //根据区块大小,决定使用第n号free-list,n从0开始计算
        static size_t FREELIST_INDEX(size_t bytes)
        {
            return (((bytes)+ ALIGN - 1) / ALIGN - 1);
        /*
           若bytes为8,则(8+7)/8-1 = 0;
           若bytes为16,则(16+7)/8-1 = 1;
           若bytes为20,则(20+7)/8-1 = 2;
           若bytes为24,则(24+7)/8-1 = 2;
        */
        }

        //返回一个大小为n的对象,并可能加入大小为n的其他区块到free-list
        static void *refill(size_t n);
        //配置一大块空间,可容纳nobjs个大小为size的区块
        //如果配置nobjs个区块有所不便,nobjs可能会降低
        static char *chunk_alloc(size_t size, size_t& nobjs);
    public:
        static void *allocate(size_t bytes);
        static void deallocate(void *ptr, size_t bytes);
        static void *reallocate(void *ptr, size_t old_sz, size_t new_sz);
    };
}

 

空间配置器allocate函数:

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

    if (n > (size_t)__MAX_BYTES) //若n大于128,则采用第一级适配器
    {
        return(malloc_alloc::allocate(n));
    }

    //寻找16个链表中适当的一个
    my_free_list = free_list + FREELIST_INDEX(n);
    result = *my_free_list;
    if (result == 0)
    {
        void* r = refill(ROUND_UP(n));
        return r;
    }
    *my_free_list = result->free_list_link;
    return (result);
};

 

重新填充free lists

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值