diff options
-rw-r--r-- | include/kern/mem.h | 12 | ||||
-rw-r--r-- | src/kern/mem.c | 124 | ||||
-rw-r--r-- | tests/test_memory.c | 138 |
3 files changed, 137 insertions, 137 deletions
diff --git a/include/kern/mem.h b/include/kern/mem.h index c0999f5..832d31d 100644 --- a/include/kern/mem.h +++ b/include/kern/mem.h @@ -11,18 +11,18 @@ ((16384 - (DATA_SEGMENT_STOP_ADDR - DATA_SEGMENT_START_ADDR)) / 4 * 4) /* allocates memory on the head, which is stored in sram2 */ -void* halloc(size_t n); +void* kalloc(size_t n); -/* Frees the memory allocated by halloc. */ -void hfree(void* mem); +/* Frees the memory allocated by kalloc. */ +void kfree(void* mem); #ifdef FOR_TESTING -void* debug_halloc_get_next_ptr(void* ptr); +void* debug_kalloc_get_next_ptr(void* ptr); -void* debug_halloc_get_prev_ptr(void* ptr); +void* debug_kalloc_get_prev_ptr(void* ptr); -int debug_halloc_assert_consistency(char* error, size_t len); +int debug_kalloc_assert_consistency(char* error, size_t len); void debug_print_blocks(); diff --git a/src/kern/mem.c b/src/kern/mem.c index 5234fff..edef8f4 100644 --- a/src/kern/mem.c +++ b/src/kern/mem.c @@ -24,67 +24,67 @@ void* memset(void* dest, int c, size_t n); #endif -typedef uint16_t halloc_off_t; +typedef uint16_t kalloc_off_t; #define CANARY 0x5a // The sizes will count the number of WORDS allocated. // Since there's a max size of 16k, only 12 bits will be // needed for this. -typedef struct HALLOC_NODE { +typedef struct KALLOC_NODE { union { uint32_t header; struct { - /* Is this memory block currently in use (hasn't been hfree'd) */ + /* Is this memory block currently in use (hasn't been kfree'd) */ uint8_t used:1; /* Number of words allocated. Does not include the header. */ uint16_t size:12; /* The location of the previous block (in WORDS from offest) */ - halloc_off_t prev:12; + kalloc_off_t prev:12; uint8_t canary:7; } PACKED; }; uint8_t mem[]; /* The memory to use. */ -} halloc_node_t; +} kalloc_node_t; -static_assert(offsetof(halloc_node_t, mem) == 4, "Offset check failed."); +static_assert(offsetof(kalloc_node_t, mem) == 4, "Offset check failed."); -halloc_node_t* halloc_start; +kalloc_node_t* kalloc_start; -#define halloc_node_out_of_range(node) \ +#define kalloc_node_out_of_range(node) \ ((uint8_t*) (node) == ((uint8_t*)&DATA_SEGMENT_STOP) + MAX_HEAP_SIZE) -#define halloc_node_next(cur) \ - ((halloc_node_t*)(((uint8_t*)(cur)) + (((cur)->size + 1) * 4))) +#define kalloc_node_next(cur) \ + ((kalloc_node_t*)(((uint8_t*)(cur)) + (((cur)->size + 1) * 4))) -#define halloc_node_prev(cur) halloc_node_at_off(cur->prev) +#define kalloc_node_prev(cur) kalloc_node_at_off(cur->prev) -#define halloc_node_at_off(offset) \ - ((halloc_node_t*)(((uint8_t*) halloc_start) + (offset) * 4)) +#define kalloc_node_at_off(offset) \ + ((kalloc_node_t*)(((uint8_t*) kalloc_start) + (offset) * 4)) -#define halloc_node_get_off(node) \ - (((uint32_t)(((uint8_t*)(node)) - ((uint8_t*)(halloc_start)))) / 4) +#define kalloc_node_get_off(node) \ + (((uint32_t)(((uint8_t*)(node)) - ((uint8_t*)(kalloc_start)))) / 4) -#define get_halloc_node(mem) \ - ((halloc_node_t*)(((uint8_t*)mem) - 4)) +#define get_kalloc_node(mem) \ + ((kalloc_node_t*)(((uint8_t*)mem) - 4)) #define size_for(n) \ (((n) / 4) + ((n) % 4 != 0)) -void* halloc(size_t size) +void* kalloc(size_t size) { - if (!halloc_start) { - halloc_start = (halloc_node_t*) DATA_SEGMENT_STOP_ADDR; - memset(halloc_start, 0, sizeof(halloc_node_t)); - halloc_start->size = (MAX_HEAP_SIZE / 4) - 1; - halloc_start->canary = CANARY; + if (!kalloc_start) { + kalloc_start = (kalloc_node_t*) DATA_SEGMENT_STOP_ADDR; + memset(kalloc_start, 0, sizeof(kalloc_node_t)); + kalloc_start->size = (MAX_HEAP_SIZE / 4) - 1; + kalloc_start->canary = CANARY; } size_t realsz = size_for(size); /* Clip the size to the nearest word. */ - halloc_off_t offset = 0; + kalloc_off_t offset = 0; while (offset < (MAX_HEAP_SIZE / 4)) { - halloc_node_t* cur = halloc_node_at_off(offset); + kalloc_node_t* cur = kalloc_node_at_off(offset); if (!cur->used && (cur->size >= realsz)) { cur->used = true; @@ -92,23 +92,23 @@ void* halloc(size_t size) cur->size = realsz; if (orig_size > realsz) { - /* This halloc node needs to split into two blocks. */ - halloc_node_t* next = halloc_node_next(cur); + /* This kalloc node needs to split into two blocks. */ + kalloc_node_t* next = kalloc_node_next(cur); next->used = 0; - next->size = orig_size - realsz - sizeof(halloc_node_t) / 4; + next->size = orig_size - realsz - sizeof(kalloc_node_t) / 4; next->prev = offset; next->canary = CANARY; - halloc_node_t* nextnext = halloc_node_next(next); - if (halloc_node_get_off(nextnext) < (MAX_HEAP_SIZE / 4)) { - nextnext->prev = halloc_node_get_off(next); + kalloc_node_t* nextnext = kalloc_node_next(next); + if (kalloc_node_get_off(nextnext) < (MAX_HEAP_SIZE / 4)) { + nextnext->prev = kalloc_node_get_off(next); } } return (void*) cur->mem; } - offset += (sizeof(halloc_node_t) / 4) + cur->size; + offset += (sizeof(kalloc_node_t) / 4) + cur->size; } return NULL; @@ -116,33 +116,33 @@ void* halloc(size_t size) /* Joins this node with the previous and next nodes if they're free. */ -static void coalesce(halloc_node_t* cur) +static void coalesce(kalloc_node_t* cur) { - halloc_node_t* orig = cur; - halloc_node_t* last_freed; - halloc_node_t* next_used; + kalloc_node_t* orig = cur; + kalloc_node_t* last_freed; + kalloc_node_t* next_used; /* Find the earliest contiguous free'd block. */ - while (!cur->used && cur != halloc_start) { - cur = halloc_node_prev(cur); + while (!cur->used && cur != kalloc_start) { + cur = kalloc_node_prev(cur); } - if (cur == halloc_start && !cur->used) { + if (cur == kalloc_start && !cur->used) { last_freed = cur; } else { - last_freed = halloc_node_next(cur); + last_freed = kalloc_node_next(cur); } /* Find the next used block. */ cur = orig; - while (!cur->used && !halloc_node_out_of_range(cur)) { - cur = halloc_node_next(cur); + while (!cur->used && !kalloc_node_out_of_range(cur)) { + cur = kalloc_node_next(cur); } next_used = cur; - if (!halloc_node_out_of_range(next_used)) { - next_used->prev = halloc_node_get_off(last_freed); + if (!kalloc_node_out_of_range(next_used)) { + next_used->prev = kalloc_node_get_off(last_freed); } last_freed->size = ((uint8_t*) next_used - (last_freed->mem)) / 4; @@ -163,12 +163,12 @@ void panic(const char* x) } #endif -void hfree(void* mem) +void kfree(void* mem) { /* Like normal free(), do nothing on free'ing NULL */ if (!mem) return; - halloc_node_t* header = get_halloc_node(mem); + kalloc_node_t* header = get_kalloc_node(mem); if (!header->used) { panic("Heap double free or corruption!\n"); return; @@ -182,18 +182,18 @@ void hfree(void* mem) #include <stdio.h> -void* debug_halloc_get_next_ptr(void* ptr) +void* debug_kalloc_get_next_ptr(void* ptr) { - halloc_node_t* node = ptr - sizeof(halloc_node_t); - halloc_node_t* next = halloc_node_next(node); + kalloc_node_t* node = ptr - sizeof(kalloc_node_t); + kalloc_node_t* next = kalloc_node_next(node); return next->mem; } -void* debug_halloc_get_prev_ptr(void* ptr) +void* debug_kalloc_get_prev_ptr(void* ptr) { - halloc_node_t* node = ptr - sizeof(halloc_node_t); - halloc_node_t* prev = halloc_node_prev(node); + kalloc_node_t* node = ptr - sizeof(kalloc_node_t); + kalloc_node_t* prev = kalloc_node_prev(node); return prev->mem; } @@ -201,20 +201,20 @@ void* debug_halloc_get_prev_ptr(void* ptr) void debug_print_blocks() { printf("------ Print Blocks -------\n"); - halloc_node_t* cur = halloc_node_at_off(0); + kalloc_node_t* cur = kalloc_node_at_off(0); - while (!halloc_node_out_of_range(cur)) { + while (!kalloc_node_out_of_range(cur)) { printf("header (%04x) {used=%d, size=%5d, prev=%04x, canary=%02x}\n", - halloc_node_get_off(cur), cur->used, cur->size, cur->prev, cur->canary); - cur = halloc_node_next(cur); + kalloc_node_get_off(cur), cur->used, cur->size, cur->prev, cur->canary); + cur = kalloc_node_next(cur); } } /* Tests that we can walk up and down the allocated blocks and that they * are properly aligned. */ -int debug_halloc_assert_consistency(char* error, size_t len) +int debug_kalloc_assert_consistency(char* error, size_t len) { - halloc_node_t* cur = halloc_node_at_off(0); + kalloc_node_t* cur = kalloc_node_at_off(0); size_t total_size = 0; size_t loop_check = 0; size_t n_blocks = 1; @@ -229,7 +229,7 @@ int debug_halloc_assert_consistency(char* error, size_t len) total_size += cur->size + 1; - halloc_node_t* next = halloc_node_next(cur); + kalloc_node_t* next = kalloc_node_next(cur); if ((uint8_t*) next == ((uint8_t*)&DATA_SEGMENT_STOP) + MAX_HEAP_SIZE) { break; } else if ((uint8_t*) next > (uint8_t*)DATA_SEGMENT_STOP_ADDR + MAX_HEAP_SIZE){ @@ -251,15 +251,15 @@ int debug_halloc_assert_consistency(char* error, size_t len) return 1; } - if (cur == halloc_start) { + if (cur == kalloc_start) { return 0; } while (loop_check < 10000) { - halloc_node_t* prev = halloc_node_prev(cur); + kalloc_node_t* prev = kalloc_node_prev(cur); ++ n_blocks_back; - if (prev == halloc_start) { + if (prev == kalloc_start) { if (n_blocks != n_blocks_back) { snprintf( error, len, "Different number of blocks found on the way back. Found %lu on the way back vs %lu up.\n", diff --git a/tests/test_memory.c b/tests/test_memory.c index 04e9289..6e523aa 100644 --- a/tests/test_memory.c +++ b/tests/test_memory.c @@ -18,11 +18,11 @@ struct TEST_STRUCT2 { }; /* Copy of the node structure. */ -typedef struct HALLOC_NODE { +typedef struct KALLOC_NODE { union { uint32_t header; struct { - /* Is this memory block currently in use (hasn't been hfree'd) */ + /* Is this memory block currently in use (hasn't been kfree'd) */ bool used:1; /* Number of words allocated. Does not include the header. */ uint16_t size:12; @@ -33,20 +33,20 @@ typedef struct HALLOC_NODE { }; uint8_t mem[]; /* The memory to use. */ -} halloc_node_t; +} kalloc_node_t; -extern halloc_node_t* halloc_start; +extern kalloc_node_t* kalloc_start; -static void wipeout_halloc() +static void wipeout_kalloc() { - memset(halloc_start, 0, 1024); - halloc_start = NULL; + memset(kalloc_start, 0, 1024); + kalloc_start = NULL; } static struct TEST_STRUCT* new_test_struct() { - struct TEST_STRUCT* ret = halloc(sizeof(struct TEST_STRUCT)); + struct TEST_STRUCT* ret = kalloc(sizeof(struct TEST_STRUCT)); ret->array[0] = 1; ret->array[1] = 2; @@ -57,7 +57,7 @@ static struct TEST_STRUCT* new_test_struct() static struct TEST_STRUCT2* new_test_struct2() { - struct TEST_STRUCT2* ret = halloc(sizeof(struct TEST_STRUCT2)); + struct TEST_STRUCT2* ret = kalloc(sizeof(struct TEST_STRUCT2)); for (int i = 0; i < 10; ++ i) { ret->array[i] = i; @@ -69,7 +69,7 @@ static struct TEST_STRUCT2* new_test_struct2() #define ASSERT_CHAIN(t1, t2) \ ASSERT_EQ(V(t1) + sizeof(*t1) + 4, V(t2)) -TEST(memory, halloc) +TEST(memory, kalloc) { #define V(x) ((void*)(x)) @@ -92,7 +92,7 @@ TEST(memory, halloc) char buf[1024]; - if (debug_halloc_assert_consistency(buf, 1024)) { + if (debug_kalloc_assert_consistency(buf, 1024)) { fprintf( stderr, "Consistency check failed. (%s:%d)\n", @@ -102,7 +102,7 @@ TEST(memory, halloc) ASSERT_TRUE(false); } - wipeout_halloc(); + wipeout_kalloc(); return 0; } @@ -113,7 +113,7 @@ struct UNEVEN_STRUCT { struct UNEVEN_STRUCT* new_uneven_struct() { - struct UNEVEN_STRUCT* ret = halloc(sizeof(struct UNEVEN_STRUCT)); + struct UNEVEN_STRUCT* ret = kalloc(sizeof(struct UNEVEN_STRUCT)); ret->arr[0] = 1; ret->arr[1] = 2; @@ -127,10 +127,10 @@ struct UNEVEN_STRUCT* new_uneven_struct() #define size_for(n) \ (((n) / 4) + ((n) % 4 != 0)) -TEST(memory, uneven_halloc) +TEST(memory, uneven_kalloc) { - if (halloc_start) { - wipeout_halloc(); + if (kalloc_start) { + wipeout_kalloc(); } struct UNEVEN_STRUCT* test1 = new_uneven_struct(); @@ -138,15 +138,15 @@ TEST(memory, uneven_halloc) ASSERT_EQ(V(test1) + 12, test2); - wipeout_halloc(); + wipeout_kalloc(); return 0; } -TEST(memory, halloc_free) +TEST(memory, kalloc_free) { - if (halloc_start) { - wipeout_halloc(); + if (kalloc_start) { + wipeout_kalloc(); } struct TEST_STRUCT* test1 = new_test_struct(); @@ -155,13 +155,13 @@ TEST(memory, halloc_free) struct TEST_STRUCT2* test4 = new_test_struct2(); struct TEST_STRUCT2* test5 = new_test_struct2(); - hfree(test2); - hfree(test4); - hfree(test3); - hfree(test1); - hfree(test5); + kfree(test2); + kfree(test4); + kfree(test3); + kfree(test1); + kfree(test5); - ASSERT_EQ((int) halloc_start->size * 4, MAX_HEAP_SIZE - 4); + ASSERT_EQ((int) kalloc_start->size * 4, MAX_HEAP_SIZE - 4); test1 = new_test_struct(); test2 = new_test_struct2(); @@ -169,13 +169,13 @@ TEST(memory, halloc_free) test4 = new_test_struct2(); test5 = new_test_struct2(); - hfree(test1); - hfree(test3); - hfree(test2); - hfree(test4); - hfree(test5); + kfree(test1); + kfree(test3); + kfree(test2); + kfree(test4); + kfree(test5); - ASSERT_EQ((int) halloc_start->size * 4, MAX_HEAP_SIZE - 4); + ASSERT_EQ((int) kalloc_start->size * 4, MAX_HEAP_SIZE - 4); test1 = new_test_struct(); test2 = new_test_struct2(); @@ -183,47 +183,47 @@ TEST(memory, halloc_free) test4 = new_test_struct2(); test5 = new_test_struct2(); - hfree(test4); - hfree(test3); - hfree(test1); - hfree(test2); - hfree(test5); + kfree(test4); + kfree(test3); + kfree(test1); + kfree(test2); + kfree(test5); - ASSERT_EQ((int) halloc_start->size * 4, MAX_HEAP_SIZE - 4); + ASSERT_EQ((int) kalloc_start->size * 4, MAX_HEAP_SIZE - 4); - wipeout_halloc(); + wipeout_kalloc(); return 0; } -TEST(memory, halloc_free_alloc2) +TEST(memory, kalloc_free_alloc2) { - if (halloc_start) { - wipeout_halloc(); + if (kalloc_start) { + wipeout_kalloc(); } struct TEST_STRUCT2* test1 = new_test_struct2(); struct TEST_STRUCT2* test2 = new_test_struct2(); - hfree(test1); + kfree(test1); struct TEST_STRUCT* test3 = new_test_struct(); struct TEST_STRUCT* test4 = new_test_struct(); - ASSERT_EQ(debug_halloc_get_next_ptr(test3), V(test4)); + ASSERT_EQ(debug_kalloc_get_next_ptr(test3), V(test4)); ASSERT_EQ( // There should be a free block after test4. - debug_halloc_get_next_ptr(debug_halloc_get_next_ptr(test4)), + debug_kalloc_get_next_ptr(debug_kalloc_get_next_ptr(test4)), V(test2)); ASSERT_EQ( // There should be a free block after test4. - debug_halloc_get_prev_ptr(debug_halloc_get_prev_ptr(test2)), + debug_kalloc_get_prev_ptr(debug_kalloc_get_prev_ptr(test2)), V(test4)); char buf[1024]; - if (debug_halloc_assert_consistency(buf, 1024)) { + if (debug_kalloc_assert_consistency(buf, 1024)) { fprintf(stderr, "Consistency check failed.\n"); fprintf(stderr, buf); ASSERT_TRUE(false); @@ -234,18 +234,18 @@ TEST(memory, halloc_free_alloc2) TEST(memory, relink_backref_after_free) { - if (halloc_start) { - wipeout_halloc(); + if (kalloc_start) { + wipeout_kalloc(); } struct TEST_STRUCT* test2 = new_test_struct(); struct TEST_STRUCT* test3 = new_test_struct(); - hfree(test2); - hfree(test3); + kfree(test2); + kfree(test3); char buf[1024]; - if (debug_halloc_assert_consistency(buf, 1024)) { + if (debug_kalloc_assert_consistency(buf, 1024)) { fprintf(stderr, "Consistency check failed.\n"); fprintf(stderr, buf); ASSERT_TRUE(false); @@ -257,8 +257,8 @@ TEST(memory, relink_backref_after_free) TEST(memory, consistency_stress) { #define NRUNS 500 - if (halloc_start) { - wipeout_halloc(); + if (kalloc_start) { + wipeout_kalloc(); } int i; @@ -267,9 +267,9 @@ TEST(memory, consistency_stress) for (i = 0; i < NRUNS; ++ i) { size_t nalloc = rand() % 20; - allocd[i] = halloc(nalloc); + allocd[i] = kalloc(nalloc); - if (debug_halloc_assert_consistency(buf, 1024)) { + if (debug_kalloc_assert_consistency(buf, 1024)) { fprintf( stderr, "Consistency check failed. (At index=%d, %s:%d)\n", @@ -285,7 +285,7 @@ TEST(memory, consistency_stress) memset(allocd[i], 0xFF, nalloc); size_t idx = rand() % NRUNS; - if (debug_halloc_assert_consistency(buf, 1024)) { + if (debug_kalloc_assert_consistency(buf, 1024)) { fprintf( stderr, "Consistency check failed. (At index=%d, %s:%d)\n", @@ -296,10 +296,10 @@ TEST(memory, consistency_stress) ASSERT_TRUE(false); } - hfree(allocd[idx]); + kfree(allocd[idx]); allocd[idx] = NULL; - if (debug_halloc_assert_consistency(buf, 1024)) { + if (debug_kalloc_assert_consistency(buf, 1024)) { fprintf( stderr, "Consistency check failed. (At index=%d, %s:%d)\n", @@ -311,10 +311,10 @@ TEST(memory, consistency_stress) } idx = rand() % NRUNS; - hfree(allocd[idx]); + kfree(allocd[idx]); allocd[idx] = NULL; - if (debug_halloc_assert_consistency(buf, 1024)) { + if (debug_kalloc_assert_consistency(buf, 1024)) { fprintf( stderr, "Consistency check failed. (At index=%d, %s:%d)\n", @@ -328,10 +328,10 @@ TEST(memory, consistency_stress) for(i = 0; i < NRUNS; ++ i) { if (allocd[i]) { - hfree(allocd[i]); + kfree(allocd[i]); } - if (debug_halloc_assert_consistency(buf, 1024)) { + if (debug_kalloc_assert_consistency(buf, 1024)) { fprintf( stderr, "Consistency check failed. (At index=%d, %s:%d)\n", @@ -342,15 +342,15 @@ TEST(memory, consistency_stress) ASSERT_TRUE(false); } } - ASSERT_EQ((int) halloc_start->size * 4, MAX_HEAP_SIZE - 4); + ASSERT_EQ((int) kalloc_start->size * 4, MAX_HEAP_SIZE - 4); return 0; } -TEST(memory, halloc_free_alloc) +TEST(memory, kalloc_free_alloc) { - if (halloc_start) { - wipeout_halloc(); + if (kalloc_start) { + wipeout_kalloc(); } new_test_struct(); @@ -359,14 +359,14 @@ TEST(memory, halloc_free_alloc) struct TEST_STRUCT2* test4 = new_test_struct2(); new_test_struct2(); - hfree(test4); + kfree(test4); struct TEST_STRUCT2* test6 = new_test_struct2(); // test_6 should have been allocated in test_4's spot. ASSERT_EQ(test6, test4); - hfree(test2); + kfree(test2); struct TEST_STRUCT* test7 = new_test_struct(); struct TEST_STRUCT* test8 = new_test_struct(); |