コード例 #1
0
ファイル: Allocator.hpp プロジェクト: kawuum/grappa
  void try_merge_buddy_recursive( ChunkMap::iterator cmit ) {
    // compute address of buddy
    intptr_t address = cmit->second.address;
    intptr_t buddy_address = (address ^ cmit->second.size);
    DVLOG(5) << cmit->second << " buddy address " << (void *) buddy_address;

    // does it exist?
    ChunkMap::iterator buddy_iterator = chunks_.find( buddy_address );
    if( buddy_iterator != chunks_.end() && 
        buddy_iterator->second.size == cmit->second.size &&
        buddy_iterator->second.in_use == false ) {
      DVLOG(5) << "buddy found! address " << (void *) address << " buddy address " << (void *) buddy_address;

      // remove the higher-addressed chunk
      ChunkMap::iterator higher_iterator = address < buddy_address ? buddy_iterator : cmit;
      remove_from_free_list( higher_iterator );
      chunks_.erase( higher_iterator );

      // keep the the lower-addressed chunk in the map:
      // update its size and move it to the right free list
      ChunkMap::iterator lower_iterator = address < buddy_address ? cmit : buddy_iterator;
      remove_from_free_list( lower_iterator ); // should these be swapped? I think so.
      lower_iterator->second.size *= 2;
      add_to_free_list( lower_iterator );

      // see if we have more to merge
      try_merge_buddy_recursive( lower_iterator );
    }
  }
コード例 #2
0
/**********************************************************
 * split_and_place
 * Split the block into new_size and GET_SIZE(bp) minus new_size
 * then allocate and free the new areas
 **********************************************************/
void split_and_place(void* bp, size_t a_new_size)
{
    size_t old_size = GET_SIZE(HDRP(bp));
    size_t f_new_size = old_size - a_new_size;

    // remove this block from the explicit free list
    remove_from_free_list(bp);

    // if old_size - a_new_size >= MINBLOCK SIZE, do split
    if (f_new_size < MINBLOCKSIZE) {
        size_t bsize = GET_SIZE(HDRP(bp));
        PUT(HDRP(bp), PACK(bsize, 1));
        PUT(FTRP(bp), PACK(bsize, 1));
        // free block completely removed, so no need to add to free list

    } else {
        char * alloc_head = HDRP(bp);
        char * free_foot = FTRP(bp);
        char * free_head = alloc_head + a_new_size;
        char * alloc_foot = free_head - WSIZE;

        PUT(alloc_head, PACK(a_new_size, 1));
        PUT(free_foot, PACK(f_new_size,0));
        PUT(free_head, PACK(f_new_size,0));
        PUT(alloc_foot, PACK(a_new_size, 1));
        add_to_free_list(free_head + WSIZE);

        printf("add_to_free being called in split_place()\n");
        printf("split_place - bp: %p\n", NEXT_BLKP(bp));
        printf("split_place - addr of prev: %p\n", PREV_FR_BP(NEXT_BLKP(bp)));
        printf("split_place - addr of next: %p\n", NEXT_FR_BP(NEXT_BLKP(bp)));
    }
}
コード例 #3
0
ファイル: arena.c プロジェクト: ddstreet/glibc
/* Lock and return an arena that can be reused for memory allocation.
   Avoid AVOID_ARENA as we have already failed to allocate memory in
   it and it is currently locked.  */
static mstate
reused_arena (mstate avoid_arena)
{
  mstate result;
  /* FIXME: Access to next_to_use suffers from data races.  */
  static mstate next_to_use;
  if (next_to_use == NULL)
    next_to_use = &main_arena;

  /* Iterate over all arenas (including those linked from
     free_list).  */
  result = next_to_use;
  do
    {
      if (!__libc_lock_trylock (result->mutex))
        goto out;

      /* FIXME: This is a data race, see _int_new_arena.  */
      result = result->next;
    }
  while (result != next_to_use);

  /* Avoid AVOID_ARENA as we have already failed to allocate memory
     in that arena and it is currently locked.   */
  if (result == avoid_arena)
    result = result->next;

  /* No arena available without contention.  Wait for the next in line.  */
  LIBC_PROBE (memory_arena_reuse_wait, 3, &result->mutex, result, avoid_arena);
  __libc_lock_lock (result->mutex);

out:
  /* Attach the arena to the current thread.  */
  {
    /* Update the arena thread attachment counters.   */
    mstate replaced_arena = thread_arena;
    __libc_lock_lock (free_list_lock);
    detach_arena (replaced_arena);

    /* We may have picked up an arena on the free list.  We need to
       preserve the invariant that no arena on the free list has a
       positive attached_threads counter (otherwise,
       arena_thread_freeres cannot use the counter to determine if the
       arena needs to be put on the free list).  We unconditionally
       remove the selected arena from the free list.  The caller of
       reused_arena checked the free list and observed it to be empty,
       so the list is very short.  */
    remove_from_free_list (result);

    ++result->attached_threads;

    __libc_lock_unlock (free_list_lock);
  }

  LIBC_PROBE (memory_arena_reuse, 2, result, avoid_arena);
  thread_arena = result;
  next_to_use = result->next;

  return result;
}
コード例 #4
0
ファイル: test.c プロジェクト: thomasstrahl/Skola
block_t* merge_block(block_t* block)
{
	block_t* buddy = find_buddy(block);
	if(buddy){
		remove_from_free_list(buddy);
		remove_from_free_list(block);
		if(block > buddy){
			++(buddy->kval);
			block = buddy;
		}else{
			++(block->kval);
		}
		return merge_block(block);
	}else{
		return block;
	}
}
コード例 #5
0
/**********************************************************
 * coalesce
 * Covers the 4 cases discussed in the text:
 * - both neighbours are allocated
 * - the next block is available for coalescing
 * - the previous block is available for coalescing
 * - both neighbours are available for coalescing
 **********************************************************/
void *coalesce(void *bp)
{
    char * prev_bp = PREV_BLKP(bp);
    char * next_bp = NEXT_BLKP(bp);
    size_t prev_alloc = GET_ALLOC(FTRP(prev_bp));
    size_t next_alloc = GET_ALLOC(HDRP(next_bp));
    size_t size = GET_SIZE(HDRP(bp));

    if (prev_alloc && next_alloc) {       /* Case 1 */
        return bp;
    }

    else if (prev_alloc && !next_alloc) { /* Case 2 */
        size += GET_SIZE(HDRP(NEXT_BLKP(bp)));
        PUT(HDRP(bp), PACK(size, 0));
        PUT(FTRP(bp), PACK(size, 0));
        //Need to remove all pointer to next bp
        remove_from_free_list(next_bp);
        return (bp);
    }

    else if (!prev_alloc && next_alloc) { /* Case 3 */
        size += GET_SIZE(HDRP(PREV_BLKP(bp)));
        PUT(FTRP(bp), PACK(size, 0));
        PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
        //Need to remove all pointers to current bp
        remove_from_free_list(bp);
        return (PREV_BLKP(bp));
    }

    else {            /* Case 4 */
        size += GET_SIZE(HDRP(PREV_BLKP(bp)))  +
            GET_SIZE(FTRP(NEXT_BLKP(bp)))  ;
        PUT(HDRP(PREV_BLKP(bp)), PACK(size,0));
        PUT(FTRP(NEXT_BLKP(bp)), PACK(size,0));
        //Need to remove all pointers for current and next bp
        remove_from_free_list(bp);
        remove_from_free_list(next_bp);
        return (PREV_BLKP(bp));
    }
}
コード例 #6
0
ファイル: buffer.c プロジェクト: binsys/doc-linux
static inline void put_first_free(struct buffer_head * bh)
{
	if (!bh || (bh == free_list))
		return;
	remove_from_free_list(bh);
/* add to front of free list */
	bh->b_next_free = free_list;
	bh->b_prev_free = free_list->b_prev_free;
	free_list->b_prev_free->b_next_free = bh;
	free_list->b_prev_free = bh;
	free_list = bh;
}
コード例 #7
0
ファイル: mm.c プロジェクト: divd/ece454
/**********************************************************
 * find_fit
 * Traverse the heap searching for a block to fit asize
 * Return NULL if no free blocks can handle that size
 * Assumed that asize is aligned
 **********************************************************/
void * find_fit(size_t asize)
{

	// printf("Entered find fit.\n");
	// Divide by DSIZE (which is 16 bytes)
	unsigned int num_dwords_payload = (asize >> 4) - 1;
	int free_list_index = get_array_position_malloc(num_dwords_payload);

	if (free_list_index == FREE_LIST_SIZE - 1) {
		// look in the largest block range to find a fit
		void *best_fit_blkp = NULL;
		void *cur_blkp = free_lists[free_list_index];
		int best_fit = 9999, cur_fit;

		while(cur_blkp != NULL) {
			cur_fit = GET_SIZE(HDRP(cur_blkp)) - asize;
			if (cur_fit == 0) {
				// found the exact fit
				best_fit_blkp = cur_blkp;
				best_fit = 0;
				break;
			}
			else if (cur_fit > 0) {
				if ((best_fit_blkp == NULL) || (cur_fit < best_fit)) {
					// we don't have a previous best fit or this fit is better than our previous best fit
					best_fit_blkp = cur_blkp;
					best_fit = cur_fit;
				}
			}
			cur_blkp = NEXT_FREE_BLKP(cur_blkp);
		}
		// found a good fit. If not, will extend heap below
		if (best_fit_blkp != NULL) {
			// printf("Found best_fit blkp, leaving find fit.\n");
			remove_from_free_list(best_fit_blkp);
			return best_fit_blkp;
		}
	} else {
		while (free_list_index < FREE_LIST_SIZE) {
			void *memblk = (unsigned int *) free_lists[free_list_index];
			if (memblk == NULL) {
				free_list_index++;
			} else {
				free_lists[free_list_index] = NEXT_FREE_BLKP(memblk);
				// printf("Found memblkp, leaving find fit.\n");
				return memblk;
			}
		}
	}
	// printf("Found nothing, leaving find fit.\n");
	return NULL;
}
コード例 #8
0
ファイル: buffer.c プロジェクト: binsys/doc-linux
static inline void put_last_free(struct buffer_head * bh)
{
	if (!bh)
		return;
	if (bh == free_list) {
		free_list = bh->b_next_free;
		return;
	}
	remove_from_free_list(bh);
/* add to back of free list */
	bh->b_next_free = free_list;
	bh->b_prev_free = free_list->b_prev_free;
	free_list->b_prev_free->b_next_free = bh;
	free_list->b_prev_free = bh;
}
コード例 #9
0
ファイル: buffer.c プロジェクト: binsys/doc-linux
static inline void remove_from_queues(struct buffer_head * bh)
{
	remove_from_hash_queue(bh);
	remove_from_free_list(bh);
}
コード例 #10
0
ファイル: mm.c プロジェクト: divd/ece454
/**********************************************************
 * coalesce
 * Covers the 4 cases discussed in the text:
 * - both neighbours are allocated
 * - the next block is available for coalescing
 * - the previous block is available for coalescing
 * - both neighbours are available for coalescing
 **********************************************************/
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));

    // MACRO for PREV_BLKP does not work for this case
    if (bp == heap_listp) {
    	prev_alloc = 1;
    }
    // printf("Coalesce: size1: %u\n",(unsigned int) size);
    void *coalesced_bp = NULL;

    if (prev_alloc && next_alloc) {       /* Case 1 */
        coalesced_bp = bp;
    }

    else if (prev_alloc && !next_alloc) { /* Case 2 */
		//account for size 16 external fragmentation which isn't
		//in the free list
		if (GET_SIZE(HDRP(NEXT_BLKP(bp))) != DSIZE) {
			assert(remove_from_free_list(NEXT_BLKP(bp)));
		}
        size += GET_SIZE(HDRP(NEXT_BLKP(bp)));
        PUT(HDRP(bp), PACK(size, 0));
        PUT(FTRP(bp), PACK(size, 0));
        coalesced_bp = bp;
    }

    else if (!prev_alloc && next_alloc){
		//account for size 16 external fragmentation which isn't
		//in the free list
		if (GET_SIZE(HDRP(PREV_BLKP(bp))) != DSIZE) {
			void * if_free = remove_from_free_list(PREV_BLKP(bp));
			assert(if_free);
		}
    	  /* Case 3 */
         size += GET_SIZE(HDRP(PREV_BLKP(bp)));
		 PUT(FTRP(bp), PACK(size, 0));
		 PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0));
		 coalesced_bp = PREV_BLKP(bp);
    }

	else { /* Case 4 */
		//account for size 16 external fragmentation which isn't
		//in the free list
		int size_prev = GET_SIZE(HDRP(PREV_BLKP(bp)));
		int size_next = GET_SIZE(FTRP(NEXT_BLKP(bp)));
		if (size_prev != DSIZE)
			assert(remove_from_free_list(PREV_BLKP(bp)));
		if (size_next != DSIZE)
			assert(remove_from_free_list(NEXT_BLKP(bp)));

		size += size_prev + size_next;
        // printf("Coalesce: size_p: %u\n",(unsigned int) size_prev);
        // printf("Coalesce: size_n: %u\n",(unsigned int) size_next);
		PUT(HDRP(PREV_BLKP(bp)), PACK(size,0));
		PUT(FTRP(NEXT_BLKP(bp)), PACK(size,0));
		coalesced_bp = PREV_BLKP(bp);
	}

	// printf("Coalesced into size: %u, addr: %p\n",(unsigned int) size, (int*)coalesced_bp);
	return coalesced_bp;
}