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