STREAMS/UX for the HP 9000 Reference Manual

89
STREAMS/UX Multiprocessor Support
Writing MP Scalable Modules and Drivers
structures with STREAMS/UX modules and drivers, unless spinlocks are used to
protect critical sections. Also, the code cannot call the following utilities: backq,
bcanputnext, canputnext, flushband, flushq, freezestr, getq, insq, putbq, putnext,
putnextctl, putnextctl1, putnextctl2, qreply, qsize, rmvq, SAMESTR, strqget,
strqset, and unfreezestr.
Callback routines and non-STREAMS code cannot call bcanput, canput, put,
putctl, putctl1, putctl2 or streams_put if they pass the utility a parameter of the
form q->q_next. They can call these utilities if they pass a parameter of the
form q (q must be a valid, allocated queue). Callback and non-STREAMS code
can call putq only if they pass it a driver's read queue or a lower mux's write
queue. Callback and non-STREAMS code can use the new streams_put utility
documented in the section “HP-UX Modifications to STREAMS/UX Utilities”
in Chapter 3.
Some restrictions exist on free routines passed to esballoc. A free routine can call
STREAMS/UX utilities in the same way as the put or service routine that calls
freeb. A free routine can access the same data structures as the put or service
routine that calls freeb.
•Aprotect_q parameter can be passed to the weldq utility. The protect_q
parameter specifies which queue the func parameter can access safely. The func
function can use the same STREAMS/UX utilities as the protect_q put and
service routines. Also, the function can access the same data structures as the
protect_q put and service routines.
Put and service routines cannot be called directly. They must be executed by
calling STREAMS/UX utilities such as putnext, put, putq, or qenable. They
cannot be called using the function pointer stored in the q_qinfo structure.
STREAMS/UX applications in which multiple processes access the same stream
need to know how STREAMS/UX will synchronize operations on the stream.
See “Multiple Processes Accessing the Same Stream” in Chapter 3.
Modules and drivers can allocate their own spinlocks to protect data structures.
If they do, they should use the lock orders reserved for them in
/usr/include/sys/semglobal.h or /usr/conf/h/semglobal.h:
STREAMS_USR1_LOCK_ORDER, STREAMS_USR2_LOCK_ORDER, and
STREAMS_USR3_LOCK_ORDER.
The lock order is passed in the order parameter of the native HP-UX
alloc_spinlock primitive and the hierarchy parameter of the SVR4 MP
LOCK_ALLOC utility. The HP-UX kernel uses this information to check for
deadlocks when the kernel is compiled with SEMAPHORE_DEBUG. When a
module acquires a spinlock, the spinlock's order must be higher than the order of
any spinlocks the module already holds. Modules and drivers cannot hold