Beispiel #1
0
void free_random() {
    void *heap0 = get_heap_base();
    Free_Header *freelist0 = get_heap_freelist();

    free(buf); // try to free a valid but non-heap data address

    void *heap1 = get_heap_base();
    Free_Header *freelist1 = get_heap_freelist();

    assert_addr_equal(heap1, heap0);
    assert_addr_equal(freelist1, freelist0);
}
Beispiel #2
0
void malloc_large_size_then_free() {
    Free_Header *freelist = get_heap_freelist();//free list before malloc
    void *p = malloc(2048);
    assert_addr_not_equal(p, NULL);
    assert_equal(chunksize(p), request2size(2048));
    Free_Header *freelist1 = get_heap_freelist(); // free list after malloc
    Busy_Header *heap = get_heap_base();
    assert_addr_equal(p,heap);
    assert_addr_not_equal(heap,freelist1);
    free(p);
    Busy_Header *heap1 = get_heap_base();
    Free_Header *freelist2 = get_heap_freelist(); // free list after free,should back to status before malloc
    assert_addr_equal(freelist,freelist2);
    assert_addr_equal(heap1,freelist2);
}
Beispiel #3
0
void long_freelist() {
    Busy_Header* b[20];
    for(int i = 0; i < 20; i++){
        b[i] = malloc(i);
        assert_addr_equal(get_freelist(), find_next(b[i]));
        assert_addr_equal(get_freelist()->prev, NULL);
    }


    Free_Header *freelist0 = get_freelist();
    for( int i = 0; i <20 ; i++){
        free(b[i]);
        assert_addr_equal(get_freelist(), b[i]);
        if (i+1 < 20)
            assert_addr_equal(find_next(get_freelist()), b[i+1]);
        assert_addr_equal(get_freelist()->prev, NULL);

    }
    //last free causes a merge
    Heap_Info info = verify_heap();
    assert_equal(info.busy, 0);
    assert_equal(info.free, 20);
    assert_equal(info.busy_size + info.free_size, get_heap_info().heap_size); // out of heap
    assert_addr_equal(get_freelist(), b[19]);
    assert_addr_equal(find_next(get_freelist()), get_heap_base() + info.heap_size); //out of heap
    assert_addr_equal(((Free_Header *)b[0])->next, NULL); //end

}
Beispiel #4
0
//free the first chunk, then free last chunk to merge with the end of free list
void merge_with_end() {
    three_malloc();
    Busy_Header *b_1 = get_heap_base();
    Busy_Header *b_2 = find_next(b_1);
    Busy_Header *b_3 = find_next(b_2);

    free(b_1);   //free the first chunk
    Free_Header *freelist0 = get_freelist();  //get the new freelist
    assert_addr_equal(freelist0, b_1);
    assert_addr_equal(freelist0->next, find_next(b_3));

    free(b_3);  //free the last chunk, merge
    Free_Header *freelist1 = get_freelist();
    assert_addr_equal(freelist1, b_3);
    assert_addr_equal(freelist1->next, b_1);
    assert_addr_equal(freelist1->prev, NULL);
    assert_addr_equal(freelist1->next->prev, freelist1);
    assert_addr_equal(freelist1->next->next, NULL);

    Heap_Info info = verify_heap();
    assert_equal(info.busy, 1);
    assert_equal(info.free, 2);
    assert_equal(info.free_size, HEAP_SIZE - info.busy_size);
    assert_equal(freelist1->next->size, b_1->size);
    assert_equal(find_next(find_next(b_1)), freelist1);
}
Beispiel #5
0
//five consecutive chunks allocated
void  five_malloc() {
    void *p = get_heap_base();
    Busy_Header *b_1 = malloc(100);
    assert_addr_equal(b_1, p);   //b_1 is at the start of heap
    assert_equal(chunksize(b_1), request2size(100));
    Busy_Header *b_2 = malloc(200);
    Busy_Header *b1_next = find_next(b_1);
    assert_addr_equal(b1_next,b_2);     //b_2 is after b_1
    assert_equal(chunksize(b_2), request2size(200));
    Busy_Header *b_3 = malloc(300);
    Busy_Header *b2_next = find_next(b_2);
    assert_addr_equal(find_next(b_2),b_3);     //b_3 is after b_2
    assert_equal(chunksize(b_3), request2size(300));
    Busy_Header *b_4 = malloc(400);
    Busy_Header *b3_next = find_next(b_3);
    assert_addr_equal(find_next(b_3),b_4);     //b_4 is after b_3
    assert_equal(chunksize(b_4), request2size(400));
    Busy_Header *b_5 = malloc(500);
    Busy_Header *b4_next = find_next(b_4);
    assert_addr_equal(find_next(b_4),b_5);     //b_5 is after b_4
    assert_equal(chunksize(b_5), request2size(500));

    Heap_Info info = verify_heap();
    assert_equal(info.busy, 5);
    assert_equal(info.free, 1);
    assert_equal(info.free_size, HEAP_SIZE - info.busy_size);
}
Beispiel #6
0
//free the middle chunk, than the first chunk, leading to a merge with the head of the list
void merge_with_head() {
	free_without_merging(); //free middle chunk first

	void *p = get_heap_base(); // the first allocated chunk on the heap
	Free_Header *freelist0 = get_freelist(); //get the head of freelist, which is the middle chunk
    assert_addr_not_equal(freelist0, p);
    Free_Header *next = freelist0->next;
    free(p);   //free the chunk before head of the free list, need to merge
	Free_Header *freelist1 = get_freelist();  //get the new freelist

	assert_addr_equal(freelist1, p); // new head is at the base of heap
	assert_addr_not_equal(freelist1, freelist0);
	assert_addr_not_equal(freelist1->next, freelist0);
    assert_addr_equal(freelist1->next, next);
    assert_addr_equal(freelist1->prev, NULL);
    assert_addr_equal(next->next, NULL);
    assert_addr_equal(next->prev, freelist1);

	Heap_Info info = verify_heap();
	assert_equal(info.busy, 1);
	assert_equal(info.free, 2);
	assert_equal(info.free_size, HEAP_SIZE - info.busy_size);
	assert_equal(freelist1->next->size, info.free_size-freelist1->size);
    assert_equal(find_next(find_next(freelist1)), freelist1->next);
}
Beispiel #7
0
/*
* for each free request
* if chunk size over 1024, free it and add to free list (sorted)
* other wise add to bin[chunk_size-1]
*/
void free(void *p) {
    if (p == NULL) return;
    void *start_of_heap = get_heap_base();
    void *end_of_heap = start_of_heap + DEFAULT_MAX_HEAP_SIZE - 1; // last valid address of heap
    if ( p<start_of_heap || p>end_of_heap ) {
#ifdef DEBUG
        fprintf(stderr, "free of non-heap address %p\n", p);
#endif
        return;
    }
    Free_Header *q = (Free_Header *) p;
    if ( !(q->size & BUSY_BIT) ) { // stale pointer? If already free'd better not try to free it again
#ifdef DEBUG
        fprintf(stderr, "free of stale pointer %p\n", p);
#endif
        return;
    }
    q->size &= SIZEMASK;
    if (q->size<= BIN_SIZE) {
        q->next = bin[q->size-1];
        bin[q->size-1] = q;
    }
    else {
        q->next = freelist;
        freelist = q;
    }
}
Beispiel #8
0
void bin_malloc_free_malloc() {  // test bin malloc and free
    void *p = malloc(99); // should split heap into two chunks
    assert_addr_not_equal(p, NULL);
    Free_Header *freelist = get_heap_freelist();
    Busy_Header *heap = get_heap_base();
    assert_addr_not_equal(freelist, heap);
    // check 1st chunk
    assert_equal(p, heap);
    assert_equal(chunksize(p), request2size(99));
    // check 2nd chunk
    assert_equal(freelist->size, HEAP_SIZE-request2size(99));
    assert_addr_equal(freelist->next, NULL);

    Free_Header *freelist1 = get_bin_freelist(99);// freelist of bin should be NULL
    free(p);                                                       // free to bin
    Free_Header *freelist2 = get_bin_freelist(99);// freelist of bin should be have one element p
    assert_addr_not_equal(freelist1,freelist2);
    void *p1 = malloc(99);                                        // this malloc should be from bin
    assert_addr_not_equal(p1, NULL);
    Free_Header *freelist3 = get_bin_freelist(99); // freelist of bin should be NULL
    assert_addr_equal(freelist3,NULL);

    free(p1);
    Free_Header *freelist4 = get_bin_freelist(99); // freelist should have one element p1
    assert_addr_equal(freelist2,freelist4);
}
Beispiel #9
0
void malloc_then_free() {
	one_malloc();
	void *p = get_heap_base(); // should be allocated chunk
	Free_Header *freelist0 = get_freelist();
	free(p);
	Free_Header *freelist1 = get_freelist();
	// allocated chunk is freed and becomes head of new freelist
	assert_addr_equal(freelist1, p);
	assert_addr_equal(freelist1, get_heap_base());
	assert_addr_not_equal(freelist0, freelist1);
	assert_equal(chunksize(freelist1) + chunksize(freelist1->next), HEAP_SIZE);
	Heap_Info info = verify_heap();
	assert_equal(info.busy, 0);
	assert_equal(info.busy_size, 0);
	assert_equal(info.free, 1); // 1 free chunk after merging
	assert_equal(info.free_size, HEAP_SIZE);
}
Beispiel #10
0
void two_malloc() {
    one_malloc();
    void *p0 = get_heap_base();
    Free_Header *freelist0 = get_heap_freelist();
    Busy_Header *p = malloc(200);
    assert_addr_not_equal(p, NULL);
    // check 2nd alloc chunk
    assert_equal(p, freelist0); // should return previous free chunk
    assert_equal(chunksize(p), request2size(200));
    // check remaining free chunk
    Free_Header *freelist1 = get_heap_freelist();
    assert_addr_not_equal(freelist0, freelist1);
    assert_addr_not_equal(freelist0, get_heap_base());
    assert_equal(chunksize(freelist1), HEAP_SIZE-request2size(100)-request2size(200));
    assert_equal(chunksize(p0)+chunksize(p)+chunksize(freelist1), HEAP_SIZE);
    assert_addr_equal(freelist1->next, NULL);

    Heap_Info info = verify_heap();
    assert_equal(info.busy, 2);
    assert_equal(info.busy_size, request2size(100) + request2size(200));
    assert_equal(info.free, 1);
    assert_equal(info.free_size, HEAP_SIZE - request2size(100) - request2size(200));
}
Beispiel #11
0
void one_malloc() {
    void *p = malloc(100);
    assert_addr_not_equal(p, NULL);
    Free_Header *freelist = get_heap_freelist();
    Busy_Header *heap = get_heap_base();
    assert_addr_not_equal(freelist, heap);
    // check 1st chunk
    assert_equal(p, heap);
    assert_equal(chunksize(p), request2size(100));
    // check 2nd chunk
    assert_equal(freelist->size, HEAP_SIZE-request2size(100));
    assert_addr_equal(freelist->next, NULL);

    Heap_Info info = verify_heap();
    assert_equal(info.busy, 1);
    assert_equal(info.busy_size, request2size(100));
    assert_equal(info.free, 1);
    assert_equal(info.free_size, HEAP_SIZE - request2size(100));
}
Beispiel #12
0
//allocate 10 consecutive chunks, free from the back to the front
//should fuse the heap to one free chunk
void fuse_to_one() {
    Busy_Header* b[10];
    for(int i = 0; i < 10; i++){
        b[i] = malloc(100);
        assert_addr_equal(get_freelist(), find_next(b[i]));
        assert_addr_equal(get_freelist()->prev, NULL);
    }
    Free_Header *freelist0 = get_freelist();
    for( int i = 9; i >= 0 ; i--){
        free(b[i]);
        assert_addr_equal(get_freelist(), b[i]);
        assert_addr_equal(get_freelist()->prev, NULL);
    }
    Heap_Info info = verify_heap();
    assert_equal(info.busy, 0);
    assert_equal(info.free, 1);
    assert_equal(info.busy_size + info.free_size, get_heap_info().heap_size);
    assert_addr_equal(find_next(get_freelist()), get_heap_base() + info.heap_size);
    assert_addr_equal(freelist0->next, NULL);
}
Beispiel #13
0
//free the first chunk, then free last chunk to merge with the end of free list
void merge_with_middle() {
    five_malloc();
    Busy_Header *b_1 = get_heap_base();
    Busy_Header *b_2 = find_next(b_1);
    Busy_Header *b_3 = find_next(b_2);
    Busy_Header *b_4 = find_next(b_3);
    Busy_Header *b_5 = find_next(b_4);

    size_t size_3 = b_3->size & SIZEMASK;
    size_t size_4 = b_4->size & SIZEMASK;

    free(b_4);
    free(b_2);
    Free_Header *freelist0 = get_freelist();  //get the new freelist at b_2->b_4->after b_5
    Free_Header *last = find_next(b_5);
    assert_addr_equal(freelist0, b_2);
    assert_addr_equal(freelist0->next, b_4);
    assert_addr_equal(freelist0->prev, NULL);
    assert_addr_equal(((Free_Header*)b_4) ->next, last);
    assert_addr_equal(((Free_Header*)b_4) ->prev, b_2);
    assert_addr_equal(last->next, NULL);
    assert_addr_equal(last->prev, b_4);

    free(b_3); //merge with b_4
    Free_Header *freelist1 = get_freelist(); //get new free list at b_3;
    assert_addr_equal(freelist1, b_3);
    assert_equal(freelist1->size & SIZEMASK, size_3 + size_4);

    assert_addr_equal(freelist1->next, b_2); //freelist1 ->freelist0->last
    assert_addr_equal(freelist1->prev, NULL);
    assert_addr_equal(freelist0->next, last);
    assert_addr_equal(freelist0->prev, freelist1);
    assert_addr_equal(last->next, NULL);
    assert_addr_equal(last->prev, freelist0);

    Heap_Info info = verify_heap();
    assert_equal(info.busy, 2);
    assert_equal(info.free, 3);
    assert_equal(info.free_size, HEAP_SIZE - info.busy_size);
    assert_equal(freelist1->next->size + freelist0->next->size, info.free_size-freelist1->size);
}
Beispiel #14
0
/* Free chunk p by adding to head of free list */
void free(void *p) {
	if (p == NULL) return;
	void *start_of_heap = get_heap_base();
	void *end_of_heap = start_of_heap + heap_size - 1; // last valid address of heap
	if ( p<start_of_heap || p>end_of_heap ) {
#ifdef DEBUG
		fprintf(stderr, "free of non-heap address %p\n", p);
#endif
		return;
	}
	Free_Header *q = (Free_Header *) p;
	if ( !(q->size & BUSY_BIT) ) { // stale pointer? If already free'd better not try to free it again
#ifdef DEBUG
		fprintf(stderr, "free of stale pointer %p\n", p);
#endif
		return;
	}
	q->next = freelist;
	q->size &= SIZEMASK; // turn off busy bit
	freelist = q;
}
Beispiel #15
0
/* Walk heap jumping by size field of chunk header. Return an info record. */
Heap_Info get_heap_info() {
	void *heap = get_heap_base();			  // should be allocated chunk
	void *end_of_heap = heap + heap_size - 1; // last valid address of heap
	Busy_Header *p = heap;
	uint32_t busy = 0;
	uint32_t free = 0;
	uint32_t busy_size = 0;
	uint32_t free_size = 0;
	while ( (void*)p>=heap && (void*)p<=end_of_heap ) { // stay inbounds, walking heap
		// track
		if ( p->size & BUSY_BIT ) {
			busy++;
			busy_size += chunksize(p);
		}
		else {
			free++;
			free_size += chunksize(p);
		}
		p = (Busy_Header *)((char *) p + chunksize(p));
	}
	return (Heap_Info){heap_size, busy, busy_size, free, free_size};
}
Beispiel #16
0
Heap_Info get_heap_info() {
    void *heap = get_heap_base();
    void *end_of_heap = heap + DEFAULT_MAX_HEAP_SIZE - 1;
    Busy_Header *p = heap;
    uint32_t busy = 0;
    uint32_t free = 0;
    uint32_t busy_size = 0;
    uint32_t free_size = 0;
    while ( p >= heap && p <= end_of_heap ) {
        if ( p->size & BUSY_BIT ) {
            busy++;
            busy_size += chunksize(p);
        }
        else {
            free++;
            free_size += chunksize(p);
        }
        p = (Busy_Header *)((char *) p + chunksize(p));
    }
    return (Heap_Info) {
        DEFAULT_MAX_HEAP_SIZE, busy, busy_size, free, free_size
    };
}
Beispiel #17
0
//free the chunk in the middle of three busy chunks
void free_without_merging() {
	three_malloc();
    Busy_Header *b_1 = get_heap_base();
    Busy_Header *b_2 = find_next(b_1);
    Busy_Header *b_3 = find_next(b_2);

	Free_Header *freelist0 = get_freelist(); //get the head of freelist, which is at the end of allocated chunks
	assert_addr_equal(freelist0, find_next(b_3));
	free(b_2);   //free the chunk in the middle, which becomes the head of the new freelist
	Free_Header *freelist1 = get_freelist();  //get the new freelist

	assert_addr_not_equal(freelist1, b_1);
	assert_addr_not_equal(freelist0, freelist1);
    assert_addr_equal(freelist1, b_2);
    assert_addr_equal(freelist1->next, freelist0); //two free chunks in the list
    assert_equal(chunksize(b_1) + chunksize(b_2) + chunksize(b_3) + chunksize(freelist0), HEAP_SIZE);
    assert_equal(chunksize(b_1) + chunksize(b_3) + chunksize(freelist1) + chunksize(freelist0), HEAP_SIZE);

	Heap_Info info = verify_heap();
	assert_equal(info.busy, 2);
	assert_equal(info.busy_size, chunksize(b_1) + chunksize(b_3));
	assert_equal(info.free, 2); // 2 free chunks not next to each other
	assert_equal(info.free_size, chunksize(freelist1) + chunksize(freelist1->next));
}
Beispiel #18
0
void test_init_shutdown() {
	freelist_init(HEAP_SIZE);
	assert_addr_equal(get_freelist(), get_heap_base());
	freelist_shutdown();
}
Beispiel #19
0
//split chunk
void split_chunk(){
    printf("after allocation:\n");
    Busy_Header* b[4];
    for(int i = 0; i < 4; i++){
        b[i] = malloc(450);
        printf("b[%d]: %p\n", i, b[i]);
    }
    assert_equal(b[0]->size & SIZEMASK, request2size(450));
    assert_equal(b[1]->size & SIZEMASK, request2size(450));
    assert_equal(b[2]->size & SIZEMASK, request2size(450));
    assert_equal(b[3]->size & SIZEMASK, request2size(450));
    Free_Header* f4 = find_next(b[3]);
    printf("head: %p\n", f4);

    Heap_Info info = verify_heap();
    assert_equal(info.busy, 4);
    assert_equal(info.free, 1);
    assert_equal(info.busy_size, 1824);
    assert_equal(info.free_size, 176);
    assert_addr_equal(get_freelist(), f4);
    assert_addr_equal(get_freelist()->next, NULL);
    assert_addr_equal(get_freelist()->prev, NULL);

    free(b[2]);

    info = verify_heap();
    assert_equal(info.busy, 3);
    assert_equal(info.free, 2);
    assert_equal(info.busy_size, 1368);
    assert_equal(info.free_size, 632);
    assert_addr_equal(get_freelist(), b[2]);
    assert_addr_equal(get_freelist()->next, f4);
    assert_addr_equal(get_freelist()->next->next, NULL);
    assert_addr_equal(f4->prev, b[2]);
    assert_addr_equal(f4->prev->prev, NULL);
    printf("after free b[2]\n");
    Free_Header *head = get_freelist();
    print_both_ways(head);


    free(b[0]);
    info = verify_heap();
    assert_equal(info.busy, 2);
    assert_equal(info.free, 3);
    assert_equal(info.busy_size, 912);
    assert_equal(info.free_size, 1088);
    assert_addr_equal(get_freelist(), b[0]);
    assert_addr_equal(get_freelist()->next, b[2]);
    assert_addr_equal(get_freelist()->next->next, f4);
    assert_addr_equal(get_freelist()->next->next->next, NULL);
    assert_addr_equal(f4->prev, b[2]);
    assert_addr_equal(f4->prev->prev, b[0]);
    assert_addr_equal(f4->prev->prev->prev, NULL);

    printf("after free b[0]\n");
    head = get_freelist();
    print_both_ways(head);

    Busy_Header *split = malloc(200);

    printf("after malloc(200)\n");
    head = get_freelist();
    print_both_ways(head);

    assert_addr_equal(split, get_heap_base());
    Free_Header *newhead = get_freelist();
    assert_addr_equal(find_next(split),newhead);
    assert_addr_equal(get_freelist(), find_next(split));
    assert_addr_equal(get_freelist()->next, b[2]);
    assert_addr_equal(get_freelist()->next->next, f4);
    assert_addr_equal(get_freelist()->next->next->next, NULL);
    assert_addr_equal(f4->prev, b[2]);
    assert_addr_equal(f4->prev->prev, newhead);
    assert_addr_equal(f4->prev->prev->prev, NULL);
    info = verify_heap();
    assert_equal(info.busy, 3);
    assert_equal(info.free, 3);
    assert_equal(info.busy_size + info.free_size, get_heap_info().heap_size); // out of heap*/
}