home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 2
/
goldfish_vol2_cd1.bin
/
files
/
util
/
libs
/
fifolib
/
fifolib.doc
< prev
next >
Wrap
Text File
|
1993-10-03
|
13KB
|
378 lines
FIFO.LIBRARY
MANUAL, VERSION 3.2
(c)Copyright 1990, Matthew Dillon, All Rights Reserved
fifo.library/FifoNotes
-
fifo.library/OpenFifo
fifo.library/CloseFifo
fifo.library/ReadFifo
fifo.library/WriteFifo
fifo.library/RequestFifo
fifo.library/BufSizeFifo
fifo.library/FifoNotes fifo.library/FifoNotes
FIFO.LIBRARY is a general fifo library implementation with the following
features:
* named fifos
* support for writing to a fifo from a hardware exception
* multiple readers on a fifo supported, each get the same data
stream
* efficient reading (no buffer copies on read)
* automatic or manual (via message passing) flow control
The uses for this library are limitless. To use the library, open
it via OpenLibrary("fifo.library", 0);, the base variable is named:
FifoBase
Please refer to the test program for an example of usage.
LINK LIBRARIES: fifo.lib standard amiga (join type) library,
large-data model
fifos.lib standard amiga (joing type) library,
small-data model
fifo.library/OpenFifo fifo.library/OpenFifo
NAME
OpenFifo - open a rendezvous FIFO by name
SYNOPSIS
fifo = OpenFifo(name, bufsize, flags)
D0 D0 D1 A0
void *fifo; /* returned fifo handle */
char *name; /* rendezvous name - case sensitive */
long bufsize; /* must be a power of 2 */
long flags; /* open flags */
FUNCTION
OpenFifo() creates a FIFO if <name> does not exist, else
references an already existing FIFO named <name>. OpenFifo()
returns a fifo handle to be used for further operations.
bufsize must be a power of 2. For example, 1024.
NOTE: two OpenFifo()s openning the same fifo are NOT guarenteed
to return the same handle, even though they reference the same
FIFO.
FLAGS
FIFOF_READ
file handle intended to be used for reading, do not specify
unless you read from the handle.
FIFOF_WRITE
file handle intended to be used for writing, do not specify
unless you write to the handle.
If a previous CloseFifo() activated FIFOF_EOF, then the flag is
cleared.
FIFOF_NORMAL
normal (task based) calls to library, else is assumed calls
will be made from an interrupt or hardware exception.
NOTE: non-normal fifo writes are unable to wake up blocked
library calls. Thus, anybody reading a fifo written to by
an interrupt or exception (read: enforcer), must poll the
fifo. Eventually automatic polling will be an option to make
operation with non-normal writers transparent to the reader.
FIFOF_KEEPIFD
When this FIFO is eventually closed, do not destroy it if
unread data is pending. Allows a 'writer' to completely finish
and exit before a read even has the chance to open the fifo.
FIFOF_RREQUIRED
Cause any write operations to fail when there are no readers
(i.e. broken pipe), prevents a lockup from occuring if the
reader is ^C'd.
FIFOF_NBIO
Specify that ReadFifo() and WriteFifo() calls are not to block.
fifo.library/CloseFifo fifo.library/CloseFifo
NAME
CloseFifo - close a previously openned FIFO
SYNOPSIS
void CloseFifo(fifo, flags)
D0 D1
void *fifo; /* fifo handle previously returned by OpenFifo() */
long flags; /* see below */
FUNCTION
CloseFifo() is the reverse of OpenFifo(), dereferencing a Fifo.
The last close of a shared fifo will result in the deletion of that
fifo ONLY if all data has been read, allowing unsynchronized
programs to use the Fifo.
A future flag will cause the last close of a FIFO to delete the
fifo and throw away any data.
FLAGS
FIFOF_EOF
If specified, the FIFO will generate an EOF to readers
after the last writer has closed. This particular handle
need not be the last writer.
If not specified, any active readers are left hanging
(allowing another program to 'take up' where this one left
off without the readers knowing)
NOTE that any new writer that OpenFifo()s the fifo will
clear this flag.
NOTE that the EOF condition will be returned only once
to a given reader, then cleared (causing the reader to
block again). This is because shells generally ignore
EOF and we would otherwise get into an infinite loop.
THIS FLAG HAS NO EFFECT IF THE HANDLE WAS NOT ORIGINALLY
OPENNED FIFOF_WRITE.
fifo.library/ReadFifo fifo.library/ReadFifo
NAME
ReadFifo - read data from a FIFO
SYNOPSIS
long ready = ReadFifo(fifo, pptr, skip)
D0 D0 D1 A0
void *fifo; /* fifo handle previously returned by OpenFifo() */
char **pptr; /* address of pointer to store buffer pointer */
long skip; /* # of bytes to skip (delete) */
long ready; /* # of bytes available to read, -1 = EOF */
WARNING
ReadFifo() uses UNCONVENTIONAL ARGUMENTS
FUNCTION
ReadFifo() first deletes (skip) bytes from the FIFO, then sets a
pointer into the fifo's buffer and returns the number of bytes
immediately available for reading.
THE DATA POINTER TO MAY NOT BE MODIFIED UNDER ANY CIRCUMSTANCES
The call is efficient because, in many cases, a buffer copy can be
completely avoided by the program. The loop code in the example
below shows generally how operation works. For further
information, refer to the test program (TEST.C).
The number of bytes available (ready), is independant of the
number of bytes you threw away (skip). You get a certain amount
of lookahead for free, but it should be stressed that the (ready)
value is not necessarily all the available data. Data in the
fifo is not always contiguous and so there may be more data
available than you can immediately determine. For example, the
call might return 1 when in fact 500 bytes are available. But
only 1 byte is available contiguously (based at the pointer).
After processing the 1 byte your next read would return 499.
NON-BLOCKING IO
If FIFOF_NBIO was specified on open, this call will return
immediately and 0 is a valid return. If 0 is returned there
is no data ready and the program must poll the fifo. But
wait, there is a better way to do it ... instead of polling
the fifo you can opt to have a message sent to you when data
becomes available. see the RequestFifo() function call and
look at TEST.C
If FIFOF_NBIO is *not* specified, then 0 will never be returned
by this call. Instead, either >0 or -1 (EOF) will be returned.
MULTIPLE-READERS
Multiple readers may exist for a given FIFO. This is completely
supported. If you have one writer and two readers, and the
writer writes "ABC", then both readers will each read "ABC".
Because the FIFO buffer is shared, readers may NOT modify any
data returned in (pptr) because this could effect other readers
(depending on whether they have already read the data or not).
INTERRUPTS / EXCEPTIONS
ReadFifo() may not be called from an interrupt or a hardware
exception. ReadFifo() may ONLY be called from task or process.
EXAMPLE
/*
* dump fifo ff. FIFO was openned without FIFOF_NBIO.
*/
{
long i = 0; /* delete nothing on first loop */
long n;
char *ptr;
while ((n = ReadFifo(ff, &ptr, i)) > 0) {
if (n > 64) /* can easily limit read-size if you */
n = 64; /* want to (optional, obviously) */
i = n; /* drain this many on next loop */
write(1, ptr, n);
}
/*
* note, if you break out of the loop you may need a final
* ReadFifo(ff, &ptr, i); to clear out what you have already
* processed.
*/
}
fifo.library/WriteFifo fifo.library/WriteFifo
NAME
WriteFifo - write data to a FIFO
SYNOPSIS
long actual = WriteFifo(fifo, buf, len)
D0 D0 D1 A0
void *fifo; /* fifo handle previously returned by OpenFifo() */
void *buf; /* buffer to read data into */
long max; /* maximum # of bytes to read */
FUNCTION
WriteFifo() writes data to a FIFO. WriteFifo() will either return
actual = len if the write succeeded, 0 if the FIFO is full, or -1
if an error occurs. No intermediate values are currently returned
(i.e. writes are atomic)
If two writers attempt to write to the same FIFO at the same time
and the FIFOF_NORMAL flag was not specified on open (i.e. writer
writes from an interrupt or exception), then it is possible for
a collision to occur in which case one of the calls will return
an error (-1).
WARNING WARNING
You may not write blocks larger than 1/2 the fifo buffer size,
this will generate an immediate error (-2) regardless of how
much space is actually available. The reason for this is simply
that writes are guarenteed to be atomic, and cannot be guarenteed
if larger blocks are written. Also, flow control breaks down
with larger blocks so I figure it is best to nip it in the bud and
return a formal error.
NON-BLOCKING-IO (FIFOF_NORMAL fifos only)
Writes are atomic. If a write fails and FIFOF_NBIO was specified
on open, the write will return with a failure code of -1. You
may optionally poll or use the RequestFifo() call.
Note that even if RequestFifo() returns the message, a write may
fail due to other processes writing to the fifo before you have
a chance to, in which case you have to RequestFifo() again and
loop.
If FIFOF_NBIO was not specified on open, then the write will not
return until the data has been successfully written, or -2 will
be returned if you specified too large a buffer.
INTERRUPTS/EXCEPTIONS
To write to a fifo from an interrupt or exception you must open the
fifo WITHOUT the FIFOF_NORMAL flag, and be prepared to handle
possible collisions with other writers.
In this case a failure code of -1 could mean either that the FIFO
is full or that a collision has occured and you were the side that
lost out.
WARNING: any writes via a fifo not openned with the FIFOF_NORMAL
flag will *NOT* wakeup anybody blocked waiting to read from the
fifo, whether by RequestFifo() (the message is not returned),
or via normal opens (without the FIFOF_NBIO flag). Readers must
POLL in this case.
fifo.library/RequestFifo fifo.library/RequestFifo
NAME
RequestFifo - request this message be returned when read data is
available or write buffer space is available.
SYNOPSIS
RequestFifo(fifo, msg, req)
D0 D1 A0
void *fifo;
struct Message *msg; /* messasge in question */
long req; /* request */
FUNCTION
Normally this call is used to queue a message to the fifo.library
that will be ReplyMsg()d to your task when the specified condition
occurs. There are four possible requests.
FREQ_RPEND
Request that the specified message be returned when read data
is pending on the fifo.
note: if data is immediately available, the message will be
immediately replied. If an EOF condition exists or occurs the
message will also be replied.
FREQ_WAVAIL
Request that the specified message be returned when the fifo is
more than half empty. It is possible that an attempt to write
after getting your message back will fail due to other writers
getting their writes in ahead of you.
FREQ_ABORT
Request that this message, which was previously queued via
FREQ_RPEND or FREQ_WAVAIL, be returned immediately.
May be called even if message has already been returned but
not processed.
You may queue multiple messages, even several messages all for the
same thing. When you queue a message, it's node becomes owned by
the library until replied. You CANNOT queue the same message
multiple times at once. Generally programmers will queue one
message for write-avail-space and another message for
read-data-ready, then poll the fifo when these messages are
returned and re-queue the message(s).
ReadFifo() and WriteFifo() call RequestFifo() internally when the
FIFOF_NBIO flag is NOT used. This is how they wait for events when
a call blocks due to lack of data or lack of buffer space.
fifo.library/BufSizeFifo fifo.library/BufSizeFifo
NAME
BufSizeFifo - return size of fifo's buffer
SYNOPSIS
long bytes = BufSizeFifo(fifo)
D0 D0
void *fifo;
FUNCTION
This function returns the size of the specified fifo's buffer.
Note that you may not make WriteFifo() calls with lengths
larger than 1/2 the size of the fifo's buffer. This function
allows you to determine the fifo's buffer size to properly
observe this limit. You cannot depend on the buffer size you
specified in OpenFifo() because only the first OpenFifo() for
a given fifo actually sets the buffer size.