X-Git-Url: https://harrygodden.com/git/?p=vg.git;a=blobdiff_plain;f=vg_mem_queue.c;fp=vg_mem_queue.c;h=3b1a9d64ccf80fab6b306a7370ea5cf30310ab16;hp=0000000000000000000000000000000000000000;hb=3b14f3dcd5bf9dd3c85144f2123d667bfa4bb63f;hpb=fce86711735b15bff37de0f70716808410fcf269 diff --git a/vg_mem_queue.c b/vg_mem_queue.c new file mode 100644 index 0000000..3b1a9d6 --- /dev/null +++ b/vg_mem_queue.c @@ -0,0 +1,77 @@ +#include "vg_platform.h" +#include "vg_mem.h" +#include "vg_mem_queue.h" +#include +#include + +/* + * Allocate memory on the queue. Returns NULL if allocation failed for any + * any reason. + */ +vg_queue_frame *vg_queue_alloc( vg_queue *q, u32 size ) +{ + u32 total = vg_align8(size) + sizeof(vg_queue_frame); + vg_queue_frame *frame = NULL; + + if( total > q->size ) + return NULL; + + if( q->head ) + { + u32 end = ((u8 *)q->head - q->buffer) + q->head->alloc_size, + start = ((u8 *)q->tail - q->buffer), + r0 = 0, + r1 = 0; + + if( start < end ){ + r0 = q->size-end; + r1 = start; + } + else + r0 = start - end; + + if( total < r0 ){ + frame = (vg_queue_frame *)(q->buffer + end); + } + else { + if( total < r1 ){ + q->head->alloc_size += r0; + frame = (vg_queue_frame *)q->buffer; + } + } + + if( !frame ) return NULL; + } + else{ + frame = (vg_queue_frame *)q->buffer; + q->tail = frame; + } + + memset( frame, 0, sizeof(vg_queue_frame) ); + + q->head = frame; + frame->alloc_size = total; + frame->size = size; + + return frame; +} + +/* + * Free last item from queue + */ +void vg_queue_pop( vg_queue *q ) +{ + if( q->head == q->tail ){ + q->head = NULL; + q->tail = NULL; + return; + } + + u32 start = ((u8 *)q->tail - q->buffer); + start += q->tail->alloc_size; + + if( start == q->size ) + start = 0; + + q->tail = (vg_queue_frame *)(q->buffer + start); +}