5 #include "vg_platform.h"
10 typedef struct vg_linear_allocator vg_linear_allocator
;
19 struct vg_linear_allocator
23 /* allows temporarily extendable buffers */
29 * TODO: Fallback on libc
32 VG_STATIC
void vg_error(const char *fmt
, ...);
34 /* allocate something from a linear allocator */
35 __attribute__((warn_unused_result
))
36 VG_STATIC
void *vg_linear_alloc( void *allocator
, u32 size
)
42 if( allocator
== NULL
)
43 vg_fatal_exit_loop( "Null allocator" );
45 vg_linear_allocator
*allocptr
= allocator
;
48 if( allocptr
->cur
+ size
> allocptr
->size
)
50 vg_error( "%u(current) + %u(alloc) > %u(max)\n",
51 allocptr
->cur
, size
, allocptr
->size
);
53 vg_fatal_exit_loop( "Linear allocator out of memory" );
56 void *data
= allocator
+ allocptr
->cur
;
57 allocptr
->cur
+= size
;
58 allocptr
->last_alloc
= data
;
59 allocptr
->last_alloc_size
= size
;
64 /* resize latest block of memory from linear */
65 __attribute__((warn_unused_result
))
66 VG_STATIC
void *vg_linear_resize( void *allocator
, void *data
, u32 newsize
)
68 vg_linear_allocator
*allocptr
= allocator
;
71 if( allocptr
->last_alloc
== data
)
73 allocptr
->cur
-= allocptr
->last_alloc_size
;
74 return vg_linear_alloc( allocator
, newsize
);
78 vg_fatal_exit_loop( "Cannot resize this buffer anymore" );
84 VG_STATIC
void vg_linear_del( void *allocator
, void *data
)
86 void *ignore
= vg_linear_resize( allocator
, data
, 0 );
88 vg_linear_allocator
*allocptr
= allocator
;
91 allocptr
->last_alloc
= NULL
;
92 allocptr
->last_alloc_size
= 0;
95 /* extend latest block of memory from linear */
96 __attribute__((warn_unused_result
))
97 VG_STATIC
void *vg_linear_extend( void *allocator
, void *data
, u32 extra
)
99 vg_linear_allocator
*allocptr
= allocator
;
102 return vg_linear_resize( allocator
, data
, allocptr
->last_alloc_size
+extra
);
105 /* get the current usage of allocator */
106 VG_STATIC u32
vg_linear_get_cur( void *allocator
)
108 vg_linear_allocator
*allocptr
= allocator
;
111 return allocptr
->cur
;
114 /* get the capacity of allocator */
115 VG_STATIC u32
vg_linear_get_capacity( void *allocator
)
117 vg_linear_allocator
*allocptr
= allocator
;
120 return allocptr
->size
;
123 /* get the size of the last allocated thing */
124 VG_STATIC u32
vg_linear_last_size( void *allocator
)
126 vg_linear_allocator
*allocptr
= allocator
;
129 return allocptr
->last_alloc_size
;
132 /* yeet all memory from linear allocator */
133 VG_STATIC
void vg_linear_clear( void *allocator
)
135 vg_linear_allocator
*allocptr
= allocator
;
138 allocptr
->last_alloc
= NULL
;
139 allocptr
->last_alloc_size
= 0;
143 /* allocate a FIXED SIZE linear allocator */
144 VG_STATIC
void *vg_create_linear_allocator( void *lin_alloc
, u32 size
)
146 u32 total
= size
+ sizeof(vg_linear_allocator
);
147 vg_linear_allocator
*allocptr
;
149 if( lin_alloc
== NULL
)
151 static int allow_once
= 1;
155 allocptr
= malloc( total
);
157 if( allocptr
== NULL
)
158 vg_fatal_exit_loop( "Create linear: Malloc failed" );
163 vg_fatal_exit_loop( "Shouldnt call this twice!" );
167 vg_linear_allocator
*parent
= lin_alloc
;
170 allocptr
= vg_linear_alloc( lin_alloc
, total
);
173 parent
->last_alloc
= allocptr
+1;
174 parent
->last_alloc_size
= total
;
176 parent
->last_alloc
= NULL
;
177 parent
->last_alloc_size
= total
;
181 allocptr
->size
= size
;
183 allocptr
->last_alloc
= NULL
;
184 allocptr
->last_alloc_size
= 0;
186 void *data
= allocptr
+1;
190 /* request all the memory we need in advance */
191 VG_STATIC
void vg_prealloc_quota( u32 size
)
193 size
= VG_MAX( size
, 20*1024*1024 );
194 vg_mem
.rtmemory
= vg_create_linear_allocator( NULL
, size
);
195 vg_mem
.scratch
= vg_create_linear_allocator( vg_mem
.rtmemory
, 10*1024*1024 );
198 #endif /* VG_MEM_H */