X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=vg_mem.h;h=be11ddd2ef4ce43741b1d23f89eb1718c9a4680f;hb=76d234b7dc5e6500e8a54009b367e7620f11ef97;hp=49ab3e3061a8af2eb1cb87aaae01f51cd6877728;hpb=c7f36b24e8d8c4424d2a5164476a5562b889ae5e;p=vg.git diff --git a/vg_mem.h b/vg_mem.h index 49ab3e3..be11ddd 100644 --- a/vg_mem.h +++ b/vg_mem.h @@ -4,11 +4,12 @@ #include "vg.h" #include "vg_stdint.h" #include "vg_platform.h" +#include "vg_log.h" #include #include -VG_STATIC void vg_print_backtrace(void); +static void vg_print_backtrace(void); #define VG_MAX_ALLOCATIONS 128 #define VG_FUZZ_ALLOCATIONS @@ -16,8 +17,7 @@ VG_STATIC void vg_print_backtrace(void); typedef struct vg_linear_allocator vg_linear_allocator; typedef struct vg_allocation_meta vg_allocation_meta; -struct -{ +struct{ void *rtmemory, *scratch; @@ -28,10 +28,11 @@ static vg_mem; struct vg_allocation_meta { + const char *name; void *data; - enum allocation_type - { - k_allocation_type_block = 0, + u32 size; + enum allocation_type{ + k_allocation_type_block = 0, k_allocation_type_linear = 1 } type; @@ -63,17 +64,75 @@ struct vg_linear_allocator }; #pragma pack(pop) -VG_STATIC void vg_fatal_error( const char *fmt, ... ); -VG_STATIC void vg_error(const char *fmt, ...); -VG_STATIC void vg_info(const char *fmt, ...); +static u32 vg_align8( u32 s ); +static u32 vg_align4( u32 s ); + +/* allocate something from a linear allocator */ +__attribute__((warn_unused_result)) +static void *_vg_linear_alloc( void *buffer, u32 size, + const char *constr_name ); + +/* resize latest block of memory from linear */ +__attribute__((warn_unused_result)) +static void *vg_linear_resize( void *buffer, void *data, u32 newsize ); + +/* its possible to delete just the last item */ +static void vg_linear_del( void *buffer, void *data ); + +/* extend latest block of memory from linear */ +__attribute__((warn_unused_result)) +static void *_vg_linear_extend( void *buffer, void *data, u32 extra, + const char *constr_name ); + +/* get the current usage of allocator */ +static u32 vg_linear_get_cur( void *buffer ); + +/* get the capacity of allocator. */ +static u32 vg_linear_get_capacity( void *buffer ); + +/* get the remaining size of the allocator */ +static u32 vg_linear_remaining( void *buffer ); + +/* yeet all memory from linear allocator */ +static void vg_linear_clear( void *buffer ); + +/* request all the memory we need in advance */ +static void vg_set_mem_quota( u32 size ); -VG_STATIC u32 vg_align8( u32 s ) +/* essentially init() */ +static void vg_alloc_quota(void); + +/* print out tree of current memory used. only works with libc mode */ +static void vg_mem_log( void *lin_alloc, int depth, const char *name ); + +#define VG_MEM_MCSTR(S) VG_MEM_MCSTR2(S) +#define VG_MEM_MCSTR2(S) #S + +#define vg_linear_alloc(...) \ + _vg_linear_alloc( __VA_ARGS__, __FILE__":"VG_MEM_MCSTR(__LINE__) ) +#define vg_linear_extend(...) \ + _vg_linear_extend( __VA_ARGS__, __FILE__":"VG_MEM_MCSTR(__LINE__) ) +#define vg_create_linear_allocator(...) \ + _vg_create_linear_allocator( __VA_ARGS__, __FILE__":"VG_MEM_MCSTR(__LINE__) ) + +/* implementation + * ---------------------------------------- + */ + +static void vg_fatal_error( const char *fmt, ... ); + +#if 0 +static void vg_error(const char *fmt, ...); +static void vg_info(const char *fmt, ...); +#endif + +static u32 vg_align8( u32 s ) { u32 m = (s + 7) >> 3; return m << 3; } -VG_STATIC u32 vg_align4( u32 s ) +static u32 vg_align4( u32 s ) { u32 m = (s + 3) >> 2; return m << 2; @@ -90,7 +149,8 @@ static vg_linear_allocator *vg_linear_header( void *data ) /* allocate something from a linear allocator */ __attribute__((warn_unused_result)) -VG_STATIC void *vg_linear_alloc( void *buffer, u32 size ) +static void *_vg_linear_alloc( void *buffer, u32 size, + const char *constr_name ) { if( size % 8 ){ vg_error( "alloc(%u) is not 8 byte aligned\n", size ); @@ -124,6 +184,8 @@ VG_STATIC void *vg_linear_alloc( void *buffer, u32 size ) vg_allocation_meta *meta = &alloc->alloc_table[ alloc->allocation_count ]; meta->type = k_allocation_type_block; meta->data = data; + meta->size = size; + meta->name = constr_name; } else{ data = buffer + alloc->cur; @@ -152,7 +214,7 @@ VG_STATIC void *vg_linear_alloc( void *buffer, u32 size ) /* resize latest block of memory from linear */ __attribute__((warn_unused_result)) -VG_STATIC void *vg_linear_resize( void *buffer, void *data, u32 newsize ) +static void *vg_linear_resize( void *buffer, void *data, u32 newsize ) { vg_linear_allocator *alloc = vg_linear_header( buffer ); @@ -187,7 +249,7 @@ VG_STATIC void *vg_linear_resize( void *buffer, void *data, u32 newsize ) } /* its possible to delete just the last item */ -VG_STATIC void vg_linear_del( void *buffer, void *data ) +static void vg_linear_del( void *buffer, void *data ) { vg_linear_allocator *alloc = vg_linear_header( buffer ); @@ -212,10 +274,11 @@ VG_STATIC void vg_linear_del( void *buffer, void *data ) /* extend latest block of memory from linear */ __attribute__((warn_unused_result)) -VG_STATIC void *vg_linear_extend( void *buffer, void *data, u32 extra ) +static void *_vg_linear_extend( void *buffer, void *data, u32 extra, + const char *constr_name ) { if( !data ) - return vg_linear_alloc( buffer, extra ); + return _vg_linear_alloc( buffer, extra, constr_name ); vg_linear_allocator *alloc = vg_linear_header( buffer ); @@ -227,28 +290,28 @@ VG_STATIC void *vg_linear_extend( void *buffer, void *data, u32 extra ) } /* get the current usage of allocator */ -VG_STATIC u32 vg_linear_get_cur( void *buffer ) +static u32 vg_linear_get_cur( void *buffer ) { vg_linear_allocator *alloc = vg_linear_header( buffer ); return alloc->cur; } /* get the capacity of allocator. */ -VG_STATIC u32 vg_linear_get_capacity( void *buffer ) +static u32 vg_linear_get_capacity( void *buffer ) { vg_linear_allocator *alloc = vg_linear_header( buffer ); return alloc->size; } /* get the remaining size of the allocator */ -VG_STATIC u32 vg_linear_remaining( void *buffer ) +static u32 vg_linear_remaining( void *buffer ) { vg_linear_allocator *alloc = vg_linear_header( buffer ); return alloc->size - alloc->cur; } /* yeet all memory from linear allocator */ -VG_STATIC void vg_linear_clear( void *buffer ) +static void vg_linear_clear( void *buffer ) { vg_linear_allocator *alloc = vg_linear_header( buffer ); @@ -277,8 +340,8 @@ VG_STATIC void vg_linear_clear( void *buffer ) } /* allocate a FIXED SIZE linear allocator */ -VG_STATIC void *vg_create_linear_allocator( void *lin_alloc, u32 size, - u16 flags ) +static void *_vg_create_linear_allocator( void *lin_alloc, u32 size, + u16 flags, const char *constr_name) { assert( sizeof( vg_linear_allocator ) == 32 ); @@ -310,6 +373,8 @@ VG_STATIC void *vg_create_linear_allocator( void *lin_alloc, u32 size, meta->data = header+1; meta->type = k_allocation_type_linear; + meta->size = size; + meta->name = constr_name; } else{ header = lin_alloc + alloc->cur; @@ -345,20 +410,56 @@ VG_STATIC void *vg_create_linear_allocator( void *lin_alloc, u32 size, } /* request all the memory we need in advance */ -VG_STATIC void vg_set_mem_quota( u32 size ) +static void vg_set_mem_quota( u32 size ) { vg_mem.quota = size; } -VG_STATIC void vg_alloc_quota(void) +static void vg_alloc_quota(void) { u32 size_scratch = 10*1024*1024; u32 size = VG_MAX( vg_mem.quota, size_scratch ); - vg_mem.rtmemory = vg_create_linear_allocator( NULL, size, VG_MEMORY_SYSTEM ); - vg_mem.scratch = vg_create_linear_allocator( vg_mem.rtmemory, - size_scratch, - VG_MEMORY_SYSTEM ); + vg_mem.rtmemory = _vg_create_linear_allocator( NULL, size, VG_MEMORY_SYSTEM, + "VG Root" ); + vg_mem.scratch = _vg_create_linear_allocator( vg_mem.rtmemory, + size_scratch, + VG_MEMORY_SYSTEM, + "Scratch buffer" ); +} + +static void vg_mem_log( void *lin_alloc, int depth, const char *name ) +{ + if( vg_mem.use_libc_malloc ){ + vg_linear_allocator *alloc = vg_linear_header( lin_alloc ); + + u32 s = alloc->size; + f32 p = ((float)alloc->cur / (float)alloc->size) * 100.0f; + + for( int i=0; iflags & VG_MEMORY_SYSTEM ){ + for( u32 i=0; iallocation_count; i++ ){ + vg_allocation_meta *meta = &alloc->alloc_table[i]; + + if( meta->type == k_allocation_type_block ){ + for( int i=0; iname, meta->size ); + } + else{ + vg_mem_log( meta->data, depth +1, meta->name ); + } + } + } + else{ + for( int i=0; i (UNTRACKED)\n" ); + } + } + else{ + vg_error( "allocations are not tracked (turn on libc mode)\n" ); + } } #endif /* VG_MEM_H */