]> git.mdlowis.com Git - archive/atc.git/commitdiff
Coalesced segment related mallocs
authorMichael D. Lowis <mike@mdlowis.com>
Thu, 2 Apr 2015 01:14:15 +0000 (21:14 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Thu, 2 Apr 2015 01:14:15 +0000 (21:14 -0400)
source/runtime/heap.c
source/runtime/heap.h
source/runtime/segment.c
source/runtime/segment.h
tests/test_heap.c
tests/test_segment.c

index 5c64b64f84cd4b322998afcef7324dcf451b9363..27577259cb0005dc489c5facee36b4ca92bd0019 100644 (file)
@@ -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)
index 926b6bfcfb55b016bd576f0dc92a64c7568614aa..b88dda8efbf83f06a54bb65fff25df3ef39a021d 100644 (file)
 
 #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;
 
index 5d3c8fab0ab70d413d1716c92be0f9c1c744e470..625ea037274cbc6c83644fc192843b392c46d9c7 100644 (file)
@@ -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) {
index 86afffa2ec9e2f7387f4281f189878bcfeab8851..623855d8b9aa94e14f6f95bf47855ca62ae396eb 100644 (file)
 
 #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);
 
index 5087d70ef2da628c90668c38fd45d762acf1380c..347cbc5532536e97a9d32b2fee380be0a6b8b12a 100644 (file)
@@ -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);
     }
 
index b1fbbe566c37844c5afbc9e62b2681b8c196c88f..f0e01ac92a1db6cf638902eb5d2a0002215e8823 100644 (file)
@@ -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);