Skip to content

Instantly share code, notes, and snippets.

@untodesu
Created December 11, 2019 14:20
Show Gist options
  • Save untodesu/be84a7c00bd972597f89771857907d18 to your computer and use it in GitHub Desktop.
Save untodesu/be84a7c00bd972597f89771857907d18 to your computer and use it in GitHub Desktop.
//================================
// 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