1 .\" $Id: mmfifo.3,v 1.6 2003/10/25 14:09:16 mmondor Exp $
3 .\" Copyright (C) 2001-2003, Matthew Mondor
4 .\" All rights reserved.
6 .\" Redistribution and use in source and binary forms, with or without
7 .\" modification, are permitted provided that the following conditions
9 .\" 1. Redistributions of source code must retain the above copyright
10 .\" notice, this list of conditions and the following disclaimer.
11 .\" 2. Redistributions in binary form must reproduce the above copyright
12 .\" notice, this list of conditions and the following disclaimer in the
13 .\" documentation and/or other materials provided with the distribution.
14 .\" 3. All advertising materials mentioning features or use of this software
15 .\" must display the following acknowledgement:
16 .\" This product includes software written by Matthew Mondor.
17 .\" 4. The name of Matthew Mondor may not be used to endorse or promote
18 .\" products derived from this software without specific prior written
21 .\" THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
22 .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 .\" IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 .\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
27 .\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 .Nd General purpose portable and versatile FIFO buffers library.
39 .Fd #include <sys/types.h>
40 .Fd #include <mmtypes.h>
41 .Fd #include <mmfifo.h>
43 .Fn FIFO_DEFINE "fifotype_t" "objecttype"
45 .Fn FIFO_INIT "fifotype_t *fifo" "void *buffer" "u_int32_t size"
47 .Fn FIFO_FULL "fifotype_t *fifo"
49 .Fn FIFO_EMPTY "fifotype_t *fifo"
51 .Fn FIFO_STAT "fifotype_t *fifo"
53 .Fn FIFO_AVAIL "fifotype_t *fifo"
55 .Fn FIFO_FLUSH "fifotype_t *fifo"
57 .Fn FIFO_PUT "fifotype_t *fifo" "objecttype *element"
59 .Fn FIFO_GET "fifotype_t *fifo" "objecttype *element"
61 .Fn FIFO_FIND "fifotype_t *fifo" "objecttype **pointer" "objecttype *element"
63 .Fn FIFO_ALLOC "fifotype_t *fifo" "objecttype **pointer" "u_int32_t *actual" \
66 .Fn FIFO_FREE "fifotype_t *fifo" "objecttype **pointer" "u_int32_t *actual" \
69 FIFO buffers (First In First Out) are especially useful when
70 implementing asynchronous systems. For instance in the implementation of
71 serial RS-232 read/write functions, a trap or interrupt occurs when a byte
72 is available to read or when the device is ready to be written more data to.
73 The user API has to be able to be used at anytime however so that the
74 application may read and write bytes at any time (in fact queueing them for
75 the trap handler). So two FIFO buffers are required, user API and the trap
76 handler, each share one side of each queue. Unlike a simple buffer, each side
77 do not know when the other side will insert or unqueue elements at the other
78 end. It therefore is extremely useful to synchronize two asynchonous
81 These almost entirely only consist of macros, which allow to work with a
82 variety of FIFO buffer types, including FIFOs to hold user supplied type
83 objects. These are not implemented as linked lists but as fixed buffers
84 which can hold a maximum number of fixed-sized elements. They also leave
85 the user application the responsibility to allocate and free the buffers
90 .Bl -tag -width indent -offset indent
91 .It void Fn FIFO_DEFINE "fifotype_t" "objecttype"
92 Permits to create a new type of FIFO buffer to hold custom objects. This
93 in fact only is a macro to create a new fifo*_t structure and typedef it.
95 defines the new FIFO type which should be created.
97 specifies the type of object that this fifo structure should allow to buffer.
98 For instance, to create a new fifo type to hold file descriptors, one could
100 .Bd -literal -offset indent
101 FIFO_DEFINE(fdfifo_t, int);
104 It then would be possible to use the
106 type, initialize it, and use it.
107 .Bd -literal -offset indent
112 FIFO_INIT(&f, buf, 1024);
117 Predefined FIFO buffer types are
123 to hold objects of type
130 .It void Fn FIFO_INIT "fifotype_t *fifo" "void *buffer" "u_int32_t size"
131 Allows to initialize a FIFO buffer.
133 consists of a pointer to the FIFO buffer to initialize,
135 is the user supplied buffer which should be able to hold the wanted number
136 of elements, minus one.
138 specifies the maximum number of elements that the buffer can hold. This is
139 not expressed in bytes, but in number of elements.
140 As a general rule, the buffer should hold sizeof(object) * (max + 1) bytes.
141 When a buffer is done with, it is the responsibility of the user application
144 .It bool Fn FIFO_FULL "fifotype_t *fifo"
145 A useful macro to determine if a FIFO buffer is full and cannot take
148 is a pointer to the FIFO buffer. This is useful if for instance one does not
149 want the FIFO buffer to loose the oldest element if it is full and
152 .It bool Fn FIFO_EMPTY "fifotype_t *fifo"
153 allows to determine if a FIFO buffer is currently empty, that is, does not hold
155 .It u_int32_t Fn FIFO_STAT "fifotype_t *fifo"
156 permits to know how many elements are currently buffered into the specified
158 buffer, which can be read using
160 .It u_int32_t Fn FIFO_AVAIL "fifotype_t *fifo"
161 evaluates the number of free elements in the buffer and returns it.
162 .It void Fn FIFO_FLUSH "fifotype_t *fifo"
163 allows to get rid of all the current contents, if any, of the specified
165 buffer. The buffer as a result becomes empty, instantly.
166 .It void Fn FIFO_PUT "fifotype_t *fifo" "objecttype *element"
167 inserts the element to which supplied
169 points, into the supplied FIFO buffer
171 If the buffer is full, the oldest element is automatically discarded, allowing
172 an automatic rotation within the buffer, but loosing bytes. If this behavior
175 macro should be used first to detect the buffer full condition.
176 .It void Fn FIFO_GET "fifotype_t *fifo" "objecttype *element"
177 attempts to read and obtain an element from the supplied FIFO buffer
181 supplied pointer. This can transparently fail; If it is unsure that the
182 FIFO buffer holds any data, the
184 macro may be used before calling this macro. The obtained element, if it
185 could be read, always consists of the oldest element that was inserted using
187 that is, the First element In is the First element Out. It is also immediately
188 forgotten afterwards.
189 .It void Fn FIFO_FIND "fifotype_t *fifo" "objecttype **pointer" \
190 "objecttype *element"
195 buffer contents, and fills
197 with the element pointer if found, or NULL if the element could not be found.
198 .It void Fn FIFO_ALLOC "fifotype_t *fifo" "objecttype **pointer" \
199 "u_int32_t *actual" "u_int32_t size"
200 macro is useful for operations which need to insert several elements at once,
201 as it allows them to allocate the required room and use
203 or other user-specific method to write in the data. Attempts to allocate room
208 The pointer to the buffer where elements can be written is placed into
210 and the number of elements which could be allocated in
212 which may be smaller than the requested size, in which case the caller may
213 perform other calls to this function. This can return smaller results for two
214 reasons: 1) The internal head pointer reached the end of the buffer, and
215 as such a single contiguous buffer cannot be provided, in which case two
216 calls will be required to this macro to complete the operation. 2) The buffer
217 did not contain enough room for the requested number of elements. The caller
218 should not attempt to use the returned pointer if the returned size is zero.
219 .It void Fn FIFO_FREE "fifotype_t *fifo" "objecttype **pointer" \
220 "u_int32_t *actual" "u_int32_t size"
223 permits to free back a certain number of elements at once from the buffer.
225 is set to the location where the elements can be found, and
227 to the number of elements which could be freed. Like it's companion, it can
228 return a smaller number of elements than that requested, and multiple calls
229 may then be performed to complete the operation.
232 .Bl -tag -width indent -offset indent
245 return TRUE or FALSE.
250 return a number of elements.
252 returns a pointer to an element into the provided pointer.
257 return their result pointers and size into the provided pointers.
267 was originally developped on NetBSD 1.5 for the Xisop portable kernel
268 project from Matthew Mondor. It was modified alot in Febuary 2003 to be more
269 versatile and generate more optimized C code.
273 library was written by Matthew Mondor and is
274 Copyright (c) 2000-2003 Matthew Mondor, All rights reserved.
276 Please report any bug to mmondor@gobot.ca