home *** CD-ROM | disk | FTP | other *** search
-
- 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.
-
-
-