#include <stdlib.h>
#include <malloc.h>
-#define VG_MAX_ALLOCATIONS 64
+VG_STATIC void vg_print_backtrace(void);
+
+#define VG_MAX_ALLOCATIONS 128
#define VG_FUZZ_ALLOCATIONS
typedef struct vg_linear_allocator vg_linear_allocator;
struct
{
void *rtmemory,
- *scratch;
+ *scratch,
+ *async;
int use_libc_malloc;
u32 quota;
__attribute__((warn_unused_result))
VG_STATIC void *vg_linear_alloc( void *buffer, u32 size )
{
- if( size % 8 )
- {
+ if( size % 8 ){
vg_error( "alloc(%u) is not 8 byte aligned\n", size );
+ vg_print_backtrace();
size = vg_align8( size );
}
+#ifdef _WIN32
+ if( ((u32)buffer) % 8 ){
+#else
+ if( ((u64)buffer) % 8 ){
+#endif
+ vg_error( "buffer: %p\n", buffer );
+ vg_fatal_exit_loop( "unaligned buffer" );
+ }
vg_linear_allocator *alloc = vg_linear_header( buffer );
- if( (alloc->cur + size) > alloc->size )
- {
+ if( (alloc->cur + size) > alloc->size ){
vg_error( "%u + %u > %u\n", alloc->cur, size, alloc->size );
vg_fatal_exit_loop( "linear allocator overflow" );
}
void *data;
- if( vg_mem.use_libc_malloc && (alloc->flags & VG_MEMORY_SYSTEM) )
- {
+ if( vg_mem.use_libc_malloc && (alloc->flags & VG_MEMORY_SYSTEM) ){
data = malloc( size );
vg_allocation_meta *meta = &alloc->alloc_table[ alloc->allocation_count ];
meta->type = k_allocation_type_block;
meta->data = data;
}
- else
- {
+ else{
data = buffer + alloc->cur;
}
+ u8 *bytes = data;
+ for( u32 i=0; i<size; i++ ){
+ bytes[i] = 0xae;
+ }
+
alloc->allocation_count ++;
alloc->last_alloc = data;
alloc->last_alloc_size = size;
alloc->cur += size;
+#ifdef _WIN32
+ if( ((u32)data) % 8 ){
+#else
+ if( ((u64)data) % 8 ){
+#endif
+ vg_fatal_exit_loop( "unaligned" );
+ }
+
return data;
}
-
/* resize latest block of memory from linear */
__attribute__((warn_unused_result))
VG_STATIC void *vg_linear_resize( void *buffer, void *data, u32 newsize )
{
vg_linear_allocator *alloc = vg_linear_header( buffer );
+ if( newsize % 8 ){
+ vg_error( "alloc(%u) is not 8 byte aligned\n", newsize );
+ vg_print_backtrace();
+ newsize = vg_align8( newsize );
+ }
+
if( alloc->last_alloc != data )
vg_fatal_exit_loop( "This block has been fixed!" );
alloc->cur += newsize;
alloc->last_alloc_size = newsize;
- if( vg_mem.use_libc_malloc && (alloc->flags & VG_MEMORY_SYSTEM) )
- {
+ if( vg_mem.use_libc_malloc && (alloc->flags & VG_MEMORY_SYSTEM) ){
data = realloc( data, newsize );
if( !data )
vg_fatal_exit_loop( "realloc failed" );
alloc->last_alloc = data;
return data;
}
- else
- {
+ else{
return data;
}
}
if( alloc->last_alloc != data )
vg_fatal_exit_loop( "This block has been fixed!" );
- if( vg_mem.use_libc_malloc && (alloc->flags & VG_MEMORY_SYSTEM) )
- {
+ if( vg_mem.use_libc_malloc && (alloc->flags & VG_MEMORY_SYSTEM) ){
vg_allocation_meta *meta = &alloc->alloc_table[alloc->allocation_count-1];
if( meta->type == k_allocation_type_linear )
vg_fatal_exit_loop( "Cannot free a linear allocator in this conext" );
__attribute__((warn_unused_result))
VG_STATIC void *vg_linear_extend( void *buffer, void *data, u32 extra )
{
+ if( !data )
+ return vg_linear_alloc( buffer, extra );
+
vg_linear_allocator *alloc = vg_linear_header( buffer );
if( alloc->last_alloc != data )
vg_linear_allocator *alloc = vg_linear_header( buffer );
/* libc mode we recursively free any allocations made */
- if( vg_mem.use_libc_malloc && (alloc->flags & VG_MEMORY_SYSTEM) )
- {
- for( u32 i=0; i<alloc->allocation_count; i++ )
- {
+ if( vg_mem.use_libc_malloc && (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 )
- {
+ if( meta->type == k_allocation_type_block ){
free( meta->data );
}
- else
- {
+ else{
vg_linear_clear( meta->data );
vg_linear_allocator *sub = vg_linear_header( meta->data );
u32 block_size = size + sizeof(vg_linear_allocator);
/* Creating it inside an existing one */
- if( lin_alloc )
- {
+ if( lin_alloc ){
vg_linear_allocator *alloc = vg_linear_header( lin_alloc );
if( alloc->cur + block_size > alloc->size )
vg_fatal_exit_loop( "Cannot declare realtime allocator inside systems"
" allocator" );
- if( vg_mem.use_libc_malloc )
- {
+ if( vg_mem.use_libc_malloc ){
vg_allocation_meta *meta =
&alloc->alloc_table[ alloc->allocation_count ];
meta->data = header+1;
meta->type = k_allocation_type_linear;
}
- else
- {
+ else{
header = lin_alloc + alloc->cur;
}
alloc->allocation_count ++;
}
- else
- {
+ else{
if( vg_mem.use_libc_malloc && (flags & VG_MEMORY_SYSTEM) )
header = malloc( sizeof(vg_linear_allocator) );
else
header->size = size;
header->flags = flags;
- if( vg_mem.use_libc_malloc && (flags & VG_MEMORY_SYSTEM) )
- {
+ if( vg_mem.use_libc_malloc && (flags & VG_MEMORY_SYSTEM) ){
u32 table_size = sizeof(vg_allocation_meta)*VG_MAX_ALLOCATIONS;
header->alloc_table = malloc( table_size );
}
vg_mem.scratch = vg_create_linear_allocator( vg_mem.rtmemory,
size_scratch,
VG_MEMORY_SYSTEM );
+
+ vg_mem.async = vg_create_linear_allocator( NULL, 50*1024*1024,
+ VG_MEMORY_REALTIME );
}
#endif /* VG_MEM_H */