diff options
Diffstat (limited to 'src/kern/mem.c')
-rw-r--r-- | src/kern/mem.c | 98 |
1 files changed, 58 insertions, 40 deletions
diff --git a/src/kern/mem.c b/src/kern/mem.c index edef8f4..ac90f0d 100644 --- a/src/kern/mem.c +++ b/src/kern/mem.c @@ -1,5 +1,6 @@ -#include "arch.h" #include "kern/mem.h" + +#include "arch.h" #include "kern/common.h" #ifdef ARCH_STM32L4 @@ -7,12 +8,12 @@ * microcontroller. */ void* memset(void* dest, int c, size_t n) { - uint8_t c8 = (uint8_t) c; - uint8_t* dest8 = (uint8_t*) dest; + uint8_t c8 = (uint8_t)c; + uint8_t* dest8 = (uint8_t*)dest; uint8_t* to = dest8 + n; - while(dest8 < to) { - *(dest8 ++) = c8; + while (dest8 < to) { + *(dest8++) = c8; } return dest; @@ -36,12 +37,12 @@ typedef struct KALLOC_NODE { uint32_t header; struct { /* Is this memory block currently in use (hasn't been kfree'd) */ - uint8_t used:1; + uint8_t used : 1; /* Number of words allocated. Does not include the header. */ - uint16_t size:12; + uint16_t size : 12; /* The location of the previous block (in WORDS from offest) */ - kalloc_off_t prev:12; - uint8_t canary:7; + kalloc_off_t prev : 12; + uint8_t canary : 7; } PACKED; }; @@ -53,7 +54,7 @@ static_assert(offsetof(kalloc_node_t, mem) == 4, "Offset check failed."); kalloc_node_t* kalloc_start; #define kalloc_node_out_of_range(node) \ - ((uint8_t*) (node) == ((uint8_t*)&DATA_SEGMENT_STOP) + MAX_HEAP_SIZE) + ((uint8_t*)(node) == ((uint8_t*)&DATA_SEGMENT_STOP) + MAX_HEAP_SIZE) #define kalloc_node_next(cur) \ ((kalloc_node_t*)(((uint8_t*)(cur)) + (((cur)->size + 1) * 4))) @@ -61,28 +62,26 @@ kalloc_node_t* kalloc_start; #define kalloc_node_prev(cur) kalloc_node_at_off(cur->prev) #define kalloc_node_at_off(offset) \ - ((kalloc_node_t*)(((uint8_t*) kalloc_start) + (offset) * 4)) + ((kalloc_node_t*)(((uint8_t*)kalloc_start) + (offset)*4)) #define kalloc_node_get_off(node) \ (((uint32_t)(((uint8_t*)(node)) - ((uint8_t*)(kalloc_start)))) / 4) -#define get_kalloc_node(mem) \ - ((kalloc_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)) +#define size_for(n) (((n) / 4) + ((n) % 4 != 0)) void* kalloc(size_t size) { if (!kalloc_start) { - kalloc_start = (kalloc_node_t*) DATA_SEGMENT_STOP_ADDR; + 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. */ - kalloc_off_t offset = 0; + kalloc_off_t offset = 0; while (offset < (MAX_HEAP_SIZE / 4)) { kalloc_node_t* cur = kalloc_node_at_off(offset); @@ -90,7 +89,7 @@ void* kalloc(size_t size) cur->used = true; size_t orig_size = cur->size; cur->size = realsz; - + if (orig_size > realsz) { /* This kalloc node needs to split into two blocks. */ kalloc_node_t* next = kalloc_node_next(cur); @@ -105,7 +104,7 @@ void* kalloc(size_t size) } } - return (void*) cur->mem; + return (void*)cur->mem; } offset += (sizeof(kalloc_node_t) / 4) + cur->size; @@ -114,7 +113,6 @@ void* kalloc(size_t size) return NULL; } - /* Joins this node with the previous and next nodes if they're free. */ static void coalesce(kalloc_node_t* cur) { @@ -145,7 +143,7 @@ static void coalesce(kalloc_node_t* cur) next_used->prev = kalloc_node_get_off(last_freed); } - last_freed->size = ((uint8_t*) next_used - (last_freed->mem)) / 4; + last_freed->size = ((uint8_t*)next_used - (last_freed->mem)) / 4; } #ifdef FOR_TESTING @@ -159,7 +157,8 @@ void panic(const char* x) #else void panic(const char* x) { - for(;;); + for (;;) + ; } #endif @@ -186,7 +185,7 @@ void* debug_kalloc_get_next_ptr(void* ptr) { kalloc_node_t* node = ptr - sizeof(kalloc_node_t); kalloc_node_t* next = kalloc_node_next(node); - + return next->mem; } @@ -194,7 +193,7 @@ void* debug_kalloc_get_prev_ptr(void* ptr) { kalloc_node_t* node = ptr - sizeof(kalloc_node_t); kalloc_node_t* prev = kalloc_node_prev(node); - + return prev->mem; } @@ -204,8 +203,13 @@ void debug_print_blocks() kalloc_node_t* cur = kalloc_node_at_off(0); while (!kalloc_node_out_of_range(cur)) { - printf("header (%04x) {used=%d, size=%5d, prev=%04x, canary=%02x}\n", - kalloc_node_get_off(cur), cur->used, cur->size, cur->prev, cur->canary); + printf( + "header (%04x) {used=%d, size=%5d, prev=%04x, canary=%02x}\n", + kalloc_node_get_off(cur), + cur->used, + cur->size, + cur->prev, + cur->canary); cur = kalloc_node_next(cur); } } @@ -220,34 +224,44 @@ int debug_kalloc_assert_consistency(char* error, size_t len) size_t n_blocks = 1; size_t n_blocks_back = 1; - while(1) { + while (1) { if (cur->canary != CANARY) { - snprintf(error, len, "Node has corrupted canary. %02x vs expected %02x\n", - cur->canary, CANARY); + snprintf( + error, + len, + "Node has corrupted canary. %02x vs expected %02x\n", + cur->canary, + CANARY); return 1; } total_size += cur->size + 1; kalloc_node_t* next = kalloc_node_next(cur); - if ((uint8_t*) next == ((uint8_t*)&DATA_SEGMENT_STOP) + MAX_HEAP_SIZE) { + 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){ + } else if ( + (uint8_t*)next > (uint8_t*)DATA_SEGMENT_STOP_ADDR + MAX_HEAP_SIZE) { snprintf( - error, len, "Next node points is out of bounds. %p vs max of %p\n", + error, + len, + "Next node points is out of bounds. %p vs max of %p\n", next, (void*)(DATA_SEGMENT_STOP_ADDR + MAX_HEAP_SIZE)); return 1; } cur = next; - ++ n_blocks; + ++n_blocks; } if (total_size * 4 != MAX_HEAP_SIZE) { snprintf( - error, len, "Total recorded size is inconsistent. %lu vs %lu\n", - total_size * 4, MAX_HEAP_SIZE); + error, + len, + "Total recorded size is inconsistent. %lu vs %lu\n", + total_size * 4, + MAX_HEAP_SIZE); return 1; } @@ -257,20 +271,24 @@ int debug_kalloc_assert_consistency(char* error, size_t len) while (loop_check < 10000) { kalloc_node_t* prev = kalloc_node_prev(cur); - ++ n_blocks_back; + ++n_blocks_back; - if (prev == kalloc_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", - n_blocks_back, n_blocks); + error, + len, + "Different number of blocks found on the way back. Found %lu on " + "the way back vs %lu up.\n", + n_blocks_back, + n_blocks); return 1; } return 0; } cur = prev; - ++ loop_check; + ++loop_check; } snprintf(error, len, "Loop check failed.\n"); |