1/*
2 * queue.c, queue
3 *
4 * Copyright (c) 2009-2010 Wind River Systems, Inc.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19#include <stdlib.h>
20
21#include <queue.h>
22
23inline void __queue_init(struct queue *queue)
24{
25	queue->head = NULL;
26	queue->tail = NULL;
27	queue->length = 0;
28}
29
30struct queue *queue_alloc(void)
31{
32	struct queue *queue;
33
34	queue = malloc(sizeof(struct queue));
35	if (queue)
36		__queue_init(queue);
37
38	return queue;
39}
40
41inline void __queue_free(struct queue *queue)
42{
43	free(queue);
44}
45
46void queue_free_all(struct queue *queue)
47{
48	struct list *list = queue->head;
49
50	list_free_all(list);
51	__queue_init(queue);
52}
53
54void __queue_push_head(struct queue *queue, struct list *entry)
55{
56	queue->head = __list_add_head(queue->head, entry);
57	if (!queue->tail)
58		queue->tail = queue->head;
59
60	queue->length++;
61}
62
63int queue_push_head(struct queue *queue, void *data)
64{
65	struct list *entry = list_alloc(data);
66
67	if (!entry)
68		return -1;
69	else
70		queue->head = __list_add_head(queue->head, entry);
71
72	if (!queue->tail)
73		queue->tail = queue->head;
74
75	queue->length++;
76        return 0;
77}
78
79void __queue_push_tail(struct queue *queue, struct list *entry)
80{
81        queue->tail = list_add_tail(queue->tail, entry);
82        if (queue->tail == NULL) {
83                return;
84        }
85	if (queue->tail->next)
86		queue->tail = queue->tail->next;
87	else
88		queue->head = queue->tail;
89
90	queue->length++;
91}
92
93int queue_push_tail(struct queue *queue, void *data)
94{
95	struct list *entry = list_alloc(data);
96
97	if (!entry)
98		return -1;
99	else
100		queue->tail = __list_add_tail(queue->tail, entry);
101
102	if (queue->tail->next)
103		queue->tail = queue->tail->next;
104	else
105		queue->head = queue->tail;
106
107	queue->length++;
108        return 0;
109}
110
111struct list *__queue_pop_head(struct queue *queue)
112{
113	struct list *entry = queue->head;
114
115	if (entry) {
116		queue->head = __list_remove(queue->head, entry);
117		if (!queue->head)
118			queue->tail = NULL;
119
120		queue->length--;
121	}
122
123	return entry;
124}
125
126void *queue_pop_head(struct queue *queue)
127{
128	struct list *entry;
129	void *data = NULL;
130
131	entry = __queue_pop_head(queue);
132	if (entry) {
133		data = entry->data;
134		__list_free(entry);
135	}
136
137	return data;
138}
139
140struct list *__queue_pop_tail(struct queue *queue)
141{
142	struct list *entry = queue->tail;
143	struct list *prev;
144
145	if (entry) {
146		prev = entry->prev;
147		queue->head = __list_remove(queue->head, entry);
148		queue->tail = prev;
149		queue->length--;
150	}
151
152	return entry;
153}
154
155void *queue_pop_tail(struct queue *queue)
156{
157	struct list *entry;
158	void *data = NULL;
159
160	entry = __queue_pop_tail(queue);
161	if (entry) {
162		data = entry->data;
163		__list_free(entry);
164	}
165
166	return data;
167}
168
169inline struct list *__queue_peek_head(struct queue *queue)
170{
171	return queue->head;
172}
173
174inline struct list *__queue_peek_tail(struct queue *queue)
175{
176	return queue->tail;
177}
178
179inline void *queue_peek_head(struct queue *queue)
180{
181	struct list *entry;
182	void *data = NULL;
183
184	entry = __queue_peek_head(queue);
185	if (entry)
186		data = entry->data;
187
188	return data;
189}
190
191inline void *queue_peek_tail(struct queue *queue)
192{
193	struct list *entry;
194	void *data = NULL;
195
196	entry = __queue_peek_tail(queue);
197	if (entry)
198		data = entry->data;
199
200	return data;
201}
202
203int queue_length(struct queue *queue)
204{
205	return queue->length;
206}
207