From: Michael D. Lowis Date: Wed, 1 Apr 2015 02:43:19 +0000 (-0400) Subject: Implemented heap allocation of small blocks X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=51428ed56c456cc7100f3871b36783b82f169f7f;p=archive%2Fatc.git Implemented heap allocation of small blocks --- diff --git a/source/runtime/heap.c b/source/runtime/heap.c index 3635053..2b4b095 100644 --- a/source/runtime/heap.c +++ b/source/runtime/heap.c @@ -1,24 +1,59 @@ /** @file heap.c @brief See header for details - $Revision$ - $HeadURL$ - */ +*/ #include "heap.h" +#include 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; +} + diff --git a/source/runtime/heap.h b/source/runtime/heap.h index 54b78e6..54ae442 100644 --- a/source/runtime/heap.h +++ b/source/runtime/heap.h @@ -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 */ diff --git a/source/runtime/segment.c b/source/runtime/segment.c index 429bcf9..5d3c8fa 100644 --- a/source/runtime/segment.c +++ b/source/runtime/segment.c @@ -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]); diff --git a/source/runtime/segment.h b/source/runtime/segment.h index 3b82e24..3c35b5c 100644 --- a/source/runtime/segment.h +++ b/source/runtime/segment.h @@ -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 */ diff --git a/tests/main.c b/tests/main.c index 1a33e6e..6cbdc83 100644 --- a/tests/main.c +++ b/tests/main.c @@ -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 index 0000000..83316e6 --- /dev/null +++ b/tests/test_heap.c @@ -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 + *************************************************************************/ +}