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