diff --git a/hw3/src/main.c b/hw3/src/main.c index 369b67a..6401ea0 100644 --- a/hw3/src/main.c +++ b/hw3/src/main.c @@ -3,5 +3,11 @@ int main(int argc, char const *argv[]) { + size_t sz_x = sizeof(int), sz_y = 10, sz_x1 = sizeof(int) * 20; + void *x = sf_malloc(sz_x); + /* void *y = */ sf_malloc(sz_y); + sf_realloc(x, sz_x1); + + sf_show_heap(); return EXIT_SUCCESS; } diff --git a/hw3/src/sfmm.c b/hw3/src/sfmm.c index 4901e26..a0fe8d6 100644 --- a/hw3/src/sfmm.c +++ b/hw3/src/sfmm.c @@ -140,6 +140,9 @@ void *sf_malloc(sf_size_t size) set_entire_header(last, size, get_block_size(last->header), 1, get_prv_alloc(last->header), 0, 0); set_entire_header(epi, 0, 0, 1, get_alloc(epi->prev_footer), 0, 1); + total_block_size += get_block_size(last->header); + add_payload(size); + return last->body.payload; } @@ -182,12 +185,15 @@ void *sf_realloc(void *pp, sf_size_t rsize) sf_size_t new_size = get_min_size(rsize); if (new_size > size) { + int payload = (int)get_payload_size(block->header); + add_payload(-1 * payload); sf_block *new; if ((new = sf_malloc(rsize)) == NULL) return NULL; new = (sf_block *)(((intptr_t) new) - 2 * sizeof(sf_header)); memcpy(new->body.payload, block->body.payload, size); sf_free(pp); + add_payload(payload); return new->body.payload; } else @@ -286,14 +292,14 @@ void set_header(sf_block *block, sf_header value) next->prev_footer = block->header; if ((prv_alloc & (sf_size_t)MAGIC) == 0) next->header = next->header & ~prv_alloc; - else + else next->header = next->header | prv_alloc; } else { if ((prv_alloc & (sf_size_t)MAGIC) == 0) next->header = next->header | prv_alloc; - else + else next->header = next->header & ~prv_alloc; } } diff --git a/hw3/tests/sfmm_tests.c b/hw3/tests/sfmm_tests.c index e680a71..9d2c513 100644 --- a/hw3/tests/sfmm_tests.c +++ b/hw3/tests/sfmm_tests.c @@ -95,6 +95,11 @@ Test(sfmm_basecode_suite, malloc_an_int, .timeout = TEST_TIMEOUT) cr_assert(sf_errno == 0, "sf_errno is not zero!"); cr_assert(sf_mem_start() + PAGE_SZ == sf_mem_end(), "Allocated more than necessary!"); + + cr_assert_eq(sf_internal_fragmentation(), 4 / 32.0, "Wrong number of sf_internal_fragmentation(): (exp=%f, found=%f)", + sf_internal_fragmentation(), 4 / 32.0); + cr_assert_eq(sf_peak_utilization(), 4 / 1024.0, "Wrong number of sf_peak_utilization(): (exp=%f, found=%f)", + sf_peak_utilization(), 4 / 1024.0); } Test(sfmm_basecode_suite, malloc_four_pages, .timeout = TEST_TIMEOUT) @@ -106,6 +111,11 @@ Test(sfmm_basecode_suite, malloc_four_pages, .timeout = TEST_TIMEOUT) assert_quick_list_block_count(0, 0); assert_free_block_count(0, 0); cr_assert(sf_errno == 0, "sf_errno is not 0!"); + + cr_assert_eq(sf_internal_fragmentation(), 4032 / 4048.0, "Wrong number of sf_internal_fragmentation(): (exp=%f, found=%f)", + sf_internal_fragmentation(), 4032 / 4048.0); + cr_assert_eq(sf_peak_utilization(), 4032 / 4096.0, "Wrong number of sf_peak_utilization(): (exp=%f, found=%f)", + sf_peak_utilization(), 4032 / 4096.0); } Test(sfmm_basecode_suite, malloc_too_large, .timeout = TEST_TIMEOUT) @@ -135,6 +145,10 @@ Test(sfmm_basecode_suite, free_quick, .timeout = TEST_TIMEOUT) assert_free_block_count(0, 1); assert_free_block_count(864, 1); cr_assert(sf_errno == 0, "sf_errno is not zero!"); + cr_assert_eq(sf_internal_fragmentation(), 9 / 64.0, "Wrong number of sf_internal_fragmentation(): (exp=%f, found=%f)", + sf_internal_fragmentation(), 9 / 64.0); + cr_assert_eq(sf_peak_utilization(), 41 / 1024.0, "Wrong number of sf_peak_utilization(): (exp=%f, found=%f)", + sf_peak_utilization(), 41 / 1024.0); } Test(sfmm_basecode_suite, free_no_coalesce, .timeout = TEST_TIMEOUT) @@ -153,6 +167,10 @@ Test(sfmm_basecode_suite, free_no_coalesce, .timeout = TEST_TIMEOUT) assert_free_block_count(704, 1); cr_assert(sf_errno == 0, "sf_errno is not zero!"); + cr_assert_eq(sf_internal_fragmentation(), 9 / 64.0, "Wrong number of sf_internal_fragmentation(): (exp=%f, found=%f)", + sf_internal_fragmentation(), 9 / 64.0); + cr_assert_eq(sf_peak_utilization(), 209 / 1024.0, "Wrong number of sf_peak_utilization(): (exp=%f, found=%f)", + sf_peak_utilization(), 209 / 1024.0); } Test(sfmm_basecode_suite, free_coalesce, .timeout = TEST_TIMEOUT) @@ -173,6 +191,10 @@ Test(sfmm_basecode_suite, free_coalesce, .timeout = TEST_TIMEOUT) assert_free_block_count(528, 1); cr_assert(sf_errno == 0, "sf_errno is not zero!"); + cr_assert_eq(sf_internal_fragmentation(), 12 / 64.0, "Wrong number of sf_internal_fragmentation(): (exp=%f, found=%f)", + sf_internal_fragmentation(), 12 / 64.0); + cr_assert_eq(sf_peak_utilization(), 512 / 1024.0, "Wrong number of sf_peak_utilization(): (exp=%f, found=%f)", + sf_peak_utilization(), 512 / 1024.0); } Test(sfmm_basecode_suite, freelist, .timeout = TEST_TIMEOUT) @@ -200,6 +222,10 @@ Test(sfmm_basecode_suite, freelist, .timeout = TEST_TIMEOUT) cr_assert_eq(&bp->header, (char *)y - 8, "Wrong first block in free list %d: (found=%p, exp=%p)", i, &bp->header, (char *)y - 8); + cr_assert_eq(sf_internal_fragmentation(), 550 / 592.0, "Wrong number of sf_internal_fragmentation(): (exp=%f, found=%f)", + sf_internal_fragmentation(), 550 / 592.0); + cr_assert_eq(sf_peak_utilization(), 1000 / 2048.0, "Wrong number of sf_peak_utilization(): (exp=%f, found=%f)", + sf_peak_utilization(), 1000 / 2048.0); } Test(sfmm_basecode_suite, realloc_larger_block, .timeout = TEST_TIMEOUT) @@ -223,6 +249,12 @@ Test(sfmm_basecode_suite, realloc_larger_block, .timeout = TEST_TIMEOUT) assert_quick_list_block_count(32, 1); assert_free_block_count(0, 1); assert_free_block_count(816, 1); + + cr_assert_eq(sf_internal_fragmentation(), 90 / 128.0, "Wrong number of sf_internal_fragmentation(): (exp=%f, found=%f)", + sf_internal_fragmentation(), 90 / 128.0); + cr_assert_eq(sf_peak_utilization(), 90 / 1024.0, "Wrong number of sf_peak_utilization(): (exp=%f, found=%f)", + sf_peak_utilization(), 90 / 1024.0); + } Test(sfmm_basecode_suite, realloc_smaller_block_splinter, .timeout = TEST_TIMEOUT) @@ -294,12 +326,12 @@ Test(sfmm_basecode_suite, quicklist1, .timeout = TEST_TIMEOUT) void *x5 = sf_malloc(sz_x); void *x6 = sf_malloc(sz_x); - sf_free(x1); - sf_free(x2); - sf_free(x3); - sf_free(x4); - sf_free(x5); - sf_free(x6); + sf_free(x1); + sf_free(x2); + sf_free(x3); + sf_free(x4); + sf_free(x5); + sf_free(x6); assert_quick_list_block_count(0, 1); assert_free_block_count(0, 2); @@ -324,16 +356,15 @@ Test(sfmm_basecode_suite, quicklist2, .timeout = TEST_TIMEOUT) void *x4 = sf_malloc(sz_x); void *x5 = sf_malloc(sz_x); - sf_free(x5); - sf_free(x4); - sf_free(x3); - sf_free(x2); - sf_free(x1); + sf_free(x5); + sf_free(x4); + sf_free(x3); + sf_free(x2); + sf_free(x1); assert_quick_list_block_count(0, 5); assert_free_block_count(0, 1); assert_free_block_count(816, 1); - // First block in list should be the most recently freed block not in quick list. int i = 0; @@ -343,24 +374,26 @@ Test(sfmm_basecode_suite, quicklist2, .timeout = TEST_TIMEOUT) i, &bp->header, (char *)x1 - 8); } -Test(sfmm_basecode_suite, realloc1, .timeout = TEST_TIMEOUT) { - char * x1 = sf_malloc(2000-8); - char * x2 = sf_malloc(10000-8); +Test(sfmm_basecode_suite, realloc1, .timeout = TEST_TIMEOUT) +{ + char *x1 = sf_malloc(2000 - 8); + char *x2 = sf_malloc(10000 - 8); sf_free(x1); - x2 = sf_realloc(x2, 12000-8); + x2 = sf_realloc(x2, 12000 - 8); assert_quick_list_block_count(0, 0); assert_free_block_count(0, 2); assert_free_block_count(12000, 1); assert_free_block_count(528, 1); } -Test(sfmm_basecode_suite, realloc2, .timeout = TEST_TIMEOUT) { - int *x1 = sf_malloc(sizeof(int)); - sf_malloc(sizeof(int)); - *x1 = 114514; - int *x3 = sf_realloc(x1, sizeof(double)); - x3 = sf_realloc(x1, sizeof(long)); - x3 = sf_realloc(x1, 24000); +Test(sfmm_basecode_suite, realloc2, .timeout = TEST_TIMEOUT) +{ + int *x1 = sf_malloc(sizeof(int)); + sf_malloc(sizeof(int)); + *x1 = 114514; + int *x3 = sf_realloc(x1, sizeof(double)); + x3 = sf_realloc(x1, sizeof(long)); + x3 = sf_realloc(x1, 24000); assert_quick_list_block_count(0, 1); assert_free_block_count(0, 1); @@ -371,12 +404,14 @@ Test(sfmm_basecode_suite, realloc2, .timeout = TEST_TIMEOUT) { 114514, (int)*x3); } -Test(sfmm_basecode_suite, freepro, .signal=SIGABRT, .timeout = TEST_TIMEOUT) { - sf_malloc(sizeof(int)); +Test(sfmm_basecode_suite, freepro, .signal = SIGABRT, .timeout = TEST_TIMEOUT) +{ + sf_malloc(sizeof(int)); sf_free(sf_mem_start()); } -Test(sfmm_basecode_suite, freeepi, .signal=SIGABRT, .timeout = TEST_TIMEOUT) { - sf_malloc(sizeof(int)); +Test(sfmm_basecode_suite, freeepi, .signal = SIGABRT, .timeout = TEST_TIMEOUT) +{ + sf_malloc(sizeof(int)); sf_free(((void *)(intptr_t)sf_mem_end()) - 2 * sizeof(sf_header)); } \ No newline at end of file