mmlib/mmat: replace some variables by literal constants
[mmondor.git] / mmsoftware / mmlib / mmfifo.3
CommitLineData
b232bd02 1.\" $Id: mmfifo.3,v 1.9 2007/12/05 23:47:56 mmondor Exp $
2f9ea7dc 2.\"
d4aaa170 3.\" Copyright (C) 2000-2004, Matthew Mondor
2f9ea7dc
MM
4.\" All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
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:
d4aaa170 16.\" This product includes software developed by Matthew Mondor.
2f9ea7dc
MM
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
19.\" permission.
d4aaa170
MM
20.\" 5. Redistribution of source code may not be released under the terms of
21.\" any GNU Public License derivate.
2f9ea7dc
MM
22.\"
23.\" THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
24.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26.\" IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
29.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33.\"
4f87c15b 34.Dd Feb 11, 2003
2f9ea7dc 35.Os mmsoftware
47071c2b
MM
36.Dt MMFIFO 3
37.Sh NAME
38.Nm mmfifo
7a56f31f 39.Nd General purpose portable and versatile FIFO buffers library.
47071c2b
MM
40.Sh SYNOPSIS
41.Fd #include <sys/types.h>
42.Fd #include <mmtypes.h>
43.Fd #include <mmfifo.h>
47071c2b 44.Ft void
7a56f31f 45.Fn FIFO_DEFINE "fifotype_t" "objecttype"
47071c2b 46.Ft void
b232bd02 47.Fn FIFO_INIT "fifotype_t *fifo" "void *buffer" "uint32_t size"
47071c2b 48.Ft bool
7a56f31f
MM
49.Fn FIFO_FULL "fifotype_t *fifo"
50.Ft bool
51.Fn FIFO_EMPTY "fifotype_t *fifo"
b232bd02 52.Ft uint32_t
7a56f31f 53.Fn FIFO_STAT "fifotype_t *fifo"
b232bd02 54.Ft uint32_t
7a56f31f
MM
55.Fn FIFO_AVAIL "fifotype_t *fifo"
56.Ft void
57.Fn FIFO_FLUSH "fifotype_t *fifo"
58.Ft void
59.Fn FIFO_PUT "fifotype_t *fifo" "objecttype *element"
47071c2b 60.Ft void
7a56f31f 61.Fn FIFO_GET "fifotype_t *fifo" "objecttype *element"
4f87c15b 62.Ft void
7a56f31f 63.Fn FIFO_FIND "fifotype_t *fifo" "objecttype **pointer" "objecttype *element"
4f87c15b 64.Ft void
b232bd02
MM
65.Fn FIFO_ALLOC "fifotype_t *fifo" "objecttype **pointer" "uint32_t *actual" \
66"uint32_t size"
7a56f31f 67.Ft void
b232bd02
MM
68.Fn FIFO_FREE "fifotype_t *fifo" "objecttype **pointer" "uint32_t *actual" \
69"uint32_t size"
47071c2b 70.Sh DESCRIPTION
7a56f31f 71FIFO buffers (First In First Out) are especially useful when
47071c2b
MM
72implementing asynchronous systems. For instance in the implementation of
73serial RS-232 read/write functions, a trap or interrupt occurs when a byte
74is available to read or when the device is ready to be written more data to.
75The user API has to be able to be used at anytime however so that the
76application may read and write bytes at any time (in fact queueing them for
77the trap handler). So two FIFO buffers are required, user API and the trap
7a56f31f 78handler, each share one side of each queue. Unlike a simple buffer, each side
47071c2b
MM
79do not know when the other side will insert or unqueue elements at the other
80end. It therefore is extremely useful to synchronize two asynchonous
81applications.
82.Pp
4f87c15b
MM
83These almost entirely only consist of macros, which allow to work with a
84variety of FIFO buffer types, including FIFOs to hold user supplied type
85objects. These are not implemented as linked lists but as fixed buffers
86which can hold a maximum number of fixed-sized elements. They also leave
87the user application the responsibility to allocate and free the buffers
88(explained in the
7a56f31f 89.Fn FIFO_INIT
4f87c15b 90section).
2f9ea7dc
MM
91.Ss FUNCTIONS
92.Bl -tag -width indent -offset indent
93.It void Fn FIFO_DEFINE "fifotype_t" "objecttype"
94Permits to create a new type of FIFO buffer to hold custom objects. This
4f87c15b
MM
95in fact only is a macro to create a new fifo*_t structure and typedef it.
96.Fa fifotype_t
97defines the new FIFO type which should be created.
98.Fa objecttype
99specifies the type of object that this fifo structure should allow to buffer.
100For instance, to create a new fifo type to hold file descriptors, one could
101use:
102.Bd -literal -offset indent
7a56f31f 103FIFO_DEFINE(fdfifo_t, int);
4f87c15b 104.Ed
47071c2b 105.Pp
4f87c15b
MM
106It then would be possible to use the
107.Fa fdfifo_t
108type, initialize it, and use it.
109.Bd -literal -offset indent
110fdfifo_t f;
7a56f31f 111int buf[1024];
4f87c15b
MM
112int fd;
113
7a56f31f
MM
114FIFO_INIT(&f, buf, 1024);
115FIFO_PUT(&f, &fd);
116FIFO_GET(&f, &fd);
4f87c15b 117.Ed
47071c2b 118.Pp
4f87c15b
MM
119Predefined FIFO buffer types are
120.Nm fifo8_t ,
121.Nm fifo16_t,
122.Nm fifo32_t
123and
124.Nm fifo64_t ,
125to hold objects of type
b232bd02
MM
126.Nm uint8_t ,
127.Nm uint16_t ,
128.Nm uint32_t
4f87c15b 129and
b232bd02 130.Nm uint64_t ,
4f87c15b 131respectively.
b232bd02 132.It void Fn FIFO_INIT "fifotype_t *fifo" "void *buffer" "uint32_t size"
2f9ea7dc 133Allows to initialize a FIFO buffer.
47071c2b 134.Fa fifo
4f87c15b
MM
135consists of a pointer to the FIFO buffer to initialize,
136.Fa buffer
137is the user supplied buffer which should be able to hold the wanted number
7a56f31f 138of elements, minus one.
4f87c15b
MM
139.Fa size
140specifies the maximum number of elements that the buffer can hold. This is
141not expressed in bytes, but in number of elements.
142As a general rule, the buffer should hold sizeof(object) * (max + 1) bytes.
143When a buffer is done with, it is the responsibility of the user application
144to free the supplied
145.Fa buffer .
2f9ea7dc
MM
146.It bool Fn FIFO_FULL "fifotype_t *fifo"
147A useful macro to determine if a FIFO buffer is full and cannot take
4f87c15b
MM
148new elements.
149.Fa fifo
7a56f31f
MM
150is a pointer to the FIFO buffer. This is useful if for instance one does not
151want the FIFO buffer to loose the oldest element if it is full and
152.Fn FIFO_PUT
153is used.
2f9ea7dc 154.It bool Fn FIFO_EMPTY "fifotype_t *fifo"
7a56f31f
MM
155allows to determine if a FIFO buffer is currently empty, that is, does not hold
156any elements.
b232bd02 157.It uint32_t Fn FIFO_STAT "fifotype_t *fifo"
4f87c15b
MM
158permits to know how many elements are currently buffered into the specified
159.Fa fifo
7a56f31f
MM
160buffer, which can be read using
161.Fn FIFO_GET .
b232bd02 162.It uint32_t Fn FIFO_AVAIL "fifotype_t *fifo"
2f9ea7dc
MM
163evaluates the number of free elements in the buffer and returns it.
164.It void Fn FIFO_FLUSH "fifotype_t *fifo"
4f87c15b
MM
165allows to get rid of all the current contents, if any, of the specified
166.Fa fifo
7a56f31f 167buffer. The buffer as a result becomes empty, instantly.
2f9ea7dc 168.It void Fn FIFO_PUT "fifotype_t *fifo" "objecttype *element"
7a56f31f
MM
169inserts the element to which supplied
170.Fa element
171points, into the supplied FIFO buffer
172.Fa fifo .
173If the buffer is full, the oldest element is automatically discarded, allowing
174an automatic rotation within the buffer, but loosing bytes. If this behavior
175is not wanted, the
176.Fn FIFO_FULL
177macro should be used first to detect the buffer full condition.
2f9ea7dc 178.It void Fn FIFO_GET "fifotype_t *fifo" "objecttype *element"
4f87c15b
MM
179attempts to read and obtain an element from the supplied FIFO buffer
180.Fa fifo ,
181and place it into
182.Fa element
183supplied pointer. This can transparently fail; If it is unsure that the
7a56f31f
MM
184FIFO buffer holds any data, the
185.Fn FIFO_EMPTY
186macro may be used before calling this macro. The obtained element, if it
187could be read, always consists of the oldest element that was inserted using
188.Fn FIFO_PUT ,
189that is, the First element In is the First element Out. It is also immediately
190forgotten afterwards.
2f9ea7dc
MM
191.It void Fn FIFO_FIND "fifotype_t *fifo" "objecttype **pointer" \
192"objecttype *element"
7a56f31f 193attempts to locate
4f87c15b 194.Fa element
7a56f31f
MM
195within the current
196.Fa fifo
197buffer contents, and fills
198.Fa pointer
199with the element pointer if found, or NULL if the element could not be found.
2f9ea7dc 200.It void Fn FIFO_ALLOC "fifotype_t *fifo" "objecttype **pointer" \
b232bd02 201"uint32_t *actual" "uint32_t size"
7a56f31f
MM
202macro is useful for operations which need to insert several elements at once,
203as it allows them to allocate the required room and use
2f9ea7dc 204.Xr memcpy 3
7a56f31f
MM
205or other user-specific method to write in the data. Attempts to allocate room
206for
47071c2b 207.Fa size
7a56f31f
MM
208elements in
209.Fa fifo .
210The pointer to the buffer where elements can be written is placed into
211.Fa pointer ,
212and the number of elements which could be allocated in
213.Fa actual ,
214which may be smaller than the requested size, in which case the caller may
215perform other calls to this function. This can return smaller results for two
216reasons: 1) The internal head pointer reached the end of the buffer, and
217as such a single contiguous buffer cannot be provided, in which case two
218calls will be required to this macro to complete the operation. 2) The buffer
219did not contain enough room for the requested number of elements. The caller
220should not attempt to use the returned pointer if the returned size is zero.
2f9ea7dc 221.It void Fn FIFO_FREE "fifotype_t *fifo" "objecttype **pointer" \
b232bd02 222"uint32_t *actual" "uint32_t size"
7a56f31f
MM
223contrary to
224.Fn FIFO_ALLOC ,
225permits to free back a certain number of elements at once from the buffer.
226.Fa pointer
227is set to the location where the elements can be found, and
228.Fa actual
229to the number of elements which could be freed. Like it's companion, it can
230return a smaller number of elements than that requested, and multiple calls
231may then be performed to complete the operation.
2f9ea7dc 232.El
47071c2b 233.Sh RETURN VALUES
2f9ea7dc
MM
234.Bl -tag -width indent -offset indent
235.It Xo
7a56f31f
MM
236.Fn FIFO_DEFINE ,
237.Fn FIFO_INIT ,
238.Fn FIFO_FLUSH ,
239.Fn FIFO_PUT ,
7a56f31f 240.Fn FIFO_GET
2f9ea7dc 241.Xc
4f87c15b 242return nothing.
2f9ea7dc
MM
243.It Xo
244.Fn FIFO_FULL ,
7a56f31f 245.Fn FIFO_EMPTY
2f9ea7dc 246.Xc
7a56f31f 247return TRUE or FALSE.
2f9ea7dc
MM
248.It Xo
249.Fn FIFO_STAT ,
7a56f31f 250.Fn FIFO_AVAIL
2f9ea7dc 251.Xc
7a56f31f 252return a number of elements.
2f9ea7dc 253.It Fn FIFO_FIND
7a56f31f 254returns a pointer to an element into the provided pointer.
2f9ea7dc
MM
255.It Xo
256.Fn FIFO_ALLOC ,
7a56f31f 257.Fn FIFO_FREE
2f9ea7dc 258.Xc
7a56f31f 259return their result pointers and size into the provided pointers.
2f9ea7dc 260.El
47071c2b
MM
261.Sh SEE ALSO
262.Xr malloc 3 ,
2f9ea7dc
MM
263.Xr free 3 ,
264.Xr memcpy 3
47071c2b
MM
265.Sh STANDARDS
266None
267.Sh HISTORY
d3fa2137
MM
268.Nm
269was originally developped on NetBSD 1.5 for the Xisop portable kernel
4f87c15b
MM
270project from Matthew Mondor. It was modified alot in Febuary 2003 to be more
271versatile and generate more optimized C code.
47071c2b 272.Sh AUTHORS
d3fa2137
MM
273The
274.Nm
275library was written by Matthew Mondor and is
93447690 276Copyright (c) 2000-2004 Matthew Mondor, All rights reserved.
47071c2b 277.Sh BUGS
93447690 278Please report any bug to mmondor@accela.net