* @(#)68 1.3 src/bos/kernext/pse/README.pse, sysxpse, bos720 11/23/94 10:04:27 * IBM_PROLOG_BEGIN_TAG * This is an automatically generated prolog. * * bos720 src/bos/kernext/pse/README.pse 1.3 * * Licensed Materials - Property of IBM * * COPYRIGHT International Business Machines Corp. 1994 * All Rights Reserved * * US Government Users Restricted Rights - Use, duplication or * disclosure restricted by GSA ADP Schedule Contract with IBM Corp. * * IBM_PROLOG_END_TAG * * COMPONENT_NAME: SYSXPSE * * FUNCTIONS: * * ORIGINS: 27 * * * (C) COPYRIGHT International Business Machines Corp. 1994 * All Rights Reserved * Licensed Materials - Property of IBM * US Government Users Restricted Rights - Use, duplication or * disclosure restricted by GSA ADP Schedule Contract with IBM Corp. * README file for the STREAMS Framework srv Purpose Services queued messages for STREAMS modules or drivers. Syntax #include #include #include int rsrv(queue_t *q); /* read side */ int wsrv(queue_t *q); /* write side */ Parameters q Pointer to the queue structure. Description The optional service (srv()) routine may be included in a STREAMS module or driver for one or more of the following reasons: * to provide greater control over the flow of messages in a stream * to make it possible to defer the processing of some messages to avoid depleting system resources * to combine small messages into larger ones, or break large messages into smaller ones * to recover from resource allocation failure. A module's or driver's put() routine can test for the availability of a resource, and if it is not available, enqueue the message for later processing by the srv routine. A message is first passed to a module's or driver's put() routine, which may or may not do some processing. It must then either: * pass the message to the next stream component with putnext() * if a srv routine has been included, it may call putq() to place the message on the queue Once a message has been enqueued, the STREAMS scheduler controls the invocation of the service routine. Service routines are called in FIFO order by the scheduler. No guarantees can be made about how long it will take for a srv routine to be called except that it will happen before any user level process is run. Every stream component (stream head, module or driver) has limit values it uses to implement flow control. Tunable high and low water marks should be checked to stop and restart the flow of message processing. Flow control limits apply only between two adjacent components with srv routines. STREAMS messages can be defined to have up to 256 different priorities to support requirements for multiple bands of data flow. At a minimum, a stream must distinguish between normal (priority zero) messages and high priority messages (such as M_IOCACK). High priority messages are always placed at the head of the srv routine's queue, after any other enqueued high priority messages. Next are messages from all included priority bands, which are enqueued in decreasing order of priority. Each priority band has its own flow control limits. If a flow controlled band is stopped, all lower priority bands are also stopped. Once the STREAMS scheduler calls a srv routine, it must process all messages on its queue. The following steps are general guidelines for processing messages. Keep in mind that many of the details of how a srv routine should be written depend of the implementation, the direction of flow (upstream or downstream), and whether it is for a module or a driver. 1. Use getq() to get the next enqueued message. 2. If the message is high priority, process it (if appropriate) and pass it to the next stream component with putnext(). 3. If it is not a high priority message (and therefore subject to flow control), attempt to send it to the next stream component with a srv routine. Use canput() or bcanput() to determine if this can be done. 4. If the message cannot be passed, put it back on the queue with putbq(). If it can be passed, process it (if appropriate) and pass it with putnext(). Rules for service routines: 1. Service routines must not call any kernel services which sleep or are not interrupt safe. 2. Service routines are called by the STREAMS scheduler with most interrupts enabled. NOTE: Each stream module must specify a read and a write service (srv()) routine. If a service routine is not needed (because the put() routine processes all messages), a NULL pointer should be placed in module's qinit structure. Do not use nulldev() instead of the NULL pointer. Use of nulldev() for a srv() routine may result in flow control errors. Return Values Ignored. Related Information put(), bcanput(), canput(), getq(), putbq(), putnext(), putq(). The queue structure in /usr/include/sys/stream.h. The STREAMS Entry Points article in infoExplorer. =========================================================== Prior to AIX 4.1, STREAMS service routines were permitted which were not coded to specification (i.e. the service routine called sleep or called a kernel services which slept, etc. . .). In AIX 4.1, this behavior will cause a system failure because the STREAMS scheduler is executed with some interrupts disabled. Modules or drivers can force the old style scheduling by oring in STR_Q_NOTTOSPEC into the sc_flags field of the kstrconf_t structure. This structure is passed to the system when the module or driver calls the str_install STREAMS service. This flag will cause STREAMS to schedule the modules or drivers service routines with all interrupts enabled. Note: there is a severe performance penalty for this type of STREAMS scheduling and future releases of AIX may not support STR_Q_NOTTOSPEC. =========================================================== wantio Purpose Register direct i/o entry points with the Stream head. Syntax #include int wantio(queue_t *q, struct wantio *w) Parameters q Pointer to the queue structure. w Pointer to the wantio structure. Description The wantio STREAMS routine may be used by a STREAMS module or driver to register input/output (read/write/select) entry points with the Stream head. The Stream head then calls these entry points directly, by-passing all normal Streams processing, when an i/o request is detected. This service may be useful to increase STREAMS performance in cases where normal module processing is not required or where STREAMS processing is to be performed outside of AIX. STREAMS modules and drivers should precede a wantio call by sending a high priority M_LETSPLAY message upstream. The M_LETSPLAY message format is a message block containing an integer followed by a pointer to the write queue of the module or driver originating the M_LETSPLAY message. The integer counts the number of modules which can permit direct i/o. Each module passes this message to its neighbor after incrementing the count if direct i/o is possible. When this message reaches the Stream head, the Stream head compares the count field with the number of modules and drivers in the Stream. If the count is not equal to the number of modules then a M_DONTPLAY message is sent downstream indicating direct i/o will not be permitted on the Stream. If the count is equal then queued messages are cleared by sending them downstream as M_BACKWASH messages. When all messages are cleared then an M_BACKDONE message is sent downstream. This process starts at the Stream head and is repeated in every module in the Stream. Modules will wait to receive an M_BACKDONE message from upstream. Upon receipt of this message, the module will send all queued data downstream as M_BACKWASH messages. When all data is cleared the module will send an M_BACKDONE message to its downstream neighbor indicating that all data has been cleared from the Stream to this point. Wantio registration is cleared from a Stream by issuing a wantio call with a NULL pointer to the wantio structure. Multiprocessor serialization is the responsibility of the driver or module requesting direct i/o. The Stream head acquires no STREAMS locks before calling the wantio entry point. Currently, the write entry point of the wantio structure is ignored. Return Values Returns 0 always. Related Information wantmsg(). The queue and wantio structures in /usr/include/sys/stream.h. The STREAMS Entry Points article in infoExplorer.