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