Initial CVS repository import (last CVS history was lost)
[mmondor.git] / mmsoftware / mmlib / mmfifo.c
CommitLineData
47071c2b
MM
1/* $Id: mmfifo.c,v 1.1 2002/12/11 10:12:57 mmondor Exp $ */
2
3/*
4 * Copyright (C) 2000-2002, Matthew Mondor
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software written by Matthew Mondor.
18 * 4. The name of Matthew Mondor may not be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34
35
36
37#include <sys/types.h>
38
39#include <mmtypes.h>
40#include <mmstring.h>
41#include <mmfifo.h>
42
43
44
45
46MMCOPYRIGHT("@(#) Copyright (c) 2002\n\
47\tMatthew Mondor. All rights reserved.\n");
48MMRCSID("$Id: mmfifo.c,v 1.1 2002/12/11 10:12:57 mmondor Exp $");
49
50
51
52
53fifo32 *
54closefifo32(fifo32 *fifo)
55{
56 void (*freefunc)(void *) = fifo->free;
57
58 freefunc(fifo);
59
60 return (NULL);
61}
62
63
64fifo8 *
65closefifo8(fifo8 *fifo)
66{
67 void (*freefunc)(void *) = fifo->free;
68
69 freefunc(fifo);
70
71 return (NULL);
72}
73
74
75void
76flushfifo32(fifo32 *fifo)
77{
78 fifo->tail = fifo->head = fifo->buffer;
79 fifo->elements = 0;
80}
81
82
83void
84flushfifo8(fifo8 *fifo)
85{
86 fifo->tail = fifo->head = fifo->buffer;
87 fifo->elements = 0;
88}
89
90
91bool
92getfifo32(u_int32_t *data, fifo32 *fifo)
93{
94 register u_int32_t *pos;
95
96 if (fifo->tail != fifo->head) {
97 pos = fifo->tail;
98 *data = *pos++;
99 if (pos == fifo->endbuffer)
100 pos = fifo->buffer;
101 fifo->tail = pos;
102 fifo->elements--;
103
104 return (TRUE);
105 }
106
107 return (FALSE);
108}
109
110
111bool
112getfifo8(uint8 *data, fifo8 *fifo)
113{
114 register uint8 *pos;
115
116 if (fifo->tail != fifo->head) {
117 pos = fifo->tail;
118 *data = *pos++;
119 if (pos == fifo->endbuffer)
120 pos = fifo->buffer;
121 fifo->tail = pos;
122 fifo->elements--;
123
124 return (TRUE);
125 }
126
127 return (FALSE);
128}
129
130
131/* This function reads all available bytes from the specified FIFO and
132 * copies them in the supplied buffer until there are none to read, or
133 * until max bytes have been transfered. Returns the number of bytes that
134 * were successfully read.
135 */
136size_t
137getnfifo8(uint8 *buffer, fifo8 *fifo, size_t max)
138{
139 register uint8 *pos;
140 register size_t len, len2, done;
141
142 if (max == 1) {
143 if (getfifo8(buffer, fifo))
144 return (1);
145 return (0);
146 }
147
148 len = fifo->elements;
149 if (len > max)
150 len = max;
151
152 if (len) {
153 pos = fifo->tail;
154 len2 = fifo->endbuffer - pos;
155 if (len2 >= len)
156 done = len;
157 else
158 done = len2;
159 mm_memcpy(buffer, pos, done);
160 buffer += done;
161 pos += done;
162 if (pos == fifo->endbuffer)
163 pos = fifo->buffer;
164 len2 -= done;
165 if (len2) {
166 mm_memcpy(buffer, pos, len2);
167 pos += len2;
168 }
169 fifo->tail = pos;
170 fifo->elements -= len;
171 }
172
173 return (len);
174}
175
176
177fifo32 *
178openfifo32(void *(*mallocfunc)(size_t), void (*freefunc)(void *),
179 size_t elements)
180{
181 fifo32 *fifo;
182 uint8 *tmp;
183
184 if ((fifo = mallocfunc(sizeof(fifo32) +
185 ((elements + 2) * sizeof(u_int32_t)))) != NULL) {
186 fifo->malloc = mallocfunc;
187 fifo->free = freefunc;
188 fifo->size = elements;
189 fifo->elements = 0;
190 tmp = ((uint8 *)fifo) + sizeof(fifo32);
191 fifo->buffer = fifo->head = fifo->tail = fifo->endbuffer
192 = (u_int32_t *)MMALIGN_CEIL(tmp, u_int32_t);
193 fifo->endbuffer += (elements + 1);
194
195 return (fifo);
196 }
197
198 return (NULL);
199}
200
201
202fifo8 *
203openfifo8(void *(*mallocfunc)(size_t), void (*freefunc)(void *),
204 size_t elements)
205{
206 fifo8 *fifo;
207 uint8 *tmp;
208
209 if ((fifo = mallocfunc((sizeof(int) * 2) + sizeof(fifo8) + elements + 2))
210 != NULL) {
211 fifo->malloc = mallocfunc;
212 fifo->free = freefunc;
213 fifo->size = elements;
214 fifo->elements = 0;
215 /* int-align buffer, even though it's only bytes, for possible
216 * optimization with mm_memcpy() in multi-bytes operations
217 */
218 tmp = (uint8 *)(((uint8 *)fifo) + sizeof(fifo8));
219 fifo->buffer = fifo->head = fifo->tail = fifo->endbuffer
220 = (uint8 *)MMALIGN_CEIL(tmp, int);
221 fifo->endbuffer += (elements + 1);
222
223 return (fifo);
224 }
225
226 return (NULL);
227}
228
229
230bool
231putfifo32(fifo32 *fifo, u_int32_t data)
232{
233 u_int32_t *pos;
234
235 if (fifo->elements < fifo->size) {
236 pos = fifo->head;
237 *pos++ = data;
238 if (pos == fifo->endbuffer)
239 pos = fifo->buffer;
240 fifo->head = pos;
241 fifo->elements++;
242
243 return (TRUE);
244 }
245
246 return (FALSE);
247}
248
249
250bool
251putfifo8(fifo8 *fifo, uint8 data)
252{
253 uint8 *pos;
254
255 if (fifo->elements < fifo->size) {
256 pos = fifo->head;
257 *pos++ = data;
258 if (pos == fifo->endbuffer)
259 pos = fifo->buffer;
260 fifo->head = pos;
261 fifo->elements++;
262
263 return (TRUE);
264 }
265
266 return (FALSE);
267}
268
269
270/* This function inserts size elements into fifo, reading them from buffer.
271 * It returns the number of elements that could be inserted.
272 */
273size_t
274putnfifo8(fifo8 *fifo, uint8 *buffer, size_t size)
275{
276 uint8 *pos;
277 size_t len, len2, done;
278
279 if (size == 1) {
280 if (putfifo8(fifo, *buffer))
281 return (1);
282 return (0);
283 }
284
285 len = size;
286 len2 = fifo->size - fifo->elements;
287 if (len2 > len)
288 len = len2;
289
290 if (len) {
291 pos = fifo->head;
292 len2 = fifo->endbuffer - pos;
293 if (len2 > len)
294 done = len;
295 else
296 done = len2;
297 mm_memcpy(pos, buffer, done);
298 buffer += done;
299 pos += done;
300 if (pos == fifo->endbuffer)
301 pos = fifo->buffer;
302 len2 -= done;
303 if (len2) {
304 mm_memcpy(pos, buffer, len2);
305 pos += len2;
306 }
307 fifo->head = pos;
308 fifo->elements += len;
309 }
310
311 return (len);
312}
313
314
315size_t
316statfifo32(fifo32 *fifo)
317{
318 return (fifo->elements);
319}
320
321
322size_t
323statfifo8(fifo8 *fifo)
324{
325 return (fifo->elements);
326}
327
328
329fifo64 *
330closefifo64(fifo64 *fifo)
331{
332 void (*freefunc)(void *) = fifo->free;
333
334 freefunc(fifo);
335
336 return (NULL);
337}
338
339
340void flushfifo64(fifo64 *fifo)
341{
342 fifo->tail = fifo->head = fifo->buffer;
343 fifo->elements = 0;
344}
345
346
347bool
348getfifo64(u_int64_t *data, fifo64 *fifo)
349{
350 register u_int64_t *pos;
351
352 if (fifo->tail != fifo->head) {
353 pos = fifo->tail;
354 *data = *pos++;
355 if (pos == fifo->endbuffer)
356 pos = fifo->buffer;
357 fifo->tail = pos;
358 fifo->elements--;
359
360 return (TRUE);
361 }
362
363 return (FALSE);
364}
365
366
367fifo64 *
368openfifo64(void *(*mallocfunc)(size_t), void (*freefunc)(void *),
369 size_t elements)
370{
371 fifo64 *fifo;
372 uint8 *tmp;
373
374 if ((fifo = mallocfunc(sizeof(fifo64) +
375 ((elements + 2) * sizeof(u_int64_t)))) != NULL) {
376 fifo->malloc = mallocfunc;
377 fifo->free = freefunc;
378 fifo->size = elements;
379 fifo->elements = 0;
380 tmp = ((uint8 *)fifo) + sizeof(fifo64);
381 fifo->buffer = fifo->head = fifo->tail = fifo->endbuffer
382 = (u_int64_t *)MMALIGN_CEIL(tmp, u_int64_t);
383 fifo->endbuffer += (elements + 1);
384
385 return (fifo);
386 }
387
388 return (NULL);
389}
390
391
392bool
393putfifo64(fifo64 *fifo, u_int64_t data)
394{
395 u_int64_t *pos;
396
397 if (fifo->elements < fifo->size) {
398 pos = fifo->head;
399 *pos++ = data;
400 if (pos == fifo->endbuffer)
401 pos = fifo->buffer;
402 fifo->head = pos;
403 fifo->elements++;
404
405 return (TRUE);
406 }
407
408 return (FALSE);
409}
410
411
412size_t
413statfifo64(fifo64 *fifo)
414{
415 return (fifo->elements);
416}