create vg memory queue
[vg.git] / vg_mem_queue.h
1 #ifndef VG_MEM_QUEUE_H
2 #define VG_MEM_QUEUE_H
3
4 #include "vg_mem.h"
5 #include "vg_stdint.h"
6
7 typedef struct vg_queue vg_queue;
8 typedef struct vg_queue_frame vg_queue_frame;
9
10 struct vg_queue {
11 u8 *buffer;
12 u32 size;
13
14 struct vg_queue_frame {
15 u32 alloc_size,size;
16 u8 data[];
17 }
18 *head, *tail;
19 };
20
21 /*
22 * Allocate memory on the queue. Returns NULL if allocation failed for any
23 * any reason.
24 */
25 static vg_queue_frame *vg_queue_alloc( vg_queue *q, u32 size ){
26 u32 total = vg_align8(size) + sizeof(vg_queue_frame);
27 vg_queue_frame *frame = NULL;
28
29 if( total > q->size )
30 return NULL;
31
32 if( q->head ){
33 u32 end = ((u8 *)q->head - q->buffer) + q->head->alloc_size,
34 start = ((u8 *)q->tail - q->buffer),
35 r0 = 0,
36 r1 = 0;
37
38 if( start < end ){
39 r0 = q->size-end;
40 r1 = start;
41 }
42 else
43 r0 = start - end;
44
45 if( total < r0 ){
46 frame = (vg_queue_frame *)(q->buffer + end);
47 }
48 else {
49 if( total < r1 ){
50 q->head->alloc_size += r0;
51 frame = (vg_queue_frame *)q->buffer;
52 }
53 }
54
55 if( !frame ) return NULL;
56 }
57 else{
58 frame = (vg_queue_frame *)q->buffer;
59 q->tail = frame;
60 }
61
62 memset( frame, 0, sizeof(vg_queue_frame) );
63
64 q->head = frame;
65 frame->alloc_size = total;
66 frame->size = size;
67
68 return frame;
69 }
70
71 /*
72 * Free last item from queue
73 */
74 static void vg_queue_pop( vg_queue *q ){
75 if( q->head == q->tail ){
76 q->head = NULL;
77 q->tail = NULL;
78 return;
79 }
80
81 u32 start = ((u8 *)q->tail - q->buffer);
82 start += q->tail->alloc_size;
83
84 if( start == q->size )
85 start = 0;
86
87 q->tail = (vg_queue_frame *)(q->buffer + start);
88 }
89
90 #endif /* VG_MEM_QUEUE_H */