ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

mm.c

2019-05-13 19:54:46  阅读:678  来源: 互联网

标签:HDRP GET mm WSIZE bp PUT size


/*
 * mm-naive.c - The fastest, least memory-efficient malloc package.
 * 
 * In this naive approach, a block is allocated by simply incrementing
 * the brk pointer.  A block is pure payload. There are no headers or
 * footers.  Blocks are never coalesced or reused. Realloc is
 * implemented directly using mm_malloc and mm_free.
 *
 * NOTE TO STUDENTS: Replace this header comment with your own header
 * comment that gives a high level description of your solution.
 */
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>

#include "mm.h"
#include "memlib.h"

/*********************************************************
 * NOTE TO STUDENTS: Before you do anything else, please
 * provide your team information in the following struct.
 ********************************************************/

/* single word (4) or double word (8) alignment */
#define ALIGNMENT 8

/* rounds up to the nearest multiple of ALIGNMENT */
#define ALIGN(size) (((size) + (ALIGNMENT - 1)) & ~0x7)

#define SIZE_T_SIZE (ALIGN(sizeof(size_t)))

/* Basic constants and macros */
#define WSIZE 4
#define DSIZE 8
#define CHUNKSIZE (1 << 12)

#define MAX(x, y) ((x) > (y) ? (x) : (y))

/* Pack a size and allocated bit into a word */
#define PACK(size, prev_alloc, alloc) ((size) | (alloc) | (prev_alloc << 1))

/* Read and write a word at address p */
#define GET(p) (*(unsigned int *)(p))
#define PUT(p, val) (*(unsigned int *)(p) = (val))

/* Read the size and allocated fileds from address p */
#define GET_SIZE(p) (GET(p) & ~0x7)
#define GET_ALLOC(p) (GET(p) & 0x1)
#define GET_PREV_ALLOC(p) ((GET(p) & 0x2) >> 1)

/* Given block ptr bp, compute address of its header and footer */
#define HDRP(bp) ((char *)(bp)-WSIZE)
#define FTRP(bp) ((char *)(bp) + GET_SIZE(HDRP(bp)) - DSIZE)

/* Given block ptr bp, compute address of next and previous blocks */
#define NEXT_BLKP(bp) ((char *)(bp) + GET_SIZE((char *)(bp)-WSIZE) - WSIZE)
#define PREV_BLKP(bp) ((char *)(bp) - (GET_SIZE(HDRP((char *)bp) - WSIZE) + WSIZE))

static char *heap_listp;
static char *free_chunk_head;

void ins(void *bp)
{
    PUT(bp, NULL);
    PUT(bp + WSIZE, free_chunk_head);
    if (free_chunk_head != NULL)
        PUT(free_chunk_head + WSIZE, HDRP(bp));
    free_chunk_head = HDRP(bp);
}

void del(void *bp)
{
    if (GET(bp) != NULL)
        PUT(GET(bp) + (2 * WSIZE), GET(bp + WSIZE));
    else
        free_chunk_head = GET(bp + WSIZE);

    if (GET(bp + WSIZE) != NULL)
        PUT(GET(bp + WSIZE) + WSIZE, GET(bp));
}

static void *coalesce(void *bp)
{
    char *p;
    size_t size = GET_SIZE(HDRP(bp));
    if (GET_ALLOC(NEXT_BLKP(bp)) == 0)
    {
        p = NEXT_BLKP(bp);
        size += GET_SIZE(p);
        PUT(HDRP(bp), PACK(size, GET_PREV_ALLOC(HDRP(bp)), 0));
        PUT(FTRP(bp), PACK(size, GET_PREV_ALLOC(HDRP(bp)), 0));
        del(p + WSIZE);
    }
    if (GET_PREV_ALLOC(HDRP(bp)) == 0)
    {
        p = PREV_BLKP(bp);
        size += GET_SIZE(p);
        PUT(p, PACK(size, GET_PREV_ALLOC(p), 0));
        PUT(FTRP(p + WSIZE), PACK(size, GET_PREV_ALLOC(p), 0));
        del(bp);
        bp = p + WSIZE;
    }
    return bp;
}

static void *extend_heap(size_t words)
{
    char *bp;
    size_t size;
    size = (words % 2) ? (words + 1) * WSIZE : words * WSIZE;
    if ((long)(bp = mem_sbrk(size)) == -1)
        return NULL;
    PUT(HDRP(bp), PACK(size, GET_PREV_ALLOC(HDRP(bp)), 0));
    PUT(FTRP(bp), PACK(size, GET_PREV_ALLOC(HDRP(bp)), 0));
    ins(bp);
    PUT(NEXT_BLKP(bp), PACK(0, 0, 1));
    return coalesce(bp);
}

static void *find_fit(size_t size)
{
    size_t f = 0;
    char *p = free_chunk_head;
    char *addr;
    while (p != NULL)
    {
        if (GET_SIZE(p) >= size + 4 * WSIZE)
        {
            addr = p + WSIZE;
            f = 1;
            break;
        }
        p = GET(p + 2 * WSIZE);
    }
    if (f)
        return addr;
    else
        return NULL;
}

static void place(void *bp, size_t size)
{
    size_t lsize;
    char *p;
    lsize = GET_SIZE(HDRP(bp)) - size;
    PUT(HDRP(bp), PACK(size, GET_PREV_ALLOC(HDRP(bp)), 1));
    p = NEXT_BLKP(bp);
    PUT(p, PACK(lsize, 1, 0));
    PUT(FTRP(p + WSIZE), PACK(lsize, 1, 0));
    ins(p + WSIZE);
    del(bp);
}

/* 
 * mm_init - initialize the malloc package.
 */
int mm_init(void)
{
    free_chunk_head = NULL;
    if ((heap_listp = mem_sbrk(4 * WSIZE)) == (void *)(-1))
        return -1;
    PUT(heap_listp, 0);
    PUT(heap_listp + (1 * WSIZE), PACK(DSIZE, 1, 1));
    PUT(heap_listp + (2 * WSIZE), PACK(DSIZE, 1, 1));
    PUT(heap_listp + (3 * WSIZE), PACK(0, 1, 1));
    heap_listp += (2 * WSIZE);
    if (extend_heap(CHUNKSIZE / WSIZE) == NULL)
        return -1;
    return 0;
}

/* 
 * mm_malloc - Allocate a block by incrementing the brk pointer.
 *     Always allocate a block whose size is a multiple of the alignment.
 */
void *mm_malloc(size_t size)
{
    size_t asize;
    size_t extendsize;
    char *bp;

    if (size == 0)
        return NULL;

    if (size <= DSIZE)
        asize = 2 * DSIZE;
    else
        asize = DSIZE * ((size + (DSIZE) + (DSIZE - 1)) / DSIZE);

    if ((bp = find_fit(asize)) != NULL)
    {
        place(bp, asize);
        return bp;
    }

    extendsize = MAX(asize, CHUNKSIZE);
    if ((bp = extend_heap(extendsize / WSIZE)) == NULL)
        return NULL;
    place(bp, asize);
    return bp;
}

/*
 * mm_free - Freeing a block does nothing.
 */
void mm_free(void *bp)
{
    size_t size = GET_SIZE(HDRP(bp));
    char *np;
    PUT(HDRP(bp), PACK(size, GET_PREV_ALLOC(HDRP(bp)), 0));
    PUT(FTRP(bp), PACK(size, GET_PREV_ALLOC(HDRP(bp)), 0));
    np = NEXT_BLKP(bp);
    PUT(np, PACK(GET_SIZE(np), 0, GET_ALLOC(np)));
    ins(bp);
    coalesce(bp);
}

/*
 * mm_realloc - Implemented simply in terms of mm_malloc and mm_free
 */
void *mm_realloc(void *ptr, size_t size)
{
    void *oldptr = ptr;
    void *newptr;
    size_t copySize;

    newptr = mm_malloc(size);
    if (newptr == NULL)
        return NULL;
    copySize = *(size_t *)((char *)oldptr - SIZE_T_SIZE);
    if (size < copySize)
        copySize = size;
    memcpy(newptr, oldptr, copySize);
    mm_free(oldptr);
    return newptr;
}

 

标签:HDRP,GET,mm,WSIZE,bp,PUT,size
来源: https://www.cnblogs.com/fqqq/p/10858584.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有