#include "mm.h" //rounds up to a multiple of the alignment for payloads and for block sizes #define ALIGNMENT 16 #define ALIGN(size) (((size) + (ALIGNMENT-1)) & ~(ALIGNMENT-1)) //excess space in block not used for payload #define OVERHEAD sizeof(block_header) //returns a pointer to the header to the given payload's block //bp = "Block Payload pointer" #define HDRP(bp) ((char *)(bp) - sizeof(block_header)) //returns the size of the given block #define GET_SIZE(p) ((block_header *)(p))->size //returns whether the block is allocated or not #define GET_ALLOC(p) ((block_header *)(p))->allocated //returns a payload pointer for the next block, given a payload pointer #define NEXT_BLKP(bp) ((char *)(bp) + GET_SIZE(HDRP(bp))) //representation of header and is a multiple of the alignment typedef struct { size_t size; char allocated; } block_header; //pointer to the payload of the first block in our heap void *first_bp; void mm_init(void *heap, size_t heap_size) { void *bp; // We changed the initial allocator to have TWO blocks instead of // just one. It no longer passes --single mode if the allocation // size is around half a page or larger, but it still passes for // smaller sizes. printf("Heap size: %ld\n", heap_size); // here's a place where we depend on // block_header being a multiple of ALIGNMENT: bp = heap + sizeof(block_header); // relying on heap_size being a multiple of 16, // which is part of the spec for mm_init GET_SIZE(HDRP(bp)) = heap_size/4; GET_ALLOC(HDRP(bp)) = 0; GET_SIZE(HDRP(NEXT_BLKP(bp))) = 3*heap_size/4; GET_ALLOC(HDRP(NEXT_BLKP(bp))) = 0; first_bp = bp; } static void set_allocated(void *bp) { GET_ALLOC(HDRP(bp)) = 1; } void *mm_malloc(size_t size) { void *bp = first_bp; //printf("Block Allocated: %d\n", GET_ALLOC(HDRP(bp))); //printf("Size available: %ld\n", GET_SIZE(HDRP(bp))); if (GET_ALLOC(HDRP(bp)) || ((size + OVERHEAD) > GET_SIZE(HDRP(bp)))) { /* Our only block is already allocated */ if(GET_ALLOC(HDRP(NEXT_BLKP(bp))) || ((size + OVERHEAD) > GET_SIZE(HDRP(NEXT_BLKP(bp))))) { return NULL; } else{ set_allocated(NEXT_BLKP(bp)); return NEXT_BLKP(bp); } } else { set_allocated(bp); return bp; } } void mm_free(void *bp) { // Callers must ensure that bp is actually allocated GET_ALLOC(HDRP(bp)) = 0; }