Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <assert.h>
- #include <unistd.h>
- #include "mm.h"
- #include "memlib.h"
- /* single word (4) or double word (8) alignment */
- #define ALIGNMENT 16
- /* rounds up to the nearest multiple of ALIGNMENT */
- #define ALIGN(size) (((size) + (ALIGNMENT-1)) & ~0x7)
- #define IS_ALIGNED(p) ((((long)(p)) % ALIGNMENT) == 0)
- #define SIZE_T_SIZE (ALIGN(sizeof(size_t)))
- /* Basic constants and macros */
- #define WSIZE 8 /* Word and header/footer size (bytes) */
- #define DSIZE 16 /* Doubleword size (bytes) */
- #define CHUNKSIZE (1<<12) /* Extend heap by this amount (bytes) */
- #define LISTLIMIT 20
- #define MAX(x, y) ((x) > (y)? (x) : (y))
- #define MIN(x, y) ((x) < (y) ? (x) : (y))
- /* Pack a size and allocated bit into a word */
- #define PACK(size, alloc) ((size) | (alloc))
- /* 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 fields from address p */
- #define GET_SIZE(p) (GET(p) & ~0x7)
- #define GET_ALLOC(p) (GET(p) & 0x1)
- /* 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)))
- #define PREV_BLKP(bp) ((char *)(bp) - GET_SIZE(((char *)(bp) - DSIZE)))
- #define NEXT(bp) (*(void **)(bp))
- #define PREV(bp) (*(void **)(((char *)(bp) + WSIZE)))
- #define GET_FREELIST(free_list, i) (*(void **)(free_list + (i*DSIZE)))
- /* Global variables */
- static char *free_list = 0;
- /* Function prototypes for internal helper routines */
- static void *extend_heap(size_t size);
- static void *coalesce(void *bp);
- static void *place(void *bp, size_t asize);
- static void insert(void *bp, size_t size);
- static void detach(void *bp);
- void mm_checkheap(int verbose);
- /*Extends the heap with a new free block*/
- void *extend_heap(size_t words)
- {
- void *bp;
- size_t size;
- size = ALIGN(words);
- if ((bp = mem_sbrk(size)) == (void *)-1){
- return NULL;
- }
- // Initialize free block header/footer and the epilogue footer
- PUT(HDRP(bp), PACK(size, 0));
- PUT(FTRP(bp), PACK(size, 0));
- PUT(HDRP(NEXT_BLKP(bp)), PACK(0, 1));
- insert(bp, size);
- return coalesce(bp);
- }
- void insert(void *bp, size_t size) {
- int list = 0;
- void *search_bp = bp;
- void *insert_bp = NULL;
- while ((list < LISTLIMIT - 1) && (size > 1)) {
- size /= 2;
- list++;
- }
- search_bp = GET_FREELIST(free_list,list);
- while ((search_bp != NULL) && (size > GET_SIZE(HDRP(search_bp)))) {
- insert_bp = search_bp;
- search_bp = NEXT(search_bp);
- }
- if (search_bp != NULL) {
- if (insert_bp != NULL) {
- NEXT(bp) = search_bp;
- PREV(search_bp) = bp;
- PREV(bp) = insert_bp;
- NEXT(insert_bp) = bp;
- }
- else {
- NEXT(bp) = search_bp;
- PREV(search_bp) = bp;
- PREV(bp) = NULL;
- GET_FREELIST(free_list,list) = bp;
- }
- }
- else {
- if (insert_bp != NULL) {
- NEXT(bp) = NULL;
- PREV(bp) = insert_bp;
- NEXT(insert_bp) = bp;
- }
- else {
- NEXT(bp) = NULL;
- PREV(bp) = NULL;
- GET_FREELIST(free_list,list) = bp;
- }
- }
- return;
- }
- /*detach the node from the free list*/
- void detach(void *bp) {
- int list = 0;
- size_t size = GET_SIZE(HDRP(bp));
- while ((list < LISTLIMIT - 1) && (size > 1)) {
- size /= 2;
- list++;
- }
- if (NEXT(bp) != NULL) {
- if (PREV(bp) != NULL) {
- PREV(NEXT(bp)) = PREV(bp);
- NEXT(PREV(bp)) = NEXT(bp);
- }
- else {
- PREV(NEXT(bp)) = NULL;
- GET_FREELIST(free_list,list) = NEXT(bp);
- }
- }
- else {
- if (PREV(bp) != NULL) {
- NEXT(PREV(bp)) = NULL;
- }
- else {
- GET_FREELIST(free_list,list) = NULL;
- }
- }
- return;
- }
- void *coalesce(void *bp)
- {
- size_t prev_alloc = GET_ALLOC(FTRP(PREV_BLKP(bp)));
- size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(bp)));
- size_t size = GET_SIZE(HDRP(bp));
- if (prev_alloc && next_alloc) {
- return bp;
- }
- else if (prev_alloc && !next_alloc) {
- detach(bp);
- detach(NEXT_BLKP(bp));
- size += GET_SIZE(HDRP(NEXT_BLKP(bp)));
- PUT(HDRP(bp), PACK(size, 0));
- PUT(FTRP(bp), PACK(size, 0));
- }
- else if (!prev_alloc && next_alloc) {
- detach(bp);
- detach(PREV_BLKP(bp));
- size += GET_SIZE(HDRP(PREV_BLKP(bp)));
- PUT(FTRP(bp), PACK(size, 0));
- PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
- bp = PREV_BLKP(bp);
- }
- else {
- detach(bp);
- detach(PREV_BLKP(bp));
- detach(NEXT_BLKP(bp));
- size += GET_SIZE(HDRP(PREV_BLKP(bp))) + GET_SIZE(HDRP(NEXT_BLKP(bp)));
- PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
- PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0));
- bp = PREV_BLKP(bp);
- }
- insert(bp, size);
- return bp;
- }
- /*place the block to its position*/
- void *place(void *bp, size_t asize)
- {
- size_t csize = GET_SIZE(HDRP(bp));
- size_t remainder = csize - asize;
- detach(bp);
- if (remainder <= DSIZE * 2) {
- PUT(HDRP(bp), PACK(csize, 1));
- PUT(FTRP(bp), PACK(csize, 1));
- }
- else if (asize >= 112) {
- PUT(HDRP(bp), PACK(remainder, 0));
- PUT(FTRP(bp), PACK(remainder, 0));
- PUT(HDRP(NEXT_BLKP(bp)), PACK(asize, 1));
- PUT(FTRP(NEXT_BLKP(bp)), PACK(asize, 1));
- insert(bp, remainder);
- return NEXT_BLKP(bp);
- }
- else {
- PUT(HDRP(bp), PACK(asize, 1));
- PUT(FTRP(bp), PACK(asize, 1));
- PUT(HDRP(NEXT_BLKP(bp)), PACK(remainder, 0));
- PUT(FTRP(NEXT_BLKP(bp)), PACK(remainder, 0));
- insert(NEXT_BLKP(bp), remainder);
- }
- return bp;
- }
- /*
- * mm_init - initialize the malloc package.
- */
- int mm_init(void)
- {
- char *heap_listp;
- free_list = NULL;
- free_list = mem_sbrk(LISTLIMIT * DSIZE);
- for (int i = 0; i < LISTLIMIT ; ++i){
- GET_FREELIST(free_list,i) = NULL;
- }
- if ((long)(heap_listp = mem_sbrk(4 * WSIZE)) == -1){
- return -1;
- }
- PUT(heap_listp, 0); /* Alignment padding */
- PUT(heap_listp + (1 * WSIZE), PACK(DSIZE, 1)); /* Prologue header */
- PUT(heap_listp + (2 * WSIZE), PACK(DSIZE, 1)); /* Prologue footer */
- PUT(heap_listp + (4 * WSIZE), PACK(0, 1)); /* Epilogue header */
- if(extend_heap(CHUNKSIZE) == 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; /* Adjusted block size */
- size_t extendsize; /* Amount to extend heap if no fit */
- void *bp = NULL;
- if (size == 0)
- return NULL;
- if (size <= DSIZE)
- asize = 2 * DSIZE;
- else
- asize = ALIGN(size+DSIZE);
- int list = 0;
- size_t searchsize = asize;
- while (list < LISTLIMIT) {
- if ((list == LISTLIMIT - 1) || ((searchsize <= 1) && (GET_FREELIST(free_list,list) != NULL))) {
- bp = GET_FREELIST(free_list,list);
- while ((bp != NULL) && ((asize > GET_SIZE(HDRP(bp))))){
- bp = NEXT(bp);
- }
- if (bp != NULL){
- break;
- }
- }
- searchsize /= 2;
- list++;
- }
- if (bp == NULL) {
- extendsize = MAX(asize, CHUNKSIZE);
- if ((bp = extend_heap(extendsize)) == NULL)
- return NULL;
- }
- bp = place(bp, asize);
- return bp;
- }
- /*
- * mm_free - Freeing a block does nothing.
- */
- void mm_free(void *bp)
- {
- size_t size = GET_SIZE(HDRP(bp));
- PUT(HDRP(bp), PACK(size, 0));
- PUT(FTRP(bp), PACK(size, 0));
- insert(bp, size);
- coalesce(bp);
- }
- /*
- * mm_realloc - Implemented simply in terms of mm_malloc and mm_free
- */
- void *mm_realloc(void *bp, size_t size)
- {
- void *new_bp = bp;
- size_t new_size = size;
- int remainder;
- int extendsize;
- if (size == 0){
- return NULL;
- }
- if (new_size <= DSIZE) {
- new_size = 2 * DSIZE;
- }
- else {
- new_size = ALIGN(size+DSIZE);
- }
- if (!GET_ALLOC(HDRP(NEXT_BLKP(bp))) || !GET_SIZE(HDRP(NEXT_BLKP(bp)))) {
- remainder = GET_SIZE(HDRP(bp)) + GET_SIZE(HDRP(NEXT_BLKP(bp))) - new_size;
- if (remainder < 0) {
- extendsize = MAX(-remainder, CHUNKSIZE);
- if (extend_heap(extendsize) == NULL){
- return NULL;
- }
- remainder += extendsize;
- }
- detach(NEXT_BLKP(bp));
- PUT(HDRP(bp), PACK(new_size + remainder, 1));
- PUT(FTRP(bp), PACK(new_size + remainder, 1));
- }
- else {
- new_bp = mm_malloc(new_size - DSIZE);
- memcpy(new_bp, bp, MIN(size, new_size));
- mm_free(bp);
- }
- return new_bp;
- }
- /* check for errors */
- void mm_checkheap(int verbose){
- for (int i = 0; i < LISTLIMIT-1; i++){
- void* bp = GET_FREELIST(free_list,i);
- while (bp != NULL){
- if(GET_ALLOC(bp) == 1){
- printf("You have an allocated block in the free list");
- }
- bp = NEXT(bp);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement