Exemplo n.º 1
0
/*
* mm_checkheap
*/
void mm_checkheap(int lineno) {
    lineno = lineno;

    int free_count = 0;
    int freelist_count = 0;
    void *bp;

    for (bp = free_listp; GET_SIZE(HDRP(bp)) > 0; bp = NEXT_FREE_BLKP(bp)) {
        if (GET_ALLOC(bp)) 
            printf("Allocated block in free list!\n");
        if (!aligned(bp)) printf("Base pointer in heap is not aligned!\n");
        if (!in_heap(NEXT_FREE_BLKP(bp)) || !in_heap(PREV_FREE_BLKP(bp))) 
            printf("Pointer not in heap! Uh oh.\n");
        if (GET(HDRP(bp)) != GET(FTRP(bp))) 
            printf("Header and footer don't match! Dang...\n");
        if (PREV_FREE_BLKP(NEXT_FREE_BLKP(bp)) != bp || 
            NEXT_FREE_BLKP(PREV_FREE_BLKP(bp)) != bp)
            printf("Pointers do not match up! Ugh\n");
        freelist_count++;
    }

    for (bp = free_listp; GET_SIZE(HDRP(bp)) > 0; bp = NEXT_BLKP(bp)) {
        if (!aligned(bp)) printf("Base pointer in heap is not aligned!\n");
        if (GET(HDRP(bp)) != GET(FTRP(bp))) 
            printf("Header and footer don't match! Dang...\n");
        if (PREV_BLKP(NEXT_BLKP(bp)) != bp || NEXT_BLKP(PREV_BLKP(bp)) != bp)
            printf("Pointers do not match up! Ugh\n");
        if (!GET_ALLOC(HDRP(bp))) free_count++;
    }

    if (free_count != freelist_count) 
        printf("Free blocks in free list don't match up with heap traversal!");

}
Exemplo n.º 2
0
// Return the header to the successor free block
static inline uint32_t* block_succ(uint32_t* const block) {
    REQUIRES(block != NULL);
    REQUIRES(in_heap(block));

    uint32_t * address = heap_listp + block[2];

    ENSURES(address != NULL);
    ENSURES(in_heap(address));

    if (address == heap_listp)
        return NULL;
    else 
        return address;
}
Exemplo n.º 3
0
// Return a pointer to block of what malloc returns
static inline uint32_t* block_block(uint32_t* const ptr) {
    REQUIRES(ptr != NULL);
    REQUIRES(in_heap(ptr - 1));
    REQUIRES(aligned(ptr));

    return ptr - 1;
}
Exemplo n.º 4
0
/*
 * malloc
 */
void *malloc (size_t size) {
    size_t a_size;
    size_t e_size;
    uint32_t *bp = NULL;

    if(size == 0)
	return NULL;

    if(size <= DSIZE)
	a_size = 2*DSIZE;
    else
	a_size = DSIZE * ((size + (DSIZE) + (DSIZE - 1)) / DSIZE);

    bp = find_first_fit(a_size);
    if(bp != NULL) {
	place(bp, a_size);
	return bp;
    }
    
    e_size = MAX(a_size, CHUNKSIZE);
    bp = extend_heap(e_size/WSIZE);
    if(bp != NULL) {
	place(bp, a_size);
	return bp;
    }
    if(0)
    	in_heap(bp);
    return NULL;
}
Exemplo n.º 5
0
/*
 * free
 */
void free (void *ptr) {
  unsigned oldS;//store original size that ptr points to
  unsigned neighS;//neighbor size
  void *nextPtr;//used for forwards just for ease of typing

  if(!ptr || !in_heap(ptr)) 
    return;

  ptr--;
  setAlloc(ptr, 0);
  setAlloc(ptr+(block_size(ptr)+1), 0);

  /* Coalesce Backwards: */
  if(!is_alloc((ptr-1))){
    oldS=block_size(ptr);
    neighS=block_size(ptr-1);
    ptr-=(neighS+2);
    createBlock(ptr, neighS+oldS+2, 0);
  }

  /* Coalesce Forwards: 
   *independent from backwards, just use ptr */
  nextPtr=ptr+block_size(ptr)+2;
  if(!is_alloc(nextPtr))
    createBlock(ptr, block_size(nextPtr)+2, 0);
}
Exemplo n.º 6
0
// Return a pointer to the memory malloc should return
static inline uint32_t* block_mem(uint32_t* const block) {
    REQUIRES(block != NULL);
    REQUIRES(in_heap(block));
    REQUIRES(aligned(block + 1));

    return block + 1;
}
Exemplo n.º 7
0
/*
 * Place the block and potentially split the block
 * Return: Nothing
 */
static void place(void *block, unsigned int awords) {
    REQUIRES(awords >= 2 && awords % 2 == 0);
    REQUIRES(block != NULL);
    REQUIRES(in_heap(block));
    REQUIRES(in_list(block));

    unsigned int cwords = block_size(block); //the size of the given freeblock
    block_delete(block);      // delete block from the seg list
    
    ENSURES(!in_list(block));

    if ((cwords - awords) >= 4) {
        set_size(block, awords);
        block_mark(block, ALLOCATED);
        block = block_next(block);
        set_size(block, cwords - awords - 2);
        block_mark(block, FREE);
        block_insert(block);

        ENSURES(in_list(block));
    } else {
        set_size(block, cwords);
        block_mark(block, ALLOCATED);
    }    
 }
Exemplo n.º 8
0
Arquivo: mm.c Projeto: nik-6947/malloc
/* 
 * Requires:
 *   None.
 *
 * Effects:
 *   Perform a minimal check of the heap for consistency. 
 */
void
checkheap(bool verbose) 
{
  void *bp;

  if (verbose)
    printf("Heap (%p):\n", heap_listp);

  if (GET_SIZE(HDRP(heap_listp)) != DSIZE ||
      !GET_ALLOC(HDRP(heap_listp)))
    printf("Bad prologue header\n");
  checkblock(heap_listp);

  for (bp = heap_listp; GET_SIZE(HDRP(bp)) > 0; bp = (void *)NEXT_BLKP(bp)) {
    if (verbose)
      printblock(bp);
    checkblock(bp);
  }

  if (verbose)
    printblock(bp);
  if (GET_SIZE(HDRP(bp)) != 0 || !GET_ALLOC(HDRP(bp)))
    printf("Bad epilogue header\n");

in_heap(bp);
check_coalescing();
check_free_list();
check_free_blocks();
}
Exemplo n.º 9
0
// Delete the given block from the seg list
static inline void block_delete(uint32_t* block) {
    REQUIRES(block != NULL);
    REQUIRES(in_heap(block));


    uint32_t *pred = block_pred(block);
    uint32_t *succ = block_succ(block);
    int index = find_index(block_size(block));

    if (pred == NULL && succ == NULL) { 
        // The list has only one block
        seg_list[index] = NULL;
    } else if (pred == NULL && succ != NULL) {
        // This block is at the head, seg_list[index] == block
        set_ptr(succ, NULL, block_succ(succ));
        seg_list[index] = succ;
    } else if (pred != NULL && succ == NULL) {
        // This block is at the tail
        set_ptr(pred, block_pred(pred), NULL);
    } else {
        // This block is the middle of somewhere
        set_ptr(pred, block_pred(pred), succ);
        set_ptr(succ, pred, block_succ(succ));
    }
}
Exemplo n.º 10
0
static inline void set_size(uint32_t* block, size_t size){
    REQUIRES(block != NULL);
    REQUIRES(in_heap(block));

    *block = size & 0x3FFFFFFF;
    *(block + block_size(block)/sizeof(uint32_t*) - 1) = size & 0x3FFFFFFF;
}
Exemplo n.º 11
0
/*
 * Set the pred and succ of the given free block
 * Since the whole memory space is 2^32 bytes
 * I can compress the 8 bytes address into 4 bytes
 * by computing its offest to heap_listp
 */
static inline void set_ptr(uint32_t* const block, 
                          uint32_t* const pred_block, 
                          uint32_t* const succ_block) {
    REQUIRES(block != NULL);
    REQUIRES(in_heap(block));

    unsigned int pred_offest; 
    unsigned int succ_offest;

    if (pred_block == NULL)
        pred_offest = 0;
    else 
        pred_offest = pred_block - heap_listp;

    if (succ_block == NULL)
        succ_offest = 0;
    else
        succ_offest = succ_block - heap_listp;

    //printf("pred_off = %d, succ_off = %d\n", pred_offest, succ_offest);
    set_val(block + 1 , pred_offest);
    set_val(block + 2 , succ_offest);
    ENSURES(block_pred(block) == pred_block);
    ENSURES(block_succ(block) == succ_block);    
}
Exemplo n.º 12
0
// Return a pointer to the memory malloc should return
static inline void* block_mem(uint64_t* block) {
    REQUIRES(block != NULL);
    REQUIRES(in_heap(block));
    REQUIRES(aligned(block));
    REQUIRES(aligned(block + 3));

    return (void*)(block+3);
}
Exemplo n.º 13
0
void test_alloc_string()
{
  int str_length;
  byte *before, *after;
  String *s;
  before = heap_address();
  s = alloc_String(12);
  after = heap_address();
  strcpy(s->elements, "abcdefghijkl");
  str_length = sizeof_array(12, ARRAY_CHAR);

  ASSERT(align(str_length), (after - before));
  ASSERT(12, s->length);
  ASSERT_TRUE(in_heap((Object *) s));
  ASSERT_STR("abcdefghijkl", s->elements);
  ASSERT_TRUE(in_heap((Object *) s->elements));
}
Exemplo n.º 14
0
/*
 * mm_checkheap
 */
void mm_checkheap(int verbose) {

    if (verbose)
        printf("Heap (%p):\n", freelist);
    
    in_heap(freelist);
    aligned(freelist);
}
Exemplo n.º 15
0
// Return the size of the given block in multiples of the word size
static inline unsigned int block_size(const uint32_t* block) {
    REQUIRES(block != NULL);
    REQUIRES(in_heap(block));

    //return (block[0] & 0x3FFFFFFF);
	return (*block)&(~0x7);

}
Exemplo n.º 16
0
// Mark the given block as free(1)/alloced(0) by marking the header and footer.
static inline void block_mark(uint32_t* block, int free) {
    REQUIRES(block != NULL);
    REQUIRES(in_heap(block));

    //unsigned int next = block_size(block) + 1;
    block[0] = free ? block[0] & (int) 0xBFFFFFFF : block[0] | 0x40000000;
    //block[next] = block[0];
}
Exemplo n.º 17
0
// Return a pointer to the memory malloc should return
static inline uint32_t* block_mem(uint32_t* const block) {
    REQUIRES(block != NULL);
    REQUIRES(in_heap(block));
    REQUIRES(aligned(block + 1));
    if (VERBOSE)
        printf("Heap size = %d bytes \n", (int)mem_heapsize());
    return block + 1;
}
Exemplo n.º 18
0
// Mark the given block as free(1)/alloced(0) by marking the header and footer.
static inline void block_mark(uint32_t* block, int free) {
    REQUIRES(block != NULL);
    REQUIRES(in_heap(block));

    unsigned int size = block_size(block);
    PUT(block, PACK(size, free));
    PUT((block + (size/WSIZE) - 1), PACK(size, free));
}
Exemplo n.º 19
0
// Set the size of the given block in multiples of 4 bytes
static inline void set_size(uint32_t* const block, unsigned int size) {
    REQUIRES(block != NULL);
    REQUIRES(in_heap(block));
    REQUIRES(size % 2 == 0);


    set_val(block, size);
}
Exemplo n.º 20
0
static int coalesce(void* block, size_t* size){
    REQUIRES(block != NULL);
    REQUIRES(in_heap(block));

    //uint64_t* left_block;
    void* right_block;
    size_t new_size;
    int index;

    void* next;
    void* prev;

    *size = block_size(block);
    new_size = (*size) * 2;
    index = get_free_list_index(*size);

    if(new_size > MAX_SIZE) return index;

    right_block = ((uint64_t*)block)+(block_size(block)/sizeof(uint64_t*));

    // if(in_heap(left_block) && block_free(left_block)){
    //     if(block_size(left_block) == size){
    //         set_size(left_block, size*2);
    //         add_block_to_list(get_free_list_index(size*2), left_block);
    //     }
    // }
    
    if(in_heap(right_block) && block_free((uint32_t*)right_block)){
        if(block_size(right_block) == new_size/2){

            next = block_next(right_block);
            prev = block_prev(right_block);

            if(free_lists[index] == right_block) free_lists[index] = next;
            if(prev != NULL) set_next_pointer(prev, next);
            if(next != NULL) set_prev_pointer(next, prev);

            set_size(block, new_size);
            *size = new_size;
            index++;
        }
    }
    return index;
}
Exemplo n.º 21
0
/*
 * Merge block with adjacent free blocks
 * Return: the pointer to the new free block 
 */
static void *coalesce(void *block) {
    REQUIRES(block != NULL);
    REQUIRES(in_heap(block));

    uint32_t *prev_block = block_prev(block);
    uint32_t *next_block = block_next(block);
    int prev_free = block_free(prev_block);
    int next_free = block_free(next_block);
    unsigned int words = block_size(block);
    

    if (prev_free && next_free) {       // Case 4, both free

        block_delete(prev_block);
        block_delete(next_block);

        words += block_size(prev_block) + block_size(next_block) + 4;
        set_size(prev_block, words);
        block_mark(prev_block, FREE);
        block = (void *)prev_block;

        block_insert(block);
        ENSURES(in_list(block));    
    }

    else if (!prev_free && next_free) { // Case 2, next if free

        block_delete(next_block);

        words += block_size(next_block) + 2;
        set_size(block, words);
        block_mark(block, FREE);  

        block_insert(block);
        ENSURES(in_list(block));      
    }

    else if (prev_free && !next_free) { // Case 3, prev is free
        block_delete(prev_block);

        words += block_size(prev_block) + 2;
        set_size(prev_block, words);
        block_mark(prev_block, FREE);
        block = (void *)prev_block;

        block_insert(block);
        ENSURES(in_list(block));
    }

    else {                              // Case 1, both unfree
        block_insert(block);
        ENSURES(in_list(block));
        return block;
    }
    return block;
 } 
Exemplo n.º 22
0
// set header and footer
static void *set_free_block(void *bp,size_t size,uint32_t alloc){
	
	REQUIRES(in_heap(bp));

	PUT((uint32_t *)bp,PACK((uint32_t)size,alloc));
	PUT((uint32_t *)bp+1,0);//pred addr
	PUT((uint32_t *)bp+2,0);//succ addr
	PUT(FTRP1(bp), PACK((uint32_t)size, alloc)); 
	return bp;
}
Exemplo n.º 23
0
static void add_block_to_list(int index, void* block){
    REQUIRES(0 <= index && index <= NUM_FREE_LISTS);
    REQUIRES(block != NULL);
    REQUIRES(in_heap(block));

    set_prev_pointer(block, NULL);
    set_next_pointer(block, free_lists[index]);

    if(free_lists[index] != NULL) set_prev_pointer(free_lists[index], block);
    free_lists[index] = block;
}
Exemplo n.º 24
0
// Insert the given free block into seg list according to its size
static inline void block_insert(uint32_t* block) {
    REQUIRES(block != NULL);
    REQUIRES(in_heap(block));

    int index = find_index(block_size(block));
    //printf("index = %d, size = %d\n", index, block_size(block));
    uint32_t *old_block = seg_list[index];

    if (old_block == NULL) { // this list is empty
        set_ptr(block, NULL, NULL);
        seg_list[index] = block;
    } else {                 // this list is not empty
        ENSURES(block_pred(old_block) == NULL);
        ENSURES(block_succ(old_block) == NULL || in_heap(block_succ(old_block)));

        set_ptr(old_block, block, block_succ(old_block));
        set_ptr(block, NULL, old_block);
        seg_list[index] = block;
    }
    ENSURES(in_list(block));
}
Exemplo n.º 25
0
void test_alloc_user() 
{
  byte *before, *after;
  User *u;
  before = heap_address();

  u = (User *) alloc(&User_type);
  after = heap_address();

  ASSERT(align(User_type.size), (after - before));
  ASSERT_TRUE(in_heap((Object *) u));
}
/*
 * free
 */
void free(void *ptr) {
    
    dbg_printf("=== FREE : 0x%lx\n",(size_t)ptr);
    
#if DEBUG
    if (NEXT_BLKP(ptr)) {
        if (!GET_PREV_ALLOC(GET_HEADER(NEXT_BLKP(ptr)))) {
            dbg_printf("0x%lx Fail to inform next block when malloc, or next block fail to update\n", (size_t)ptr);
            exit(3);
        }
    }
#endif
    
    if(!ptr) return;
    
    /* Debug */
    if(!in_heap(ptr)) {
        dbg_printf("ptr is not in heap!\n");
        
        mm_checkheap(63);
        exit(1);
    }
    if (!aligned(ptr)) {
        dbg_printf("ptr is not aligned!\n");
        
        mm_checkheap(63);
        exit(1);
    }
    
    size_t bsize = GET_SIZE(GET_HEADER(ptr));
    
    size_t flag = GET_PREV_ALLOC(GET_HEADER(ptr)) ? 0x2 : 0x0;
    PUT(GET_HEADER(ptr), PACK(bsize, flag));
    PUT(GET_FOOTER(ptr), PACK(bsize, flag));
    
    /* Inform the next block that this block is freed */
    char *nextbp = NEXT_BLKP(ptr);
    if (nextbp) {
        flag = GET(GET_HEADER(nextbp));
        flag &= ~0x2;
        PUT(GET_HEADER(nextbp), flag);
        /* Only put footer when next block is free */
        if (!GET_ALLOC(GET_HEADER(nextbp))) {
            PUT(GET_FOOTER(nextbp), flag);
        }
    }
    
    coalesce(ptr);
    
    mm_checkheap(CHECK_HEAP);
}
Exemplo n.º 27
0
static void *find_fit(size_t asize){
	
	void *bp;

	if (free_list==base)
		return NULL;
	
	for (bp=free_list;get_succ_offset(bp)!=0;bp=succ_blkp(bp)){
		if (GET_SIZE(bp)>=asize){
in_heap(bp);
			return bp;
}	}
	return NULL;
}
Exemplo n.º 28
0
/* addfreeblock*/
static void *add_free_block(void *bp){

	REQUIRES(in_heap(bp));

	set_succ(bp,get_offset(free_list));
	set_pred(bp,0);

	if (get_offset(free_list)!=0)
	set_pred(free_list,get_offset(bp));
	 
	//set new list header
	free_list=bp;
	return bp;
}
Exemplo n.º 29
0
void MultiTimeout::add_timeout_at(int64 key, double timeout) {
  LOG(DEBUG) << "Add timeout for " << key << " in " << timeout - Time::now();
  auto item = items_.emplace(key);
  auto heap_node = static_cast<HeapNode *>(const_cast<Item *>(&*item.first));
  if (heap_node->in_heap()) {
    CHECK(!item.second);
  } else {
    CHECK(item.second);
    timeout_queue_.insert(timeout, heap_node);
    if (heap_node->is_top()) {
      update_timeout();
    }
  }
}
Exemplo n.º 30
0
void MultiTimeout::cancel_timeout(int64 key) {
  LOG(DEBUG) << "Cancel timeout for " << key;
  auto item = items_.find(Item(key));
  if (item != items_.end()) {
    auto heap_node = static_cast<HeapNode *>(const_cast<Item *>(&*item));
    CHECK(heap_node->in_heap());
    bool need_update_timeout = heap_node->is_top();
    timeout_queue_.erase(heap_node);
    items_.erase(item);

    if (need_update_timeout) {
      update_timeout();
    }
  }
}