create vg memory queue
authorhgn <hgodden00@gmail.com>
Thu, 12 Oct 2023 11:42:23 +0000 (12:42 +0100)
committerhgn <hgodden00@gmail.com>
Thu, 12 Oct 2023 11:42:23 +0000 (12:42 +0100)
vg_mem_queue.h [new file with mode: 0644]

diff --git a/vg_mem_queue.h b/vg_mem_queue.h
new file mode 100644 (file)
index 0000000..8cd054b
--- /dev/null
@@ -0,0 +1,90 @@
+#ifndef VG_MEM_QUEUE_H
+#define VG_MEM_QUEUE_H
+
+#include "vg_mem.h"
+#include "vg_stdint.h"
+
+typedef struct vg_queue vg_queue;
+typedef struct vg_queue_frame vg_queue_frame;
+
+struct vg_queue {
+   u8 *buffer;
+   u32 size;
+   
+   struct vg_queue_frame {
+      u32 alloc_size,size;
+      u8 data[];
+   }
+   *head, *tail;
+};
+
+/*
+ * Allocate memory on the queue. Returns NULL if allocation failed for any
+ * any reason.
+ */
+static 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 
+ */
+static 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);
+}
+
+#endif /* VG_MEM_QUEUE_H */