Chinaunix首页 | 论坛 | 博客
  • 博客访问: 208341
  • 博文数量: 35
  • 博客积分: 2691
  • 博客等级: 少校
  • 技术积分: 527
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-11 09:42
文章分类

全部博文(35)

文章存档

2012年(5)

2010年(6)

2009年(2)

2008年(22)

我的朋友

分类: C/C++

2008-05-28 16:35:50

//default_alloc.h

 

#ifndef DEFAULT_MALLOC_H
#define DEFAULT_MALLOC_H

#include <stdlib.h>
#include "malloc_alloc.h"

class __default_alloc : public __malloc_alloc {
public:
    void* allocate(size_t n);
    void deallocate(void* p, size_t n);
    void* reallocate(void*p, size_t old_sz, size_t new_sz);
private:
    enum {__ALIGN = 8};

    enum {__MAX_BYTES = 128};

    enum {__NFREELISTS = __MAX_BYTES/__ALIGN};

    size_t ROUND_UP(size_t bytes) {
        return ((bytes) + __ALIGN - 1) & ~(__ALIGN - 1);
    }

    union obj {
        union obj* free_list_link;
        char client_data[1];
    };

    obj* volatile free_list[__NFREELISTS];

    size_t FREELIST_INDEX(size_t bytes) {
        return (((bytes) + __ALIGN - 1) / __ALIGN - 1);
    }

    void* refill(size_t n);

    char* chunk_alloc(size_t size, int &nobjs);

    char* start_free;
    char* end_free;
    size_t heap_size;
    __default_alloc() {
        start_free = 0;
        end_free = 0;
        heap_size = 0;
    }
};

#endif

//default_alloc.cpp
#include "default_alloc.h"

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

    if(n > (size_t)__MAX_BYTES) {
        return __malloc_alloc::allocate(n);
    }

    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;
}

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

    if(n > (size_t)__MAX_BYTES) {
        __malloc_alloc::deallocate(p, n);
        return;
    }

    my_free_list = free_list + FREELIST_INDEX(n);
    q->free_list_link = *my_free_list;
    *my_free_list = q;
}

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

    my_free_list = free_list + FREELIST_INDEX(n);
    result = (obj*)chunk;
    *my_free_list = next_obj = (obj*)(chunk + n);
    for(int i = 1; ; ++i) {
        current_obj = next_obj;
        next_obj = (obj*)((char*)current_obj + n);
        if(nobjs - 1 == i) {
            current_obj->free_list_link = 0;
            break;
        } else {
            current_obj->free_list_link = next_obj;
        }
    }

    return result;
}

char* __default_alloc::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;
    } else if(bytes_left >= size) {
        nobjs = bytes_left/size;
        total_bytes = size * nobjs;
        result = start_free;
        start_free += total_bytes;
        return result;
    } else {
        size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size >> 4);
        if(bytes_left > 0) {
            obj* volatile* my_free_list = free_list + FREELIST_INDEX(bytes_left);
            ((obj*)start_free)->free_list_link = *my_free_list;
            *my_free_list = (obj*)start_free;
        }

        start_free = (char*)malloc(bytes_to_get);
        heap_size += bytes_to_get;
        end_free = start_free + bytes_to_get;
        return chunk_alloc(size, nobjs);
    }
}

 

//malloc_alloc.h
#ifndef MALLOC_ALLOC_H
#define MALLOC_ALLOC_H

#include <stdio.h>
#include <stdlib.h>

class __malloc_alloc {
public:
    void* allocate(size_t n);
    void deallocate(void* p, size_t n);
    void* reallocate(void* p, size_t old_sz, size_t new_sz);
};

#endif

//malloc_alloc.cpp
#include "malloc_alloc.h"

void* __malloc_alloc::allocate(size_t n)
{
    void* result = malloc(n);
    return result;
}

void __malloc_alloc::deallocate(void* p, size_t n)
{
    free(p);
}

void* __malloc_alloc::reallocate(void* p, size_t old_sz, size_t new_sz)
{
    void* result = realloc(p, new_sz);
    return result;
}

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