diff options
| author | Charles.Forsyth <devnull@localhost> | 2006-12-22 20:52:35 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2006-12-22 20:52:35 +0000 |
| commit | 46439007cf417cbd9ac8049bb4122c890097a0fa (patch) | |
| tree | 6fdb25e5f3a2b6d5657eb23b35774b631d4d97e4 /man/10/qio | |
| parent | 37da2899f40661e3e9631e497da8dc59b971cbd0 (diff) | |
20060303-partial
Diffstat (limited to 'man/10/qio')
| -rw-r--r-- | man/10/qio | 482 |
1 files changed, 482 insertions, 0 deletions
diff --git a/man/10/qio b/man/10/qio new file mode 100644 index 00000000..c0a88869 --- /dev/null +++ b/man/10/qio @@ -0,0 +1,482 @@ +.TH QIO 10.2 +.SH NAME +qio: qget, qdiscard, qconsume, qpass, qproduce, qcopy, qopen, qbread, qread, qbwrite, qwrite, qiwrite, qfree, qclose, qhangup, qreopen, qlen, qwindow, qcanread, qsetlimit, qnoblock, qflush, qfull \- queued I/O for devices +.SH SYNOPSIS +.ta \w'\fLQueue* 'u +.B +Queue* qopen(int limit,int msg, void (*kick)(void*),void *arg) +.PP +.B +void qhangup(Queue *q, char *reason) +.PP +.B +void qclose(Queue *q) +.PP +.B +void qreopen(Queue *q) +.PP +.B +void qfree(Queue *q) +.PP +.B +long qbwrite(Queue *q, Block *b) +.PP +.B +long qwrite(Queue *q, void *buf, int len) +.PP +.B +int qpass(Queue *q, Block *b) +.PP +.B +int qpassnolim(Queue *q, Block *b) +.PP +.B +int qproduce(Queue *q, void *buf, int len) +.PP +.B +int qiwrite(Queue *q, void *buf, int len) +.PP +.B +Block* qbread(Queue *q, int len) +.PP +.B +long qread(Queue *q, void *buf, int len) +.PP +.B +Block* qcopy(Queue *q, int len, ulong offset) +.PP +.B +Block* qget(Queue *q) +.PP +.B +int qconsume(Queue *q, void *buf, int len) +.PP +.B +int qdiscard(Queue *q, int len) +.PP +.B +void qflush(Queue *q) +.PP +.B +int qlen(Queue *q) +.PP +.B +int qwindow(Queue *q) +.PP +.B +int qcanread(Queue *q) +.PP +.B +void qsetlimit(Queue *q, int limit) +.PP +.B +void qnoblock(Queue *q, int nonblock) +.PP +.B +int qfull(Queue *q); +.SH DESCRIPTION +This suite of functions provides serial data buffering for device drivers. +Data is stored in a +.B Queue +structure as a sequence of variable-sized +.BR Blocks ; +see +.IR allocb (10.2). +.PP +.I Qopen +initialises and returns a pointer to a new +.BR Queue , +configuring it according to the following parameters: +.TF limit +.PD +.TP +.I limit +Set the queue limit (high water mark) in bytes. +.TP +.I msg +Set message mode if non-zero; otherwise, stream mode (discussed below). +.TP +.I kick +Optional flow-control function called by +.I qbread +to restart writers, and by +.I qbwrite +(also +.IR qiwrite ) +to restart readers. +.TP +.I arg +Argument to pass to +.I kick +.PP +.I Qhangup +marks +.I q +as `hung up' +for the given +.IR reason +.RB ( Ehungup +by default). +Subsequent attempts to write to the queue raise an +.IR error (10.2). +.I Qhangup +does not flush the queue: subsequent read requests are +handled normally until the queue empties. +.I Qread +and the other functions then return their conventional values +for a hungup stream: 0, -1 or a null pointer, depending on the function. +After a few such attempts by any process, an +.IR error (10.2) +is raised (typically +.BR Ehungup ) +on each subsequent read. +.PP +If queued data is left unread, and not flushed by +.I qflush +or +.IR qclose , +the data will again be readable following a subsequent +.IR qreopen . +.PP +.I Qclose +also marks a given +.I q +as `hung up', +but removes and frees any queued data Blocks. +.I Qclose +ignores calls when +.I q +is null. +.PP +.I Qreopen +makes a closed or hung up queue available for use again. +The queue's data limit is reset to the +.I limit +value given when the queue was first created by +.IR qopen , +cancelling the effect of any previous call to +.IR qsetlimit . +.PP +.I Qfree +closes +.I q +with +.I qclose +and frees it. +The caller must ensure that no references remain; +these functions do not keep a reference count. +.SS "Flow control" +The queue I/O routines provide a flow control mechanism to coordinate producers and consumers. +Each queue has a limit on the number of bytes queued, its `high water mark', +initially set when the queue is created, but adjustable by +.IR qsetlimit , +below. +The low water mark is not set explicitly: +it is always half the current queue limit. +When the high water mark is exceeded, writes normally block until a reader drains the +queue below its low water mark; the writer is then allowed to proceed. +Conversely, readers normally block when the queue is empty, until a writer +arrives with data, or the queue is closed. +.PP +A queue can be given a +.I kick +function when the queue is created by +.IR qopen . +The function is invoked by +.IR qread +and +.IR qbread , +to prod an output routine when the queue falls below the low-water mark, and by +.IR qwrite , +.IR qbwrite +and +.IR qiwrite , +to notify a reader that a queue is no longer empty. +Because +.I kick +is called from the reading (or writing) process, or an interrupt handler, it +must not block. +.PP +Interrupt handlers must not +.IR sleep (10.2), +and are therefore restricted to using only the non-blocking functions described below. +.SS "Stream mode and message mode" +In stream mode, +no read will return more than one +block +of data, but +a read can split a block that contains more data than requested, leaving the remainder +in a new block at the front of the Queue. +Writes of more than the maximum +.B Block +size (currently 128k bytes) +are split into as many Blocks as required, each written separately to the queue, +in order, but with possible flow-control between them. +The queue is locked meanwhile, however, so that data from other writers is not intermingled. +.PP +In message mode, by contrast, a read will return at most +one block's worth of data, but the remainder of a partially-read block will be discarded, +not returned to the queue. +If a write count exceeds the maximum +.B Block +size, the excess data is discarded: +at most a single block can be queued. +.PP +The mode of the queue should be taken into account in the descriptions below +of the following functions: +.IR qwrite , +.IR qiwrite , +.IR qbread +and +.IR qconsume . +No other functions are aware of the distinction. +.SS "Write operations (flow controlled)" +.I Qwrite +copies +.I len +bytes of data from +.I buf +into one or more +.B Blocks +which it places on the +.IR q . +.I Qwrite +always returns +.IR len . +It can implement message mode. +.PP +.I Qbwrite +places the single Block +.I b +on the tail of +.IR q , +waking any sleeping reader. +If the queue is full, the +writing process blocks until a reader +has reduced the queued data to +the low-water mark; +if the queue is non-blocking +(see +.I qnoblock +below), +the data is discarded without notice. +.I Qbwrite +normally returns +.IR len , +but raises an +.IR error (10.2) +if the queue is closed (see +.I qhangup +and +.IR qclose ). +The block +.I b +is always freed. +Note that +.I b +can be empty (zero-length), to punctuate the data in a queue. +.I Qbwrite +cannot handle a list of Blocks; +.I qpass +must be used instead. +.SS Non-blocking writes +.PP +.I Qproduce +returns -1immediately if +.I q +is full. +Otherwise, it queues +.I len +bytes of data from +.I buf +in a single +.B Block +on +.I q +and returns the number of bytes written. +.PP +.I Qpass +attempts to place the list of Blocks headed by +.I b +on +.IR q , +returning the number of bytes written if successful. +If +.I q +was full, it +frees the Block list +.I b +and returns -1. +.PP +.I Qpassnolim +puts the Block list +.I b +on +.I q +regardless of flow control; it returns the number of bytes in the list +.IR b . +.PP +.I Qiwrite +is a variant of +.I qwrite +used exclusively by the kernel print function, +to allow printing by interrupt handlers; +.I qiwrite +could be used with care by other routines, but +.IR qproduce +is preferable. +.I Qiwrite +writes the +.I len +bytes of data at +.I buf +into the +.I q +without regard to flow control; +the writer never blocks. +The queue is assumed to be open. +.I Qiwrite +always returns +.IR len . +It can implement message mode. +.SS "Read operations (flow controlled)" +.I Qbread +blocks until data arrives on +.IR q , +then +returns the first +.BR Block ; +it limits the data returned +to +.I len +bytes (in the manner depending on the mode of +.IR q ). +It returns a null pointer if the queue has hung up. +.PP +.I Qread +reads a Block of up to +.I len +bytes from +.I q +using +.IR qbread , +and copies the data in the Block into +.IR buf , +then frees the Block and returns +the number of bytes read. +.I Qread +returns 0 on end of file or error (hangup). +It can implement message mode. +.PP +.I Qcopy +returns a Block with a copy of data from the queue (the data remains on the queue). +The copy begins +.I offset +bytes into the queue's data and proceeds until +.I len +bytes have been copied or no more data remains. +The Block's read and write pointers delimit the data copied into it. +.I Qcopy +can be used by a reliable transport protocol to copy a packet for transmission, +leaving the data queued for possible retransmission, if unacknowledged. +.SS Non-blocking reads +.PP +.I Qconsume +returns -1 immediately if +.I q +is empty. +Otherwise, it +copies up to +.I len +bytes from the first +.B Block +on the queue into +.IR buf , +returning the number of bytes copied. +It can implement message mode. +.PP +.I Qget +returns a null pointer immediately if +.I q +is empty or closed. +Otherwise, it +returns the first +.B Block +on the queue. +.SS "Discard and flush" +.I Qdiscard +removes the first +.I len +data bytes from +.IR q ; +it returns the number of bytes actually discarded, in case +the queue is shorter than +.IR len . +If the queue drains below the low-water mark, +.I qdiscard +wakes any sleeping writers. +Since it does not block, +.I qdiscard +can safely be called from interrupt handlers. +It is useful in transport protocol drivers to remove data from the queue +once acknowledged. +.PP +.I Qflush +discards all data waiting on +.IR q , +waking any waiting writer. +.SS "Queue status" +The following functions return a Queue's status. +Note that between a call to one of these functions and another operation, +the state can change if a driver allows concurrent access by +either another process or an interrupt handler. +.PP +.I Qlen +returns the number of bytes queued on +.IR q . +.PP +.I Qwindow +returns the number of bytes that can be written before reaching the queue's high-water mark. +A return of 0 means that a write operation will certainly block; +a non-zero return gives no guarantees (see +.IR qfull , +below). +.PP +.I Qcanread +returns 1 if any data queued is queued. A subsequent read operation will not block. +.PP +.I Qfull +returns non-zero if +.I q +is flow-controlled and a write would block or a non-blocking write would return an error. +(Note that the implementation allows +.I qwindow +to return non-zero yet +.I qfull +to return true.) +.SS "Queue control" +.I Qsetlimit +sets the high water mark for the queue to +.IR limit . +Note that +.I qopen +saves the initial queue limit. +If the queue is closed and reopened (by +.IR qreopen ) +that initial limit is restored. +.PP +.I Qnoblock +sets or resets non-blocking mode. +If +.I nonblock +is non-zero, +the queue becomes non-blocking, and +data written to a queue beyond its high water mark is discarded +by calls that would otherwise block. +.SH SOURCE +.B /os/port/qio.c +.br +.B /emu/port/qio.c +.SH SEE ALSO +.IR allocb (10.2), +.IR ref (10.2) |
