A multiple-readers, single-writer lock is represented by the krwlock_t data type. This type of lock will allow many threads to have simultaneous read-only access to an object.
Only one thread may have write access at any one time. An object which is searched more frequently than it is changed is a good candidate for a readers/writer lock.
Readers/writer locks are slightly more expensive than mutex locks, and the advantage of multiple read access may not occur if the lock will only be held for a short time.
rw_init() initializes a readers/writer lock. It is an error to initialize a lock more than once. The type argument should be set to RW_DRIVER. If the lock is used by the interrupt handler, the type-specific argument, arg, should be the ddi_iblock_cookie returned from ddi_get_iblock_cookie(9F) or ddi_get_soft_iblock_cookie(9F). If the lock is not used by any interrupt handler, the argument should be NULL.
rw_destroy() releases any resources that might have been allocated by rw_init(). It should be called before freeing the memory containing the lock.
rw_enter() acquires the lock, and blocks if necessary. If enter_type is RW_READER, the caller blocks if there is a writer or a thread
attempting to enter for writing. If enter_type is RW_WRITER, the caller blocks if any thread holds the lock.
NOTE: It is a programming error for any thread to acquire an rwlock it already holds, even as a reader. Doing so can deadlock the system: if thread R acquires the lock as a reader, then thread W
tries to acquire the lock as a writer, W will set write-wanted and block. When R tries to get its second read hold on the lock, it will honor the write-wanted bit and block waiting for W; but W cannot
run until R drops the lock. Thus threads R and W deadlock.
rw_exit() releases the lock and may wake up one or more threads waiting on the lock.
rw_tryenter() attempts to enter the lock, like rw_enter(), but never blocks. It returns a non-zero value if the lock was successfully entered, and zero otherwise.
A thread which holds the lock exclusively (entered with RW_WRITER), may call rw_downgrade() to convert to holding the lock non-exclusively
(as if entered with RW_READER). One or more waiting readers may be unblocked.
rw_tryupgrade() can be called by a thread which holds the lock for reading to attempt to convert to holding it for writing. This upgrade can only succeed if no other thread is
holding the lock and no other thread is blocked waiting to acquire the lock for writing.
rw_read_locked() returns non-zero if the calling thread holds the lock for read, and zero if the caller holds the lock for write. The caller must hold the lock. The system may
panic if rw_read_locked() is called for a lock that isn't held by the caller.
|