typedef struct vg_linear_allocator vg_linear_allocator;
typedef struct vg_allocation_meta vg_allocation_meta;
-struct
-{
+struct{
void *rtmemory,
*scratch;
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;
/* allocate something from a linear allocator */
__attribute__((warn_unused_result))
-VG_STATIC void *vg_linear_alloc( void *buffer, u32 size )
+VG_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 );
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;
/* extend latest block of memory from linear */
__attribute__((warn_unused_result))
-VG_STATIC void *vg_linear_extend( void *buffer, void *data, u32 extra )
+VG_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 );
}
/* allocate a FIXED SIZE linear allocator */
-VG_STATIC void *vg_create_linear_allocator( void *lin_alloc, u32 size,
- u16 flags )
+VG_STATIC void *_vg_create_linear_allocator( void *lin_alloc, u32 size,
+ u16 flags, const char *constr_name)
{
assert( sizeof( vg_linear_allocator ) == 32 );
meta->data = header+1;
meta->type = k_allocation_type_linear;
+ meta->size = size;
+ meta->name = constr_name;
}
else{
header = lin_alloc + alloc->cur;
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" );
+}
+
+VG_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; i<depth; i++ ) printf( " " );
+ printf( "LA(%s): %u bytes, %f%% used\n", name, s, p );
+
+ if( alloc->flags & VG_MEMORY_SYSTEM ){
+ for( u32 i=0; i<alloc->allocation_count; i++ ){
+ vg_allocation_meta *meta = &alloc->alloc_table[i];
+
+ if( meta->type == k_allocation_type_block ){
+ for( int i=0; i<depth+1; i++ ) printf( " " );
+ printf( "B(%s): %u bytes\n", meta->name, meta->size );
+ }
+ else{
+ vg_mem_log( meta->data, depth +1, meta->name );
+ }
+ }
+ }
+ else{
+ for( int i=0; i<depth+1; i++ ) printf( " " );
+ printf( "<opaque memory> (UNTRACKED)\n" );
+ }
+ }
+ else{
+ vg_error( "allocations are not tracked (turn on libc mode)\n" );
+ }
}
+#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__) )
+
+
#endif /* VG_MEM_H */