예제 #1
0
파일: mm.c 프로젝트: horf31/ece454
/**********************************************************
 * 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));
	}

}
예제 #2
0
파일: mymalloc.c 프로젝트: Sun42/malloc
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);
}
예제 #3
0
파일: mm.c 프로젝트: horf31/ece454
/**********************************************************
 * 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);

}
예제 #4
0
파일: mm.c 프로젝트: horf31/ece454
/**********************************************************
 * 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);

}
예제 #5
0
파일: mymalloc.c 프로젝트: Sun42/malloc
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);
}
예제 #6
0
파일: mm.c 프로젝트: horf31/ece454
/**********************************************************
 * 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;
}