From: Michael D. Lowis Date: Thu, 2 Apr 2015 01:14:15 +0000 (-0400) Subject: Coalesced segment related mallocs X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=8b428d51cb843ac7ddecae1f9c284fb79009b546;p=archive%2Fatc.git Coalesced segment related mallocs --- diff --git a/source/runtime/heap.c b/source/runtime/heap.c index 5c64b64..2757725 100644 --- a/source/runtime/heap.c +++ b/source/runtime/heap.c @@ -17,18 +17,12 @@ void heap_destroy(heap_t* heap) /* Free all the large blocks */ while (NULL != current) { block_t* deadite = current; - current = deadite->next; + current = current->next; free(deadite); } /* Free all of the small block segments */ for (i = 0; i < NUM_HEAP_STACKS; i++) { - segnode_t* curr = heap->heaps[i]; - while (NULL != curr) { - segnode_t* deadite = curr; - curr = deadite->next; - segment_destroy(deadite->segment); - free(deadite); - } + segment_destroy(heap->heaps[i]); } /* Free the heap itself */ free(heap); @@ -37,15 +31,11 @@ void heap_destroy(heap_t* heap) static void* allocate_small_block(heap_t* heap, uintptr_t num_slots) { uintptr_t index = (num_slots >= MIN_NUM_SLOTS) ? (num_slots - HEAP_INDEX_OFFSET) : 0; - segnode_t* node = heap->heaps[index]; - if ((NULL == node) || segment_full(node->segment)) { - segnode_t* newnode = (segnode_t*)malloc(sizeof(segnode_t)); - newnode->segment = segment_create(num_slots); - newnode->next = node; - heap->heaps[index] = newnode; - node = newnode; + segment_t* current = heap->heaps[index]; + if ((NULL == current) || segment_full(current)) { + heap->heaps[index] = segment_create(num_slots, current); } - return segment_alloc(heap->heaps[index]->segment); + return segment_alloc(heap->heaps[index]); } static void* allocate_large_block(heap_t* heap, uintptr_t num_slots) diff --git a/source/runtime/heap.h b/source/runtime/heap.h index 926b6bf..b88dda8 100644 --- a/source/runtime/heap.h +++ b/source/runtime/heap.h @@ -15,18 +15,13 @@ #define NUM_HEAP_STACKS (MAX_NUM_SLOTS) -typedef struct segnode_t { - segment_t* segment; - struct segnode_t* next; -} segnode_t; - typedef struct block_t { struct block_t* next; uintptr_t data[]; } block_t; typedef struct { - segnode_t* heaps[NUM_HEAP_STACKS]; + segment_t* heaps[NUM_HEAP_STACKS]; block_t* blocks; } heap_t; diff --git a/source/runtime/segment.c b/source/runtime/segment.c index 5d3c8fa..625ea03 100644 --- a/source/runtime/segment.c +++ b/source/runtime/segment.c @@ -14,20 +14,25 @@ static uint8_t get_free_index(int32_t bitmap) { return lookup[((uint32_t)((bitmap & -bitmap) * 0x077CB531U)) >> 27]; } -segment_t* segment_create(uintptr_t blocksize) +segment_t* segment_create(uintptr_t num_slots, segment_t* next) { - segment_t* seg = (segment_t*)malloc(sizeof(segment_t)); - seg->blocksize = blocksize; - seg->start = (uintptr_t*)malloc(sizeof(uintptr_t) * blocksize * NUM_BLOCKS); - seg->end = (seg->start + (blocksize * NUM_BLOCKS)); + size_t segsize = sizeof(uintptr_t) * num_slots * NUM_BLOCKS; + segment_t* seg = (segment_t*)malloc(sizeof(segment_t) + segsize); + seg->next = next; + seg->blocksize = num_slots; + seg->end = (seg->start + (num_slots * NUM_BLOCKS)); memset(seg->blockmap, 0xFFu, sizeof(seg->blockmap)); return seg; } void segment_destroy(segment_t* seg) { - free(seg->start); - free(seg); + segment_t* curr = seg; + while (NULL != curr) { + segment_t* deadite = curr; + curr = curr->next; + free(deadite); + } } bool segment_full(segment_t* seg) { diff --git a/source/runtime/segment.h b/source/runtime/segment.h index 86afffa..623855d 100644 --- a/source/runtime/segment.h +++ b/source/runtime/segment.h @@ -12,14 +12,15 @@ #define BLOCKMAP_SIZE ((sizeof(uint16_t) * 8) + 1) -typedef struct { +typedef struct segment_t { + struct segment_t* next; uintptr_t blocksize; - uintptr_t* start; - uintptr_t* end; uint16_t blockmap[BLOCKMAP_SIZE]; + uintptr_t* end; + uintptr_t start[]; } segment_t; -segment_t* segment_create(uintptr_t blocksize); +segment_t* segment_create(uintptr_t blocksize, segment_t* next); void segment_destroy(segment_t* seg); diff --git a/tests/test_heap.c b/tests/test_heap.c index 5087d70..347cbc5 100644 --- a/tests/test_heap.c +++ b/tests/test_heap.c @@ -23,14 +23,14 @@ TEST_SUITE(Heap) { TEST(Verify_Allocate_should_allocate_a_new_segment_if_the_current_segment_is_full) { heap_t* heap = heap_create(); - segnode_t* prev_seg_node; + segment_t* prev; CHECK(NULL != heap_allocate(heap, 1)); CHECK(heap->heaps[0] != NULL); - prev_seg_node = heap->heaps[0]; - prev_seg_node->segment->blockmap[0] = 0; + prev = heap->heaps[0]; + prev->blockmap[0] = 0; CHECK(NULL != heap_allocate(heap, 1)); - CHECK(heap->heaps[0] != prev_seg_node); - CHECK(heap->heaps[0]->next == prev_seg_node); + CHECK(heap->heaps[0] != prev); + CHECK(heap->heaps[0]->next == prev); heap_destroy(heap); } diff --git a/tests/test_segment.c b/tests/test_segment.c index b1fbbe5..f0e01ac 100644 --- a/tests/test_segment.c +++ b/tests/test_segment.c @@ -6,7 +6,7 @@ TEST_SUITE(Segment) { *************************************************************************/ TEST(Verify_Create_allocates_and_initializes_a_segment) { int i; - segment_t* seg = segment_create(2u); + segment_t* seg = segment_create(2u, NULL); CHECK(seg->blocksize == 2u); CHECK(seg->start != NULL); CHECK(seg->end == (seg->start + (NUM_BLOCKS * 2u))); @@ -18,14 +18,14 @@ TEST_SUITE(Segment) { /* Verify: segment_alloc *************************************************************************/ TEST(Verify_alloc_allocates_the_first_block) { - segment_t* seg = segment_create(2u); + segment_t* seg = segment_create(2u, NULL); void* obj = segment_alloc(seg); CHECK(obj == seg->start); segment_destroy(seg); } TEST(Verify_alloc_allocates_the_second_block) { - segment_t* seg = segment_create(2u); + segment_t* seg = segment_create(2u, NULL); seg->blockmap[1] = UINT16_MAX-1; void* obj = segment_alloc(seg); CHECK(obj == &seg->start[2]); @@ -33,7 +33,7 @@ TEST_SUITE(Segment) { } TEST(Verify_alloc_allocates_the_sixteenth_block) { - segment_t* seg = segment_create(2u); + segment_t* seg = segment_create(2u, NULL); seg->blockmap[0] = UINT16_MAX-1; seg->blockmap[1] = 0u; void* obj = segment_alloc(seg); @@ -42,7 +42,7 @@ TEST_SUITE(Segment) { } TEST(Verify_alloc_allocates_blocks_consecutively) { - segment_t* seg = segment_create(2u); + segment_t* seg = segment_create(2u, NULL); void* obj1 = segment_alloc(seg); void* obj2 = segment_alloc(seg); void* obj3 = segment_alloc(seg); @@ -55,7 +55,7 @@ TEST_SUITE(Segment) { } TEST(Verify_alloc_allocates_blocks_consecutively_across_bitmap_boundaries) { - segment_t* seg = segment_create(2u); + segment_t* seg = segment_create(2u, NULL); seg->blockmap[1] = 1 << 15; void* obj1 = segment_alloc(seg); void* obj2 = segment_alloc(seg); @@ -68,7 +68,7 @@ TEST_SUITE(Segment) { } TEST(Verify_alloc_returns_NULL_if_no_blocks_available) { - segment_t* seg = segment_create(2u); + segment_t* seg = segment_create(2u, NULL); seg->blockmap[0] = 0; void* obj = segment_alloc(seg); CHECK(obj == NULL);