Specifications
D
evice Driver Programming
11-18
Using Multiple Locks 11
If multiple LWPs are contending for the resources of the driver, it can be more efficient to
have a different lock for each data item. Efficiency is gained because access to the differ-
ent data is allowed from different processors at the same time. The trade-off is the over-
head that comes from having to make more lock and unlock calls.
Be sure to check that the order in which the locks are acquired meets the following con-
straints:
• Sleeping
When a basic or read/write lock is held, blocking locks cannot be acquired.
• Hierarchical ordering
There must be an ordering of the locks so that a sequence of locks is always
acquired in the same order and unlocked in reverse order.
To meet these constraints, determine what the order for acquisition of these locks is for
each different type of access to the shared resource. This determines the locking rules to
be used in your driver.
If it is impossible to create an ordering for a set of locks that is always followed, then a
driver can attempt to obtain a lock in the wrong order by performing the appropriate
TRYLOCK operation (TRYLOCK, RW_TRYRDLOCK, RW_TRYWRLOCK). If the TRYLOCK
fails, then all of the locks that are currently owned must be released and then reacquired in
the correct order. Use caution when doing this, because once the locks are released, there
is no longer any guarantee about the state that these locks protect. This technique prevents
deadlocks from occurring.
Synchronization Variables 11
Synchronization variables are used to synchronize LWPs based on the occurrence of an
event. An event can be any arbitrary condition that either has or has not occurred. A syn-
chronization variable is always associated with a basic spin lock. A synchronization vari-
able is used to wait until some event has occurred. The spin lock protects the data that
indicates that the event has or has not occurred. To be sure that the event does not occur
immediately after releasing the spin lock, the lock routines for a synchronization variable
atomically release the spin lock and block the calling LWP.
First, you must allocate and initialize a synchronization variable by using the SV_ALLOC
routine:
#include <sys/kmem.h>
#include <sys/ksynch.h>
#include <sys/ddi.h>
sv_t* SV_ALLOC(flag)
int *flag;
where: