]> git.mdlowis.com Git - archive/atc.git/commitdiff
Implemented heap allocation of small blocks
authorMichael D. Lowis <mike@mdlowis.com>
Wed, 1 Apr 2015 02:43:19 +0000 (22:43 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Wed, 1 Apr 2015 02:43:19 +0000 (22:43 -0400)
source/runtime/heap.c
source/runtime/heap.h
source/runtime/segment.c
source/runtime/segment.h
tests/main.c
tests/test_heap.c [new file with mode: 0644]

index 3635053bfcf46423a1c33e2463dbbf0e855a536b..2b4b095674f8968a6d9b335ae051d741e98a02a7 100644 (file)
@@ -1,24 +1,59 @@
 /**
   @file heap.c
   @brief See header for details
-  $Revision$
-  $HeadURL$
-  */
+*/
 #include "heap.h"
+#include <stdlib.h>
 
 heap_t* heap_create(void)
 {
-    return NULL;
+    heap_t* heap = (heap_t*)calloc(1u, sizeof(heap_t));
+    return heap;
 }
 
 void heap_destroy(heap_t* heap)
 {
-    (void)heap;
+    int i;
+    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);
+        }
+    }
+    free(heap);
+}
+
+void* allocate_small_block(heap_t* heap, uintptr_t num_slots)
+{
+    uintptr_t index = num_slots - HEAP_INDEX_OFFSET;
+    printf("index: %d, %d\n", (unsigned int)index, (unsigned int)num_slots);
+    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;
+    }
+    return segment_alloc(heap->heaps[index]->segment);
 }
 
-void* heap_allocate(size_t block_size)
+void* allocate_large_block(heap_t* heap, uintptr_t num_slots)
 {
-    (void)block_size;
     return NULL;
 }
 
+void* heap_allocate(heap_t* heap, uintptr_t num_slots)
+{
+    void* obj = NULL;
+    if (num_slots <= MAX_NUM_SLOTS) {
+        obj = allocate_small_block(heap, num_slots);
+    } else {
+        obj = allocate_large_block(heap, num_slots);
+    }
+    return obj;
+}
+
index 54b78e67480b03063c8f243f1131a12049f8cc08..54ae44212ee4dc3e99889d7f8e2d19d288edccc1 100644 (file)
@@ -7,7 +7,13 @@
 
 #include "segment.h"
 
-#define NUM_HEAP_STACKS ((sizeof(uintptr_t) * 8u) - 3u)
+#define MIN_NUM_SLOTS (2u)
+
+#define MAX_NUM_SLOTS ((sizeof(uintptr_t)*8u) - 1u)
+
+#define HEAP_INDEX_OFFSET (MIN_NUM_SLOTS)
+
+#define NUM_HEAP_STACKS ((sizeof(uintptr_t) * 8u) - 1)
 
 typedef struct segnode_t {
     segment_t* segment;
@@ -16,16 +22,13 @@ typedef struct segnode_t {
 
 typedef struct {
     uintptr_t bytes_allocated;
-    struct {
-        segnode_t* first;
-        segnode_t* last;
-    } heaps[NUM_HEAP_STACKS];
+    segnode_t* heaps[NUM_HEAP_STACKS];
 } heap_t;
 
 heap_t* heap_create(void);
 
 void heap_destroy(heap_t* heap);
 
-void* heap_allocate(size_t block_size);
+void* heap_allocate(heap_t* heap, uintptr_t num_slots);
 
 #endif /* HEAP_H */
index 429bcf9699de030025e31fe57bc741a90dd1c221..5d3c8fab0ab70d413d1716c92be0f9c1c744e470 100644 (file)
@@ -30,10 +30,14 @@ void segment_destroy(segment_t* seg)
     free(seg);
 }
 
+bool segment_full(segment_t* seg) {
+    return (0u == seg->blockmap[0]);
+}
+
 void* segment_alloc(segment_t* seg) {
     void* obj = NULL;
     /* Check if the segment has any free blocks */
-    if (0u != seg->blockmap[0]) {
+    if (!segment_full(seg)) {
         /* Find the free block */
         uint8_t root_idx   = get_free_index(seg->blockmap[0]);
         uint8_t submap_idx = get_free_index(seg->blockmap[root_idx + 1]);
index 3b82e243a7df5acb1b99badeb4c58730065ac8e0..3c35b5cc49832a8890209ac1268918a0fab0a40e 100644 (file)
@@ -23,6 +23,8 @@ segment_t* segment_create(uintptr_t blocksize);
 
 void segment_destroy(segment_t* seg);
 
+bool segment_full(segment_t* seg);
+
 void* segment_alloc(segment_t* seg);
 
 #endif /* SEGMENT_H */
index 1a33e6e9fbfba2d3a0f1f4b9acb0684f6e89f946..6cbdc83acec69a74c54049b7aa7bc83f84f5bed7 100644 (file)
@@ -5,5 +5,6 @@ int ATC_Main(int argc, char** argv) {
     (void)argv;
     RUN_EXTERN_TEST_SUITE(SplayTree);
     RUN_EXTERN_TEST_SUITE(Segment);
+    RUN_EXTERN_TEST_SUITE(Heap);
     return PRINT_TEST_RESULTS();
 }
diff --git a/tests/test_heap.c b/tests/test_heap.c
new file mode 100644 (file)
index 0000000..83316e6
--- /dev/null
@@ -0,0 +1,17 @@
+#include "atf.h"
+#include "heap.h"
+
+TEST_SUITE(Heap) {
+    /* Verify: heap_create
+     *************************************************************************/
+    TEST(Verify_Create_allocates_and_initializes_a_heap) {
+        heap_t* heap = heap_create();
+        CHECK(heap != NULL);
+
+        CHECK(NULL != heap_allocate(heap, 63));
+        heap_destroy(heap);
+    }
+
+    /* Verify: segment_alloc
+     *************************************************************************/
+}