阿里2015实习生笔试附加题第一个

enum{ __ALIGN = 8 };
enum{ __MAX_BYTES = 128 };
enum{ __NFREELISTS = __MAX_BYTES / __ALIGN };

template <bool threads, int inst>
class FreeList
{
private:
    static size_t ROUND_UP(size_t bytes)
    {
        return (((bytes)+__ALIGN - 1) & ~(__ALIGN - 1));
    }

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

    static obj* volatile free_list[__NFREELISTS];
    static size_t FREELIST_INDEX(size_t bytes)
    {
        return (((bytes)+__ALIGN - 1) / __ALIGN - 1);
    }

    static void* refill(size_t n);
    static char* chunk_alloc(size_t size, int& nobjs);


    static char* start_free;
    static char* end_free;
    static size_t heap_size;

public:
    void special_access(size_t sz, int n)
    {
        chunk_alloc(sz, n);
    }

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

        if (n > (size_t)__MAX_BYTES)

            return malloc((size_t)n);

        my_free_list = free_list + FREELIST_INDEX(n);
        result = *my_free_list;

        if (0 == result)
        {

            void* r = refill(ROUND_UP(n));
            return r;
        }

        *my_free_list = result->free_list_link;
        return result;
    }

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

        if (n > (size_t)__MAX_BYTES)
        {

            free(p);
            return;
        }

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

    static void* reallocate(void* p, size_t old_sz, size_t new_sz);
};
template <bool threads, int inst>
char* FreeList<threads, inst>::start_free = 0;

template <bool threads, int inst>
char* FreeList<threads, inst>::end_free = 0;

template <bool threads, int inst>
size_t FreeList<threads, inst>::heap_size = 0;
template <bool threads, int inst>
typename FreeList<threads, inst>::obj* volatile FreeList<threads, inst>::free_list[__NFREELISTS] =
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

template <bool threads, int inst>
void* FreeList<threads, inst>::refill(size_t n)
{
    int nobjs = 20;

    char* chunk = chunk_alloc(n, nobjs);
    obj* volatile* my_free_list;
    obj* result;
    obj* current_obj, *next_obj;
    int i;
    if (1 == nobjs)
        return chunk;
    my_free_list = free_list + FREELIST_INDEX(n);
    result = (obj*)chunk;
    *my_free_list = next_obj = (obj*)(chunk + n);

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

template<bool threads, int inst>
char* FreeList<threads, inst>::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);
    }
    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);
        if (0 == start_free)
        {

            int i;


            obj* volatile* my_free_list, *p;

            for (i = size; i <= __MAX_BYTES; i += __ALIGN)
            {
                my_free_list = free_list + FREELIST_INDEX(i);
                p = *my_free_list;
                if (0 != p)
                {
                    *my_free_list = p->free_list_link;
                    start_free = (char*)p;
                    end_free = start_free + i;
                    return(chunk_alloc(size, nobjs));

                }
            }

            end_free = 0;
            start_free = (char*)malloc(bytes_to_get);
        }

        heap_size += bytes_to_get;
        end_free = start_free + bytes_to_get;
        return(chunk_alloc(size, nobjs));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值