xref: /inferno-os/os/boot/puma/qio.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1 #include "u.h"
2 #include "lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "io.h"
7 
8 struct Queue {
9 	Block*	first;
10 	Block*	last;
11 	void	(*kick)(void*);
12 	void*	arg;
13 	long	len;
14 };
15 
16 Block *
iallocb(int n)17 iallocb(int n)
18 {
19 	Block *b;
20 
21 	b = (Block*)malloc(sizeof(Block)+n);
22 	b->data = (uchar*)b + sizeof(Block);
23 	b->rp = b->wp = b->data;
24 	b->lim = b->data + n;
25 	b->next = 0;
26 	b->magic = 0xcafebee0;
27 	return b;
28 }
29 
30 void
freeb(Block * b)31 freeb(Block *b)
32 {
33 	if(b){
34 		if(b->magic != 0xcafebee0)
35 			panic("freeb");
36 		b->magic = 0;
37 		b->next = (Block*)0xdeadbabe;
38 		free(b);
39 	}
40 }
41 
42 Queue *
qopen(int limit,int msg,void (* kick)(void *),void * arg)43 qopen(int limit, int msg, void (*kick)(void*), void *arg)
44 {
45 	Queue *q;
46 
47 	USED(limit, msg);
48 	q = (Queue*)malloc(sizeof(Queue));
49 	q->first = q->last = 0;
50 	q->kick = kick;
51 	q->arg = arg;
52 	q->len = 0;
53 	return q;
54 }
55 
56 Block *
qget(Queue * q)57 qget(Queue *q)
58 {
59 	int s;
60 	Block *b;
61 
62 	s = splhi();
63 	if((b = q->first) != 0){
64 		q->first = b->next;
65 		b->next = 0;
66 		q->len -= BLEN(b);
67 		if(q->len < 0)
68 			panic("qget");
69 	}
70 	splx(s);
71 	return b;
72 }
73 
74 void
qbwrite(Queue * q,Block * b)75 qbwrite(Queue *q, Block *b)
76 {
77 	int s;
78 
79 	s = splhi();
80 	b->next = 0;
81 	if(q->first == 0)
82 		q->first = b;
83 	else
84 		q->last->next = b;
85 	q->last = b;
86 	q->len += BLEN(b);
87 	splx(s);
88 	if(q->kick)
89 		q->kick(q->arg);
90 }
91 
92 long
qlen(Queue * q)93 qlen(Queue *q)
94 {
95 	return q->len;
96 }
97 
98 int
qbgetc(Queue * q)99 qbgetc(Queue *q)
100 {
101 	Block *b;
102 	int s, c;
103 
104 	c = -1;
105 	s = splhi();
106 	while(c < 0 && (b = q->first) != nil){
107 		if(b->rp < b->wp){
108 			c = *b->rp++;
109 			q->len--;
110 		}
111 		if(b->rp >= b->wp){
112 			q->first = b->next;
113 			b->next = nil;
114 		}
115 	}
116 	splx(s);
117 	return c;
118 }
119 
120 void
qbputc(Queue * q,int c)121 qbputc(Queue *q, int c)
122 {
123 	Block *b;
124 
125 	b = iallocb(1);
126 	*b->wp++ = c;
127 	qbwrite(q, b);
128 }
129