xref: /haiku/src/system/kernel/util/queue.cpp (revision cee04e8074ec61fd8c6dac3539c5b821c3618888)
1*bd185b41SIngo Weinhold /* Standard queue */
2*bd185b41SIngo Weinhold 
3*bd185b41SIngo Weinhold /*
4*bd185b41SIngo Weinhold ** Copyright 2001, Travis Geiselbrecht. All rights reserved.
5*bd185b41SIngo Weinhold ** Distributed under the terms of the NewOS License.
6*bd185b41SIngo Weinhold */
7*bd185b41SIngo Weinhold 
8*bd185b41SIngo Weinhold #include <kernel.h>
9*bd185b41SIngo Weinhold #include <queue.h>
10*bd185b41SIngo Weinhold #include <malloc.h>
11*bd185b41SIngo Weinhold #include <errno.h>
12*bd185b41SIngo Weinhold 
13*bd185b41SIngo Weinhold typedef struct queue_element {
14*bd185b41SIngo Weinhold 	void *next;
15*bd185b41SIngo Weinhold } queue_element;
16*bd185b41SIngo Weinhold 
17*bd185b41SIngo Weinhold typedef struct queue_typed {
18*bd185b41SIngo Weinhold 	queue_element *head;
19*bd185b41SIngo Weinhold 	queue_element *tail;
20*bd185b41SIngo Weinhold 	int count;
21*bd185b41SIngo Weinhold } queue_typed;
22*bd185b41SIngo Weinhold 
23*bd185b41SIngo Weinhold 
24*bd185b41SIngo Weinhold int
queue_init(queue * q)25*bd185b41SIngo Weinhold queue_init(queue *q)
26*bd185b41SIngo Weinhold {
27*bd185b41SIngo Weinhold 	q->head = q->tail = NULL;
28*bd185b41SIngo Weinhold 	q->count = 0;
29*bd185b41SIngo Weinhold 	return 0;
30*bd185b41SIngo Weinhold }
31*bd185b41SIngo Weinhold 
32*bd185b41SIngo Weinhold 
33*bd185b41SIngo Weinhold int
queue_remove_item(queue * _q,void * e)34*bd185b41SIngo Weinhold queue_remove_item(queue *_q, void *e)
35*bd185b41SIngo Weinhold {
36*bd185b41SIngo Weinhold 	queue_typed *q = (queue_typed *)_q;
37*bd185b41SIngo Weinhold 	queue_element *elem = (queue_element *)e;
38*bd185b41SIngo Weinhold 	queue_element *temp, *last = NULL;
39*bd185b41SIngo Weinhold 
40*bd185b41SIngo Weinhold 	temp = (queue_element *)q->head;
41*bd185b41SIngo Weinhold 	while (temp) {
42*bd185b41SIngo Weinhold 		if (temp == elem) {
43*bd185b41SIngo Weinhold 			if (last)
44*bd185b41SIngo Weinhold 				last->next = temp->next;
45*bd185b41SIngo Weinhold 			else
46*bd185b41SIngo Weinhold 				q->head = (queue_element*)temp->next;
47*bd185b41SIngo Weinhold 
48*bd185b41SIngo Weinhold 			if (q->tail == temp)
49*bd185b41SIngo Weinhold 				q->tail = last;
50*bd185b41SIngo Weinhold 			q->count--;
51*bd185b41SIngo Weinhold 			return 0;
52*bd185b41SIngo Weinhold 		}
53*bd185b41SIngo Weinhold 		last = temp;
54*bd185b41SIngo Weinhold 		temp = (queue_element*)temp->next;
55*bd185b41SIngo Weinhold 	}
56*bd185b41SIngo Weinhold 
57*bd185b41SIngo Weinhold 	return -1;
58*bd185b41SIngo Weinhold }
59*bd185b41SIngo Weinhold 
60*bd185b41SIngo Weinhold 
61*bd185b41SIngo Weinhold int
queue_enqueue(queue * _q,void * e)62*bd185b41SIngo Weinhold queue_enqueue(queue *_q, void *e)
63*bd185b41SIngo Weinhold {
64*bd185b41SIngo Weinhold 	queue_typed *q = (queue_typed *)_q;
65*bd185b41SIngo Weinhold 	queue_element *elem = (queue_element *)e;
66*bd185b41SIngo Weinhold 
67*bd185b41SIngo Weinhold 	if (q->tail == NULL) {
68*bd185b41SIngo Weinhold 		q->tail = elem;
69*bd185b41SIngo Weinhold 		q->head = elem;
70*bd185b41SIngo Weinhold 	} else {
71*bd185b41SIngo Weinhold 		q->tail->next = elem;
72*bd185b41SIngo Weinhold 		q->tail = elem;
73*bd185b41SIngo Weinhold 	}
74*bd185b41SIngo Weinhold 	elem->next = NULL;
75*bd185b41SIngo Weinhold 	q->count++;
76*bd185b41SIngo Weinhold 	return 0;
77*bd185b41SIngo Weinhold }
78*bd185b41SIngo Weinhold 
79*bd185b41SIngo Weinhold 
80*bd185b41SIngo Weinhold void *
queue_dequeue(queue * _q)81*bd185b41SIngo Weinhold queue_dequeue(queue *_q)
82*bd185b41SIngo Weinhold {
83*bd185b41SIngo Weinhold 	queue_typed *q = (queue_typed *)_q;
84*bd185b41SIngo Weinhold 	queue_element *elem;
85*bd185b41SIngo Weinhold 
86*bd185b41SIngo Weinhold 	elem = q->head;
87*bd185b41SIngo Weinhold 	if (q->head != NULL)
88*bd185b41SIngo Weinhold 		q->head = (queue_element*)q->head->next;
89*bd185b41SIngo Weinhold 	if (q->tail == elem)
90*bd185b41SIngo Weinhold 		q->tail = NULL;
91*bd185b41SIngo Weinhold 
92*bd185b41SIngo Weinhold 	if (elem != NULL)
93*bd185b41SIngo Weinhold 		q->count--;
94*bd185b41SIngo Weinhold 
95*bd185b41SIngo Weinhold 	return elem;
96*bd185b41SIngo Weinhold }
97*bd185b41SIngo Weinhold 
98*bd185b41SIngo Weinhold 
99*bd185b41SIngo Weinhold void *
queue_peek(queue * q)100*bd185b41SIngo Weinhold queue_peek(queue *q)
101*bd185b41SIngo Weinhold {
102*bd185b41SIngo Weinhold 	return q->head;
103*bd185b41SIngo Weinhold }
104*bd185b41SIngo Weinhold 
105*bd185b41SIngo Weinhold 
106*bd185b41SIngo Weinhold //	#pragma mark -
107*bd185b41SIngo Weinhold /* fixed queue stuff */
108*bd185b41SIngo Weinhold 
109*bd185b41SIngo Weinhold 
110*bd185b41SIngo Weinhold int
fixed_queue_init(fixed_queue * q,int size)111*bd185b41SIngo Weinhold fixed_queue_init(fixed_queue *q, int size)
112*bd185b41SIngo Weinhold {
113*bd185b41SIngo Weinhold 	if (size <= 0)
114*bd185b41SIngo Weinhold 		return EINVAL;
115*bd185b41SIngo Weinhold 
116*bd185b41SIngo Weinhold 	q->table = (void**)malloc(size * sizeof(void *));
117*bd185b41SIngo Weinhold 	if (!q->table)
118*bd185b41SIngo Weinhold 		return ENOMEM;
119*bd185b41SIngo Weinhold 	q->head = 0;
120*bd185b41SIngo Weinhold 	q->tail = 0;
121*bd185b41SIngo Weinhold 	q->count = 0;
122*bd185b41SIngo Weinhold 	q->size = size;
123*bd185b41SIngo Weinhold 
124*bd185b41SIngo Weinhold 	return 0;
125*bd185b41SIngo Weinhold }
126*bd185b41SIngo Weinhold 
127*bd185b41SIngo Weinhold 
128*bd185b41SIngo Weinhold void
fixed_queue_destroy(fixed_queue * q)129*bd185b41SIngo Weinhold fixed_queue_destroy(fixed_queue *q)
130*bd185b41SIngo Weinhold {
131*bd185b41SIngo Weinhold 	free(q->table);
132*bd185b41SIngo Weinhold }
133*bd185b41SIngo Weinhold 
134*bd185b41SIngo Weinhold 
135*bd185b41SIngo Weinhold int
fixed_queue_enqueue(fixed_queue * q,void * e)136*bd185b41SIngo Weinhold fixed_queue_enqueue(fixed_queue *q, void *e)
137*bd185b41SIngo Weinhold {
138*bd185b41SIngo Weinhold 	if (q->count == q->size)
139*bd185b41SIngo Weinhold 		return ENOMEM;
140*bd185b41SIngo Weinhold 
141*bd185b41SIngo Weinhold 	q->table[q->head++] = e;
142*bd185b41SIngo Weinhold 	if (q->head >= q->size)
143*bd185b41SIngo Weinhold 		q->head = 0;
144*bd185b41SIngo Weinhold 	q->count++;
145*bd185b41SIngo Weinhold 
146*bd185b41SIngo Weinhold 	return 0;
147*bd185b41SIngo Weinhold }
148*bd185b41SIngo Weinhold 
149*bd185b41SIngo Weinhold 
150*bd185b41SIngo Weinhold void *
fixed_queue_dequeue(fixed_queue * q)151*bd185b41SIngo Weinhold fixed_queue_dequeue(fixed_queue *q)
152*bd185b41SIngo Weinhold {
153*bd185b41SIngo Weinhold 	void *e;
154*bd185b41SIngo Weinhold 
155*bd185b41SIngo Weinhold 	if (q->count <= 0)
156*bd185b41SIngo Weinhold 		return NULL;
157*bd185b41SIngo Weinhold 
158*bd185b41SIngo Weinhold 	e = q->table[q->tail++];
159*bd185b41SIngo Weinhold  	if (q->tail >= q->size)
160*bd185b41SIngo Weinhold  		q->tail = 0;
161*bd185b41SIngo Weinhold 	q->count--;
162*bd185b41SIngo Weinhold 
163*bd185b41SIngo Weinhold 	return e;
164*bd185b41SIngo Weinhold }
165*bd185b41SIngo Weinhold 
166*bd185b41SIngo Weinhold 
167*bd185b41SIngo Weinhold void *
fixed_queue_peek(fixed_queue * q)168*bd185b41SIngo Weinhold fixed_queue_peek(fixed_queue *q)
169*bd185b41SIngo Weinhold {
170*bd185b41SIngo Weinhold 	if (q->count <= 0)
171*bd185b41SIngo Weinhold 		return NULL;
172*bd185b41SIngo Weinhold 
173*bd185b41SIngo Weinhold 	return q->table[q->tail];
174*bd185b41SIngo Weinhold }
175*bd185b41SIngo Weinhold 
176*bd185b41SIngo Weinhold 
177