Files
basalt/include/core/basalt_memory.h
Riley King-Saunders 8d7bfe0bc9 Buildsystem: Removed include/basalt_window.h. See prior commit #cac50b01
Library:
Added logging and memory modules.
The logging module provides a flexible interface for adding and removing logging streams (think stdout, stderr, a file) and supports ANSI colouring and including the date and time of each log call. Its header also provides several definitions for assertions, each corresponding to a specific log level and some other side effects such as debug_break(), returning, exiting or doing nothing.
The memory module wraps (_)aligned_alloc and free functions and includes memory tagging by class and location and the ability to fetch a formatted string containing this information. This can allow you to narrow down where memory leaks and double frees occur to particular sections within a module. Memory can be aligned to any, 32, 64 or 4096 byte boundaries using this module.
2025-06-22 03:02:42 +10:00

87 lines
3.7 KiB
C++

#pragma once
#include "basalt_defines.h"
typedef u16 MEMORY_TAG;
typedef enum MEMORY_TAGS {
MEMORY_TAG_BITWIDTH_CLASS = 5,
MEMORY_TAG_BITWIDTH_ZONE = 4,
MEMORY_TAG_BITWIDTH_ALIGN = 2,
MEMORY_TAG_SHIFT_CLASS = 0,
MEMORY_TAG_SHIFT_ZONE = MEMORY_TAG_SHIFT_CLASS + MEMORY_TAG_BITWIDTH_CLASS,
MEMORY_TAG_SHIFT_ALIGN = MEMORY_TAG_SHIFT_ZONE + MEMORY_TAG_BITWIDTH_ZONE,
MEMORY_TAG_MASK_CLASS = ((1 << MEMORY_TAG_BITWIDTH_CLASS) - 1) << MEMORY_TAG_SHIFT_CLASS,
MEMORY_TAG_MASK_ZONE = ((1 << MEMORY_TAG_BITWIDTH_ZONE) - 1) << MEMORY_TAG_SHIFT_ZONE,
MEMORY_TAG_MASK_ALIGN = ((1 << MEMORY_TAG_BITWIDTH_ALIGN) - 1) << MEMORY_TAG_SHIFT_ALIGN,
MEMORY_TAG_CLASS_UNKNOWN = 0 << MEMORY_TAG_SHIFT_CLASS,
MEMORY_TAG_CLASS_ARRAY = 1 << MEMORY_TAG_SHIFT_CLASS,
MEMORY_TAG_CLASS_DYNARRAY = 2 << MEMORY_TAG_SHIFT_CLASS,
MEMORY_TAG_CLASS_STRING = 3 << MEMORY_TAG_SHIFT_CLASS,
MEMORY_TAG_CLASS_CIRCULAR_BUFFER = 4 << MEMORY_TAG_SHIFT_CLASS,
MEMORY_TAG_CLASS_DICT = 5 << MEMORY_TAG_SHIFT_CLASS,
MEMORY_TAG_CLASS_BINTREE = 6 << MEMORY_TAG_SHIFT_CLASS,
MEMORY_TAG_CLASS_OCTTREE = 7 << MEMORY_TAG_SHIFT_CLASS,
MEMORY_TAG_CLASS_TEXTURE = 9 << MEMORY_TAG_SHIFT_CLASS,
MEMORY_TAG_CLASS_JOB = 9 << MEMORY_TAG_SHIFT_CLASS,
MEMORY_TAG_CLASS_TRANSFORM = 10 << MEMORY_TAG_SHIFT_CLASS,
MEMORY_TAG_CLASS_RENDER_OBJECT = 11 << MEMORY_TAG_SHIFT_CLASS,
MEMORY_TAG_CLASS_MATERIAL = 12 << MEMORY_TAG_SHIFT_CLASS,
MEMORY_TAG_CLASS_MAX_BUILTIN = (MEMORY_TAG_CLASS_MATERIAL >> MEMORY_TAG_SHIFT_CLASS) + 1,
MEMORY_TAG_CLASS_MAX = (1 << MEMORY_TAG_BITWIDTH_CLASS) - 1,
MEMORY_TAG_ZONE_UNKNOWN = 0 << MEMORY_TAG_SHIFT_ZONE,
MEMORY_TAG_ZONE_SCENE = 1 << MEMORY_TAG_SHIFT_ZONE,
MEMORY_TAG_ZONE_APPLICATION = 2 << MEMORY_TAG_SHIFT_ZONE,
MEMORY_TAG_ZONE_RENDERER = 3 << MEMORY_TAG_SHIFT_ZONE,
MEMORY_TAG_ZONE_ENGINE = 4 << MEMORY_TAG_SHIFT_ZONE,
MEMORY_TAG_ZONE_EVENT = 5 << MEMORY_TAG_SHIFT_ZONE,
MEMORY_TAG_ZONE_DEBUG = 6 << MEMORY_TAG_SHIFT_ZONE,
MEMORY_TAG_ZONE_AUDIO = 7 << MEMORY_TAG_SHIFT_ZONE,
MEMORY_TAG_ZONE_MAX_BUILTIN = (MEMORY_TAG_ZONE_AUDIO >> MEMORY_TAG_SHIFT_ZONE) + 1,
MEMORY_TAG_ZONE_MAX = (1 << MEMORY_TAG_BITWIDTH_ZONE) - 1,
MEMORY_TAG_ALIGN_ANY = 0 << MEMORY_TAG_SHIFT_ALIGN,
MEMORY_TAG_ALIGN_32 = 1 << MEMORY_TAG_SHIFT_ALIGN,
MEMORY_TAG_ALIGN_64 = 2 << MEMORY_TAG_SHIFT_ALIGN,
MEMORY_TAG_ALIGN_PAGE = 3 << MEMORY_TAG_SHIFT_ALIGN,
MEMORY_TAG_ALIGN_MAX_BUILTIN = (MEMORY_TAG_ALIGN_PAGE >> MEMORY_TAG_SHIFT_ALIGN) + 1,
MEMORY_TAG_ALIGN_MAX = (1 << MEMORY_TAG_BITWIDTH_ALIGN) - 1,
} MEMORY_TAGS;
namespace basalt
{
namespace mem
{
void initialize_memory(void);
void terminate_memory (void);
template <typename T>
T* allocT(u64 num_elements, MEMORY_TAG tag);
void* alloc(u64 num_bytes, MEMORY_TAG tag);
void dealloc(void* ptr, u64 num_bytes, MEMORY_TAG tag);
template <typename T>
T* setzeroT(T* dst, u64 num_elements);
void* setzero(void* dst, u64 num_bytes);
void changetag(u64 nbytes, MEMORY_TAG prev, MEMORY_TAG next);
i64 get_total_memory_usage(void);
i64 get_memory_usage_for_class(MEMORY_TAG memory_class, i64 out_per_zone[MEMORY_TAG_CLASS_MAX]);
i64 get_memory_usage_for_zone(MEMORY_TAG memory_zone, i64 out_per_class[MEMORY_TAG_ZONE_MAX]);
// Must be freed by user via dealloc with the tags;
// MEMORY_TAG_CLASS_STRING | MEMORY_TAG_ZONE_DEBUG | MEMORY_TAG_ALIGN_ANY
char* get_memory_usage_string(void);
i64 get_memory_tag_class_name(MEMORY_TAG memory_class, char* out_buf, u64 out_buf_size);
i64 get_memory_tag_zone_name(MEMORY_TAG zone_class, char* out_buf, u64 out_buf_size);
template<typename T>
T* allocT(u64 num_elements, MEMORY_TAG tag)
{ return alloc(num_elements*sizeof(T), tag); }
template<typename T>
T* setzeroT(T * dst, u64 num_elements)
{ return setzero(dst, num_elements*sizeof(T)); }
}
}