mm.c
作者:互联网
/* * 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