Next | Prev | Up | Top | Contents | Index

Special Considerations for Multiprocessing

In IRIX releases prior to 6.2, the STREAMS monitor was single-threaded, so that only one put() or srv() function in the entire system could execute at any time. That one put() or srv() function might execute concurrently with user-level code, but no two STREAMS functions could execute concurrently.

Beginning with IRIX 6.2, the STREAMS monitor is multi-threaded. Depending on the version of IRIX and on the number of CPUs in the system, the following functions can run concurrently in any combination: one srv() function for each queue; any number of put() functions for each queue; and one or more user processes. For general discussion of the consequences, see "Planning for Multiprocessor Use".

In the multithreaded monitor, when a module or driver calls putq() or qenable(), the service function for the enabled queue can begin to execute at any time. It can begin execution before putq() or qenable() call has returned, and can run concurrently with the module or driver that enabled the queue.

The STREAMS monitor runs concurrently with interrupt handling. For this reason, the interrupt handler of a STREAMS driver must take an extra step before it performns any STREAMS-related processing such as allocb(), putq(), or qenable(). The IRIX-unique functions provided for this purpose are summarized in Table 19-1.

Multiprocessing STREAMS Functions
NameCan Sleep?Summary
streams_interrupt(D3) NSynchronize interrupt-level function with STREAMS mechanism.
STREAMS_TIMEOUT(D3) NSynchronize timeout with STREAMS mechanism.

Suppose that the interrupt handler of a STREAMS driver needs to add a message to the read queue with putq(). It cannot simply call that function, since the STREAMS monitor might be using the queue at the same time in another CPU. The driver must define a function in which the putq() call is written. The name of this function and the pointer to the queue are passed to streams_interrupt(). As soon as possible, streams_interrupt() gets control of the queue and executes the passed function.

A callback function scheduled using itimeout() and similar functions (see "Waiting for Time to Pass") must also be synchronized with the STREAMS monitor.

Suppose that a STREAMS driver or module needs to schedule a function to execute at a later time. (In a nonSTREAMS driver the function would be scheduled with itimeout().) In the time-delayed function is a call to qenable(). That call cannot be executed freely whenever the interval expires, because the state of the STREAMS monitor is not known at that time.

The STREAMS_TIMEOUT macros provide a solution. Like itimeout(), it schedules a function to be executed at a later time. However, it defers calling the function until the function is synchronized with the STREAMS monitor, so that it can execute calls such as qenable().



Next | Prev | Up | Top | Contents | Index