Created
December 11, 2019 14:20
-
-
Save untodesu/be84a7c00bd972597f89771857907d18 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //================================ | |
| // The AUX2D Engine | |
| // | |
| // This Source Code Form is subject to the terms of the Mozilla Public | |
| // License, v2.0. If a copy of the MPL was not distributed with this | |
| // file, You can obtain one at https://mozilla.org/MPL/2.0/ | |
| // | |
| // File: The double-ended linear memory allocator | |
| //================================ | |
| #include <cstdlib> | |
| #include <cassert> | |
| #include <aux2d.h> | |
| #include <heap.h> | |
| //-------------------------------- | |
| // Allocator structure | |
| //-------------------------------- | |
| struct H_Allocator { | |
| size_t buffer_size; | |
| void * buffer; | |
| size_t high_end; | |
| size_t low_end; | |
| H_Allocator(void) : buffer_size(0), buffer(nullptr), high_end(0), low_end(0) { } | |
| }; | |
| static H_Allocator s_allocator; | |
| //-------------------------------- | |
| // Initialize allocator | |
| //-------------------------------- | |
| bool H_Initialize(size_t buffer_size) | |
| { | |
| //Initialize only if not initialized. | |
| if(!s_allocator.buffer) { | |
| //Allocate | |
| s_allocator.buffer = malloc(buffer_size); | |
| assert(s_allocator.buffer); | |
| //Initialize values | |
| s_allocator.buffer_size = buffer_size; | |
| s_allocator.high_end = 0; //Grows down | |
| s_allocator.low_end = 0; | |
| return true; | |
| } | |
| return false; | |
| } | |
| //-------------------------------- | |
| // Shutdown allocator | |
| //-------------------------------- | |
| bool H_Shutdown(void) | |
| { | |
| //Shutdown allowed only if initialized | |
| if(s_allocator.buffer) { | |
| //De-allocate | |
| free(s_allocator.buffer); | |
| s_allocator.buffer = nullptr; | |
| //Clear values. | |
| s_allocator.buffer_size = 0; | |
| s_allocator.high_end = 0; | |
| s_allocator.low_end = 0; | |
| return true; | |
| } | |
| return false; | |
| } | |
| //-------------------------------- | |
| // Allocate (low area) | |
| //-------------------------------- | |
| void * H_Malloc(size_t size) | |
| { | |
| if(!s_allocator.buffer) { | |
| return nullptr; | |
| } | |
| //Control variables | |
| size_t old_end = (s_allocator.low_end); | |
| size_t new_end = (s_allocator.low_end + size); | |
| size_t high_limit = (s_allocator.buffer_size - s_allocator.high_end); | |
| //New end shouldn't overflow current higher allocation | |
| if(new_end > high_limit) { | |
| return nullptr; | |
| } | |
| //Now we have allocated memory! | |
| s_allocator.low_end = new_end; | |
| return (uint8_t *)s_allocator.buffer + old_end; | |
| } | |
| //-------------------------------- | |
| // Allocate (high area) | |
| //-------------------------------- | |
| void * H_HighMalloc(size_t size) | |
| { | |
| if(!s_allocator.buffer) { | |
| return nullptr; | |
| } | |
| //Control variables | |
| size_t old_end = (s_allocator.high_end); | |
| size_t new_end = (s_allocator.high_end + size); | |
| size_t low_limit = (s_allocator.buffer_size - s_allocator.low_end); | |
| //New end shouldn't overflow current lower allocation | |
| if(new_end > low_limit) { | |
| return nullptr; | |
| } | |
| //Now we have allocated memory in the higher area | |
| s_allocator.high_end = new_end; | |
| return (uint8_t *)s_allocator.buffer + old_end; | |
| } | |
| //-------------------------------- | |
| // Clear low area | |
| //-------------------------------- | |
| void H_Free(void) | |
| { | |
| if(!s_allocator.buffer) { | |
| return; | |
| } | |
| // Actually clear all stuff | |
| for(size_t i = 0; i < s_allocator.low_end; i++) { | |
| *((uint8_t *)s_allocator.buffer + i) = 0x00; | |
| } | |
| s_allocator.low_end = 0; | |
| } | |
| //-------------------------------- | |
| // Clear high area | |
| //-------------------------------- | |
| void H_HighFree(void) | |
| { | |
| if(!s_allocator.buffer) { | |
| return; | |
| } | |
| // Actually clear all stuff | |
| for(size_t i = 0; i < s_allocator.high_end; i++) { | |
| *((uint8_t *)s_allocator.buffer + (s_allocator.buffer_size - i - 1)) = 0x00; | |
| } | |
| s_allocator.high_end = 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment