Skip Navigation Links | |
Exit Print View | |
STREAMS Programming Guide Oracle Solaris 11.1 Information Library |
Part I Application Programming Interface
2. STREAMS Application-Level Components
3. STREAMS Application-Level Mechanisms
4. Application Access to the STREAMS Driver and Module Interfaces
7. STREAMS Framework - Kernel Level
8. STREAMS Kernel-Level Mechanisms
11. Configuring STREAMS Drivers and Modules
Multithreaded (MT) STREAMS Overview
Routines Used Inside a Perimeter
Asynchronous Callback Functions
Unloading a Module that Uses esballoc
Sample Multithreaded Device Driver Using a Per Module Inner Perimeter
Sample Multithreaded Module With Outer Perimeter
14. Debugging STREAMS-based Applications
B. Kernel Utility Interface Summary
Although the result is not reliable, you can use explicit locks either instead of perimeters or to augment the concurrency restrictions provided by the perimeters.
Caution - Explicit locks cannot be used to preserve message ordering in a module because of the risk of re-entering the module. Use MT STREAMS perimeters to preserve message ordering. |
All four types of kernel synchronization primitives are available to the module writer: mutexes, readers/writer locks, semaphores, and condition variables. Because cv_wait implies a context switch, it can only be called from the module's open and close procedures, which are executed with valid process context. You must use the synchronization primitives to protect accesses and ensure the integrity of private module data structures.
When adding locks in a module, observe these constraints:
Avoid holding module private locks across calls to putnext(9F). The module might be re-entered by the same thread that called putnext(9F), causing the module to try to acquire a lock that it already holds. This can cause kernel panic.
Do not hold module private locks, acquired in put or service procedures, across the calls to qprocson(9F) or qprocsoff(9F). Doing this causes deadlock, since qprocson(9F) and qprocsoff(9F) wait until all threads leave the inner perimeter.
Similarly, do not hold locks, acquired in the timeout(9F) and bufcall(9F) callback procedures, across the calls to untimeout(9F) or unbufcall(9F). Doing this causes deadlock, because untimeout(9F)and unbufcall(9F) wait until an already executing callback has completed.
The first restriction deters using module private locks to preserve message ordering. The preferred mechanism is to use MT STREAMS perimeters to preserve message ordering.
Module private locks cannot be used to preserve message ordering because they cannot be held across calls to putnext(9F) and the other messages that pass routines to other modules. The alternatives for preserving message ordering are:
Use MT STREAMS perimeters.
Pass all messages through the service procedures. The service procedure can drop the locks before calling putnext(9F) or qreply(9F), without reordering messages, because the framework guarantees that at most, one thread will execute in the service procedure for a given queue.
Use perimeters to avoid the performance penalty for using service procedures.