5 #include "vg_platform.h"
9 typedef struct vg_linear_allocator vg_linear_allocator
;
19 struct vg_linear_allocator
23 /* allows temporarily extendable buffers */
30 * TODO: Fallback on libc
31 * TODO: 8 byte alignment
34 VG_STATIC
void vg_error(const char *fmt
, ...);
36 /* allocate something from a linear allocator */
37 __attribute__((warn_unused_result
))
38 VG_STATIC
void *vg_linear_alloc( void *allocator
, u32 size
)
40 if( allocator
== NULL
)
41 vg_fatal_exit_loop( "Null allocator" );
43 vg_linear_allocator
*allocptr
= allocator
;
46 if( allocptr
->cur
+ size
> allocptr
->size
)
48 vg_error( "%u(current) + %u(alloc) > %u(max)\n",
49 allocptr
->cur
, size
, allocptr
->size
);
51 vg_fatal_exit_loop( "Linear allocator out of memory" );
54 void *data
= allocator
+ allocptr
->cur
;
55 allocptr
->cur
+= size
;
56 allocptr
->last_alloc
= data
;
57 allocptr
->last_alloc_size
= size
;
62 /* resize latest block of memory from linear */
63 __attribute__((warn_unused_result
))
64 VG_STATIC
void *vg_linear_resize( void *allocator
, void *data
, u32 newsize
)
66 vg_linear_allocator
*allocptr
= allocator
;
69 if( allocptr
->last_alloc
== data
)
71 allocptr
->cur
-= allocptr
->last_alloc_size
;
72 return vg_linear_alloc( allocator
, newsize
);
76 vg_fatal_exit_loop( "Cannot resize this buffer anymore" );
82 VG_STATIC
void vg_linear_del( void *allocator
, void *data
)
84 void *ignore
= vg_linear_resize( allocator
, data
, 0 );
86 vg_linear_allocator
*allocptr
= allocator
;
89 allocptr
->last_alloc
= NULL
;
90 allocptr
->last_alloc_size
= 0;
93 /* extend latest block of memory from linear */
94 __attribute__((warn_unused_result
))
95 VG_STATIC
void *vg_linear_extend( void *allocator
, void *data
, u32 extra
)
97 vg_linear_allocator
*allocptr
= allocator
;
100 return vg_linear_resize( allocator
, data
, allocptr
->last_alloc_size
+extra
);
103 /* get the current usage of allocator */
104 VG_STATIC u32
vg_linear_get_cur( void *allocator
)
106 vg_linear_allocator
*allocptr
= allocator
;
109 return allocptr
->cur
;
112 /* get the capacity of allocator */
113 VG_STATIC u32
vg_linear_get_capacity( void *allocator
)
115 vg_linear_allocator
*allocptr
= allocator
;
118 return allocptr
->size
;
121 /* get the size of the last allocated thing */
122 VG_STATIC u32
vg_linear_last_size( void *allocator
)
124 vg_linear_allocator
*allocptr
= allocator
;
127 return allocptr
->last_alloc_size
;
130 /* yeet all memory from linear allocator */
131 VG_STATIC
void vg_linear_clear( void *allocator
)
133 vg_linear_allocator
*allocptr
= allocator
;
136 allocptr
->last_alloc
= NULL
;
137 allocptr
->last_alloc_size
= 0;
141 /* allocate a FIXED SIZE linear allocator */
142 VG_STATIC
void *vg_create_linear_allocator( void *lin_alloc
, u32 size
)
144 u32 total
= size
+ sizeof(vg_linear_allocator
);
145 vg_linear_allocator
*allocptr
;
147 if( lin_alloc
== NULL
)
149 static int allow_once
= 1;
153 allocptr
= malloc( total
);
155 if( allocptr
== NULL
)
156 vg_fatal_exit_loop( "Create linear: Malloc failed" );
161 vg_fatal_exit_loop( "Shouldnt call this twice!" );
165 vg_linear_allocator
*parent
= lin_alloc
;
168 allocptr
= vg_linear_alloc( lin_alloc
, total
);
171 parent
->last_alloc
= allocptr
+1;
172 parent
->last_alloc_size
= total
;
174 parent
->last_alloc
= NULL
;
175 parent
->last_alloc_size
= total
;
179 allocptr
->size
= size
;
181 allocptr
->last_alloc
= NULL
;
182 allocptr
->last_alloc_size
= 0;
184 void *data
= allocptr
+1;
188 /* request all the memory we need in advance */
189 VG_STATIC
void vg_prealloc_quota( u32 size
)
191 size
= VG_MAX( size
, 20*1024*1024 );
192 vg_mem
.rtmemory
= vg_create_linear_allocator( NULL
, size
);
193 vg_mem
.scratch
= vg_create_linear_allocator( vg_mem
.rtmemory
, 10*1024*1024 );
196 #endif /* VG_MEM_H */