Exemple #1
0
/*
 * mm_free - Free a block by adding it to the appropriate list and coalescing
 *           it.
 */
void mm_free(void *ptr)
{
  size_t size = GET_SIZE(HEAD(ptr)); /* Size of block */

  /* Unset the reallocation tag on the next block */
  UNSET_TAG(HEAD(NEXT(ptr)));

  /* Adjust the allocation status in boundary tags */
  PUT(HEAD(ptr), PACK(size, 0));
  PUT(FOOT(ptr), PACK(size, 0));

  /* Insert new block into appropriate list */
  insert_node(ptr, size);

  /* Coalesce free block */
  coalesce(ptr);

  /*
  // Check heap for consistency
  line_count++;
  if (CHECK && CHECK_FREE) {
    mm_check('f', ptr, size);
  }
  */


  return;
}
Exemple #2
0
/*
 * mark - mark a block's header and footer
 */
static inline void mark(void *bp, size_t block_size, int is_prev_alloc, int is_alloc) {
    is_prev_alloc = !!is_prev_alloc;
    is_alloc = !!is_alloc;
    PUT(HEAD(bp), PACK(block_size, is_prev_alloc, is_alloc));
    if (!is_alloc) {
        PUT(FOOT(bp), PACK(block_size, is_prev_alloc, is_alloc));
    }
}
Exemple #3
0
/*
* mm_realloc - Reallocate a block in place, extending the heap if necessary.
* The new block is padded with a buffer to guarantee that the
* next reallocation can be done without extending the heap,
* assuming that the block is expanded by a constant number of bytes
* per reallocation.
*
* If the buffer is not large enough for the next reallocation,
* mark the next block with the reallocation tag. Free blocks
* marked with this tag cannot be used for allocation or
* coalescing. The tag is cleared when the marked block is
* consumed by reallocation, when the heap is extended, or when
* the reallocated block is freed.
*/
void *mm_realloc(void *ptr, size_t size)
{
void *new_ptr = ptr; /* Pointer to be returned */
size_t new_size = size; /* Size of new block */
int remainder; /* Adequacy of block sizes */
int extendsize; /* Size of heap extension */
int block_buffer; /* Size of block buffer */
/* Filter invalid block size */
if (size == 0)
return NULL;
/* Adjust block size to include boundary tag and alignment requirements */
if (new_size <= DSIZE) {
new_size = 2 * DSIZE;
} else {
new_size = DSIZE * ((new_size + (DSIZE) + (DSIZE - 1)) / DSIZE);
}
/* Add overhead requirements to block size */
new_size += BUFFER;
/* Calculate block buffer */
block_buffer = GET_SIZE(HEAD(ptr)) - new_size;
/* Allocate more space if overhead falls below the minimum */
if (block_buffer < 0) {
/* Check if next block is a free block or the epilogue block */
if (!GET_ALLOC(HEAD(NEXT(ptr))) || !GET_SIZE(HEAD(NEXT(ptr)))) {
remainder = GET_SIZE(HEAD(ptr)) + GET_SIZE(HEAD(NEXT(ptr))) - new_size;
if (remainder < 0) {
extendsize = MAX(-remainder, CHUNKSIZE);
if (extend_heap(extendsize) == NULL)
return NULL;
remainder += extendsize;
}
delete_node(NEXT(ptr));
// Do not split block
PUT_NOTAG(HEAD(ptr), PACK(new_size + remainder, 1)); /* Block header */
PUT_NOTAG(FOOT(ptr), PACK(new_size + remainder, 1)); /* Block footer */
} else {
new_ptr = mm_malloc(new_size - DSIZE);
//line_count--;
memmove(new_ptr, ptr, MIN(size, new_size));
mm_free(ptr);
//line_count--;
}
block_buffer = GET_SIZE(HEAD(new_ptr)) - new_size;
}
/* Tag the next block if block overhead drops below twice the overhead */
if (block_buffer < 2 * BUFFER)
SET_TAG(HEAD(NEXT(new_ptr)));
/*
// Check heap for consistency
line_count++;
if (CHECK && CHECK_REALLOC) {
mm_check('r', ptr, size);
}
*/
/* Return reallocated block */
return new_ptr;
}
Exemple #4
0
/*
 * coalesce - Coalesce adjacent free blocks. Sort the new free block into the
 *            appropriate list.
 */
static void *coalesce(void *ptr)
{
  size_t prev_alloc = GET_ALLOC(HEAD(PREV(ptr)));
  size_t next_alloc = GET_ALLOC(HEAD(NEXT(ptr)));
  size_t size = GET_SIZE(HEAD(ptr));

  /* Return if previous and next blocks are allocated */
  if (prev_alloc && next_alloc) {
    return ptr;
  }

  /* Do not coalesce with previous block if it is tagged */
  if (GET_TAG(HEAD(PREV(ptr))))
    prev_alloc = 1;

  /* Remove old block from list */
  delete_node(ptr);

  /* Detect free blocks and merge, if possible */
  if (prev_alloc && !next_alloc) {
    delete_node(NEXT(ptr));
    size += GET_SIZE(HEAD(NEXT(ptr)));
    PUT(HEAD(ptr), PACK(size, 0));
    PUT(FOOT(ptr), PACK(size, 0));
  } else if (!prev_alloc && next_alloc) {
    delete_node(PREV(ptr));
    size += GET_SIZE(HEAD(PREV(ptr)));
    PUT(FOOT(ptr), PACK(size, 0));
    PUT(HEAD(PREV(ptr)), PACK(size, 0));
    ptr = PREV(ptr);
  } else {
    delete_node(PREV(ptr));
    delete_node(NEXT(ptr));
    size += GET_SIZE(HEAD(PREV(ptr))) + GET_SIZE(HEAD(NEXT(ptr)));
    PUT(HEAD(PREV(ptr)), PACK(size, 0));
    PUT(FOOT(NEXT(ptr)), PACK(size, 0));
    ptr = PREV(ptr);
  }

  /* Adjust segregated linked lists */
  insert_node(ptr, size);

  return ptr;
}
Exemple #5
0
/*
* place - Set headers and footers for newly allocated blocks. Split blocks
* if enough space is remaining.
*/
static void place(void *ptr, size_t asize)
{
size_t ptr_size = GET_SIZE(HEAD(ptr));
size_t remainder = ptr_size - asize;
/* Remove block from list */
delete_node(ptr);
if (remainder >= MINSIZE) {
/* Split block */
PUT(HEAD(ptr), PACK(asize, 1)); /* Block header */
PUT(FOOT(ptr), PACK(asize, 1)); /* Block footer */
PUT_NOTAG(HEAD(NEXT(ptr)), PACK(remainder, 0)); /* Next header */
PUT_NOTAG(FOOT(NEXT(ptr)), PACK(remainder, 0)); /* Next footer */
insert_node(NEXT(ptr), remainder);
} else {
/* Do not split block */
PUT(HEAD(ptr), PACK(ptr_size, 1)); /* Block header */
PUT(FOOT(ptr), PACK(ptr_size, 1)); /* Block footer */
}
return;
}
Exemple #6
0
/*
* extend_heap - Extend the heap with a system call. Insert the newly
* requested free block into the appropriate list.
*/
static void *extend_heap(size_t size)
{
void *ptr; /* Pointer to newly allocated memory */
size_t words = size / WSIZE; /* Size of extension in words */
size_t asize; /* Adjusted size */
/* Allocate an even number of words to maintain alignment */
asize = (words % 2) ? (words + 1) * WSIZE : words * WSIZE;
/* Extend the heap */
if ((long)(ptr = mem_sbrk(asize)) == -1)
return NULL;
/* Set headers and footer */
PUT_NOTAG(HEAD(ptr), PACK(asize, 0)); /* Free block header */
PUT_NOTAG(FOOT(ptr), PACK(asize, 0)); /* Free block footer */
PUT_NOTAG(HEAD(NEXT(ptr)), PACK(0, 1)); /* Epilogue header */
/* Insert new block into appropriate list */
insert_node(ptr, asize);
/* Coalesce if the previous block was free */
return coalesce(ptr);
}
Exemple #7
0
/*
 * mm_checkheap
 */
void mm_checkheap(int verbose){
    void *bp;
    unsigned *list_p;
    unsigned *pred, *succ;
    int i;
    if (!verbose) {
        return;
    }
    bp = data_head + DSIZE;
    /* checking the heap */
    /* prologue */
    if (!(block_size(bp) == 8 && block_alloc(bp) == 1)) {
        printf("Invariant Error: prologue block\n");
    }
    /* blocks */
    bp = next_block(bp);
    while (block_size(bp) != 0) {
        if ((long)bp % DSIZE != 0) {
            printf("Invariant Error: block's address isn't aligned\n");
        }
        if (!block_alloc(bp)) {
            if (*(int *)HEAD(bp) != *(int *)FOOT(bp)) {
                printf("Invariant Error: block head and foot don't match\n");
            }
        }
        if (!block_prev_alloc(bp)) {
            if (block_prev_alloc(bp) != block_alloc(prev_block(bp))) {
                printf("Invariant Error: prev alloc bit doesn't match prev block\n");
            }
            if (block_alloc(bp) == 0) {
                printf("Inveriant Error: find consecutive free blocks\n");
            }
        }
        if (block_alloc(bp) == 0 && block_alloc(next_block(bp)) == 0) {
            printf("Inveriant Error: find consecutive free blocks\n");
        }
        if (block_size(bp) < 4 * WSIZE) {
            printf("Invariant Error: block is too small\n");
        }
        bp = next_block(bp);
    } 
    /* epilogue */
    if (!(block_size(bp) == 0 && block_alloc(bp) == 1)) {
        printf("Invariant Error: epilogue block\n");
    }

    /* checking the free list */
    list_p = (unsigned *)heap_head;
    for (i = 0; i < ARRAYSIZE; i++) {
        if (!*list_p) {
            continue;
        }
        bp = (unsigned *)r2a((size_t)*list_p);
        while (bp != NULL) {
            pred = pred_block(bp);
            succ = succ_block(bp);
            if (pred != NULL) {
                if (*(pred + 1) != a2r((size_t)bp)) {
                    printf("Invariant Error: inconsistent pointer\n");
                }
            }
            if (succ != NULL) {
                if (*succ != a2r((size_t)bp)) {
                    printf("Invariant Error: inconsistent pointer\n");
                }
            }
            if (get_list(block_size((void *)bp)) != list_p) {
                printf("Invariant Error: block size doesn't match list\n");
            }
            bp = succ;
        }
        list_p++;
    }
    print_heap();
}
Exemple #8
0
void f()
{
	FOOT();
	//FOOT_KEEPER(__FUNCTION__);
}