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 allocptr
= malloc( total
);
153 if( allocptr
== NULL
)
154 vg_fatal_exit_loop( "Create linear: Malloc failed" );
158 vg_linear_allocator
*parent
= lin_alloc
;
161 allocptr
= vg_linear_alloc( lin_alloc
, total
);
164 parent
->last_alloc
= allocptr
+1;
165 parent
->last_alloc_size
= total
;
167 parent
->last_alloc
= NULL
;
168 parent
->last_alloc_size
= total
;
172 allocptr
->size
= size
;
174 allocptr
->last_alloc
= NULL
;
175 allocptr
->last_alloc_size
= 0;
177 void *data
= allocptr
+1;
181 /* request all the memory we need in advance */
182 VG_STATIC
void vg_prealloc_quota( u32 size
)
184 size
= VG_MAX( size
, 20*1024*1024 );
185 vg_mem
.rtmemory
= vg_create_linear_allocator( NULL
, size
);
186 vg_mem
.scratch
= vg_create_linear_allocator( vg_mem
.rtmemory
, 10*1024*1024 );
189 #endif /* VG_MEM_H */