/********************************************************** * place * Mark the block as allocated **********************************************************/ void place(void* bp, size_t asize, int from_free_list) { // Get the current block size size_t bsize = GET_SIZE(HDRP(bp)); // bp is not from the operation of the extend_heap, so need to remove from free list if (from_free_list == 1) delete_from_list(bp); void * split_bp; // Split the block if the difference of the sizes is not less than the minimum block size (2*DSIZE) if (asize + 2 * DSIZE <= bsize) { // Mark the footer and header with the requested size PUT(HDRP(bp), PACK(asize, 1)); PUT(FTRP(bp), PACK(asize, 1)); // Find the next block ptr as split ptr split_bp = NEXT_BLKP(bp); // Mark the footer and header of the splitted block PUT(HDRP(split_bp), PACK((bsize-asize), 0)); PUT(FTRP(split_bp), PACK((bsize-asize), 0)); // Insert this free block to the list insert_freelist(split_bp); } else { // Not enough size to split, mark the footer and header PUT(HDRP(bp), PACK(bsize, 1)); PUT(FTRP(bp), PACK(bsize, 1)); } }
void myfree(void *ptr) { /* my_putstr("############## FREE ######### \n"); my_put_nbr(ptr); */ /* todo some control*/ if (ptr == NULL) return ; if (del_list_alloc(&start_alloc, (t_header *)ptr - 1) == -1) my_putstr("echoue"); insert_freelist((t_header *)ptr - 1); }
/********************************************************** * split * Split the block with requested size **********************************************************/ void split(void *ptr, size_t size, size_t oldSize) { void * split_bp; // Mark header and footer PUT(HDRP(ptr), PACK(size, 1)); PUT(FTRP(ptr), PACK(size, 1)); // Find the next block ptr as split ptr split_bp = NEXT_BLKP(ptr); // Mark split ptr's header and footer PUT(HDRP(split_bp), PACK((oldSize-size), 0)); PUT(FTRP(split_bp), PACK((oldSize-size), 0)); // Insert this free block to the list insert_freelist(split_bp); }
/********************************************************** * mm_free * Free the block and coalesce with neighbouring blocks **********************************************************/ void mm_free(void *bp) { // If ptr is NULL, do nothing if (bp == NULL) return; // Coalesce with the neighboring block if possible bp = coalesce(bp); // Mark the header and footer of the current/coalesced block size_t size = GET_SIZE(HDRP(bp)); PUT(HDRP(bp), PACK(size,0)); PUT(FTRP(bp), PACK(size,0)); // Insert this free block to the list insert_freelist(bp); }
int ask_memory(unsigned int unite) { int nb; void *addr; t_header *header; struct rlimit rlp; /* my_putstr("Ask memory "); my_put_nbr(unite); my_putstr("\n Sbrk(0) : "); my_put_nbr((unsigned )sbrk(0)); getrlimit(RLIMIT_DATA,&rlp); my_putstr(" \nRlimit cur:"); my_put_nbr((unsigned )rlp.rlim_cur); my_putstr(" \n Rlimit max:"); my_put_nbr((unsigned int)rlp.rlim_max); my_putchar('\n'); */ if (unite < NALLOC) unite = NALLOC; nb = (unite) * sizeof(t_header); /* my_put_nbr(nb); my_putchar('\n'); */ addr = sbrk(nb); if ((char *) addr == (char *) - 1) { /* my_putstr("Can't allocate memory \n"); my_put_nbr_error(errno); */ errno = 12; return (0); } header = (t_header *)addr; header->size = (nb / sizeof(t_header)); header->next = NULL; insert_freelist((void *)addr); return (1); }
/********************************************************** * mm_realloc * Implemented simply in terms of mm_malloc and mm_free *********************************************************/ void *mm_realloc(void *ptr, size_t size) { /* Case 1: If size == 0 then this is just free, and we return NULL. */ if (size == 0) { mm_free(ptr); return NULL; } /* Case 2: If oldptr is NULL, then this is just malloc. */ if (ptr == NULL) { return (mm_malloc(size)); } /* Case 3: Size is equal or smaller than the original size, return or split */ size_t old_size = GET_SIZE(HDRP(ptr)); /* current block size */ size_t asize; /* adjusted requested block size */ // Adjust block size to include overhead and alignment reqs. if (size <= DSIZE) asize = 2 * DSIZE; else asize = DSIZE * ((size + (DSIZE) + (DSIZE - 1)) / DSIZE); // If old_size is greater than the minimum block size and new size, then split if (old_size >= asize + 2 * DSIZE) { split(ptr, asize, old_size); return ptr; } else if (old_size >= asize) { // If not enough space to split, just return return ptr; } /* Case 4: Check next neighboring block, if free, and the combined size is equal to or greater than size, combine */ size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(ptr))); /* allocative state of the next block */ size_t next_size = GET_SIZE(HDRP(NEXT_BLKP(ptr))); /* size of the next block */ size_t remainder_size; if ((int) next_alloc == 0 && old_size + next_size >= asize) { delete_from_list(NEXT_BLKP(ptr)); // Remove from the free list // If the combined space is too large, split if (old_size + next_size > asize + 2 * DSIZE) { PUT(HDRP(ptr), PACK(asize, 1)); // Mark the footer and header of the realloc'd block PUT(FTRP(ptr), PACK(asize, 1)); remainder_size = old_size + next_size - asize; // Calculate the remainder size of the splitted block PUT(HDRP(NEXT_BLKP(ptr)), PACK(remainder_size, 0)); // Mark the footer and header for the splitted block PUT(FTRP(NEXT_BLKP(ptr)), PACK(remainder_size, 0)); insert_freelist((intptr_t *) NEXT_BLKP(ptr)); } else { // No enough space to split PUT(HDRP(ptr), PACK(old_size+next_size, 1)); // Mark the footer and header of the realloc'd block PUT(FTRP(ptr), PACK(old_size+next_size, 1)); } return ptr; } /* Case 5: Current block is at the end of the heap, just extend heap */ // Check if the next block ptr is at the end of the heap if (NEXT_BLKP(ptr) > (char*)mem_heap_hi() ) { size_t extendsize = asize - old_size; // Calculate the size needed to extend intptr_t * bp; if ((bp = extend_heap(extendsize / WSIZE)) == NULL) // Extend the heap return NULL; PUT(HDRP(ptr), PACK(asize, 1)); // Mark the footer and header PUT(FTRP(ptr), PACK(asize, 1)); return ptr; } /* Case 6: Check previous neighboring block, if free, and the combined size is equal to or greater than size, combine and move the content */ intptr_t * prev_p = (intptr_t *)PREV_BLKP(ptr); /* previous block's ptr */ size_t prev_alloc = GET_ALLOC(HDRP(prev_p)); /* allocative state of the prev block */ size_t prev_size = GET_SIZE(HDRP(prev_p)); /* size of the next block */ if ((int) prev_alloc == 0 && old_size + prev_size >= asize) { delete_from_list(PREV_BLKP(ptr)); // Remove from the free list memmove(prev_p, ptr, asize); // Move the content to the new starting ptr // If the combined space is too large, split if (old_size + prev_size > asize + 2 * DSIZE) { PUT(HDRP(prev_p), PACK(asize, 1)); // Mark the footer and header of the realloc'd block PUT(FTRP(prev_p), PACK(asize, 1)); remainder_size = old_size + prev_size - asize; // Calculate the remainder size of the splitted block PUT(HDRP(NEXT_BLKP(prev_p)), PACK(remainder_size, 0)); // Mark the footer and header for the splitted block PUT(FTRP(NEXT_BLKP(prev_p)), PACK(remainder_size, 0)); insert_freelist((intptr_t *) NEXT_BLKP(prev_p)); } else { // No enough space to split PUT(HDRP(prev_p), PACK(old_size+prev_size, 1)); // Mark the footer and header of the realloc'd block PUT(FTRP(prev_p), PACK(old_size+prev_size, 1)); } return prev_p; } /* Case 7: Malloc a new block, copy the content, free the old block */ void *oldptr = ptr; void *newptr; newptr = mm_malloc(size); // Malloc a new block if (newptr == NULL) return NULL; // Copy the old data. if (size < old_size) old_size = size; memcpy(newptr, oldptr, old_size); mm_free(oldptr); // Free the old block return newptr; }