--- /dev/null
+#include "vg_platform.h"
+#include "vg_mem.h"
+#include "vg_mem_queue.h"
+#include <stddef.h>
+#include <string.h>
+
+/*
+ * 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);
+}