memory.c (1893B)
1 // TODO: test that alignment is working properly 2 internal uintptr_t mem_align_address(uintptr_t address, size_t alignment) 3 { 4 assert(math_is_pow_2(alignment)); 5 // This works since we've asserted alignment is a power of 2 6 size_t mask = alignment - 1; 7 uintptr_t result = (address + mask) & ~mask; 8 return result; 9 } 10 11 internal void mem_st_init(struct StackAllocator *allocator, void *backing_buffer, size_t backing_buffer_bytes) 12 { 13 allocator->size = backing_buffer_bytes; 14 allocator->base = backing_buffer; 15 allocator->used = 0; 16 } 17 18 internal void *mem_st_alloc(struct StackAllocator *allocator, size_t bytes, size_t alignment) 19 { 20 size_t worst_case_bytes = bytes + alignment - 1; 21 assert(allocator->used + worst_case_bytes <= allocator->size); 22 23 uintptr_t current_head = (uintptr_t)allocator->base + allocator->used; 24 allocator->used += worst_case_bytes; 25 26 void *address = (void *)mem_align_address(current_head, alignment); 27 { 28 void *address_after_allocated_buffer = address + bytes; 29 void *address_after_used_allocator_memory = allocator->base + allocator->used; 30 void *address_after_backing_buffer = allocator->base + allocator->size; 31 assert(address_after_allocated_buffer <= address_after_used_allocator_memory); 32 assert(address_after_allocated_buffer <= address_after_backing_buffer); 33 } 34 return address; 35 } 36 37 internal size_t mem_st_get_marker(struct StackAllocator *allocator) 38 { 39 size_t marker = allocator->used; 40 return marker; 41 } 42 43 internal void mem_st_free_to_marker(struct StackAllocator *allocator, size_t marker) 44 { 45 if (allocator->used > marker) 46 { 47 allocator->used = marker; 48 } 49 } 50 51 internal void mem_st_free_all(struct StackAllocator *allocator) 52 { 53 allocator->used = 0; 54 } 55 56 internal void mem_move(void *dest, void *source, size_t num_bytes) 57 { 58 memmove(dest, source, num_bytes); 59 }