Patch to remove segfault on the exiting of a service.
[openais.git] / include / queue.h
blob82df8a5a37cfdd577a7ad902be548cf240a5fac1
1 /*
2 * Copyright (c) 2002-2004 MontaVista Software, Inc.
4 * All rights reserved.
6 * Author: Steven Dake (sdake@mvista.com)
8 * This software licensed under BSD license, the text of which follows:
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met:
13 * - Redistributions of source code must retain the above copyright notice,
14 * this list of conditions and the following disclaimer.
15 * - Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 * - Neither the name of the MontaVista Software, Inc. nor the names of its
19 * contributors may be used to endorse or promote products derived from this
20 * software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32 * THE POSSIBILITY OF SUCH DAMAGE.
34 #ifndef QUEUE_H_DEFINED
35 #define QUEUE_H_DEFINED
37 #include <string.h>
38 #include <pthread.h>
39 #include "assert.h"
41 #ifdef OPENAIS_SOLARIS
42 /* struct queue is already defined in sys/stream.h on Solaris */
43 #define queue _queue
44 #endif
45 struct queue {
46 int head;
47 int tail;
48 int used;
49 int usedhw;
50 int size;
51 void *items;
52 int size_per_item;
53 int iterator;
54 pthread_mutex_t mutex;
57 static inline int queue_init (struct queue *queue, int queue_items, int size_per_item) {
58 queue->head = 0;
59 queue->tail = queue_items - 1;
60 queue->used = 0;
61 queue->usedhw = 0;
62 queue->size = queue_items;
63 queue->size_per_item = size_per_item;
65 queue->items = malloc (queue_items * size_per_item);
66 if (queue->items == 0) {
67 return (-ENOMEM);
69 memset (queue->items, 0, queue_items * size_per_item);
70 pthread_mutex_init (&queue->mutex, NULL);
71 return (0);
74 static inline int queue_reinit (struct queue *queue)
76 pthread_mutex_lock (&queue->mutex);
77 queue->head = 0;
78 queue->tail = queue->size - 1;
79 queue->used = 0;
80 queue->usedhw = 0;
82 memset (queue->items, 0, queue->size * queue->size_per_item);
83 pthread_mutex_unlock (&queue->mutex);
84 return (0);
87 static inline void queue_free (struct queue *queue) {
88 pthread_mutex_destroy (&queue->mutex);
89 free (queue->items);
92 static inline int queue_is_full (struct queue *queue) {
93 int full;
95 pthread_mutex_lock (&queue->mutex);
96 full = ((queue->size - 1) == queue->used);
97 pthread_mutex_unlock (&queue->mutex);
98 return (full);
101 static inline int queue_is_empty (struct queue *queue) {
102 int empty;
104 pthread_mutex_lock (&queue->mutex);
105 empty = (queue->used == 0);
106 pthread_mutex_unlock (&queue->mutex);
107 return (empty);
110 static inline void queue_item_add (struct queue *queue, void *item)
112 char *queue_item;
113 int queue_position;
115 pthread_mutex_lock (&queue->mutex);
116 queue_position = queue->head;
117 queue_item = queue->items;
118 queue_item += queue_position * queue->size_per_item;
119 memcpy (queue_item, item, queue->size_per_item);
121 assert (queue->tail != queue->head);
123 queue->head = (queue->head + 1) % queue->size;
124 queue->used++;
125 if (queue->used > queue->usedhw) {
126 queue->usedhw = queue->used;
128 pthread_mutex_unlock (&queue->mutex);
131 static inline void *queue_item_get (struct queue *queue)
133 char *queue_item;
134 int queue_position;
136 pthread_mutex_lock (&queue->mutex);
137 queue_position = (queue->tail + 1) % queue->size;
138 queue_item = queue->items;
139 queue_item += queue_position * queue->size_per_item;
140 pthread_mutex_unlock (&queue->mutex);
141 return ((void *)queue_item);
144 static inline void queue_item_remove (struct queue *queue) {
145 pthread_mutex_lock (&queue->mutex);
146 queue->tail = (queue->tail + 1) % queue->size;
148 assert (queue->tail != queue->head);
150 queue->used--;
151 assert (queue->used >= 0);
152 pthread_mutex_unlock (&queue->mutex);
155 static inline void queue_items_remove (struct queue *queue, int rel_count)
157 pthread_mutex_lock (&queue->mutex);
158 queue->tail = (queue->tail + rel_count) % queue->size;
160 assert (queue->tail != queue->head);
162 queue->used -= rel_count;
163 pthread_mutex_unlock (&queue->mutex);
167 static inline void queue_item_iterator_init (struct queue *queue)
169 pthread_mutex_lock (&queue->mutex);
170 queue->iterator = (queue->tail + 1) % queue->size;
171 pthread_mutex_unlock (&queue->mutex);
174 static inline void *queue_item_iterator_get (struct queue *queue)
176 char *queue_item;
177 int queue_position;
179 pthread_mutex_lock (&queue->mutex);
180 queue_position = (queue->iterator) % queue->size;
181 if (queue->iterator == queue->head) {
182 pthread_mutex_unlock (&queue->mutex);
183 return (0);
185 queue_item = queue->items;
186 queue_item += queue_position * queue->size_per_item;
187 pthread_mutex_unlock (&queue->mutex);
188 return ((void *)queue_item);
191 static inline int queue_item_iterator_next (struct queue *queue)
193 int next_res;
195 pthread_mutex_lock (&queue->mutex);
196 queue->iterator = (queue->iterator + 1) % queue->size;
198 next_res = queue->iterator == queue->head;
199 pthread_mutex_unlock (&queue->mutex);
200 return (next_res);
203 static inline void queue_avail (struct queue *queue, int *avail)
205 pthread_mutex_lock (&queue->mutex);
206 *avail = queue->size - queue->used - 2;
207 assert (*avail >= 0);
208 pthread_mutex_unlock (&queue->mutex);
211 static inline int queue_used (struct queue *queue) {
212 int used;
214 pthread_mutex_lock (&queue->mutex);
215 used = queue->used;
216 pthread_mutex_unlock (&queue->mutex);
218 return (used);
221 static inline int queue_usedhw (struct queue *queue) {
222 int usedhw;
224 pthread_mutex_lock (&queue->mutex);
225 usedhw = queue->usedhw;
226 pthread_mutex_unlock (&queue->mutex);
228 return (usedhw);
231 #endif /* QUEUE_H_DEFINED */