If a thread blocks on a condition with cv_wait(9F), and that condition does not occur, it can wait forever. For that reason, it is often preferable to use cv_timedwait(9F), which depends upon another thread to perform a wakeup. cv_timedwait(9F) takes an absolute wait time as an argument and returns -1 if the time is reached and the event has not occurred. It returns a positive value if the condition is met.
cv_timedwait(9F) requires an absolute wait time expressed in clock ticks since the system was last rebooted. This can be determined by retrieving the current value with ddi_get_lbolt(9F). The driver usually has a maximum number of seconds or microseconds to wait, so this value is converted to clock ticks with drv_usectohz(9F) and added to the value from ddi_get_lbolt(9F).
Example 3–2 shows how to use cv_timedwait(9F) to wait up to five seconds to access the device before returning EIO to the caller.
clock_t cur_ticks, to;
mutex_enter(&xsp->mu);
while (xsp->busy) {
cur_ticks = ddi_get_lbolt();
to = cur_ticks + drv_usectohz(5000000); /* 5 seconds from now */
if (cv_timedwait(&xsp->cv, &xsp->mu, to) == -1) {
/*
* The timeout time 'to' was reached without the
* condition being signalled.
*/
/* tidy up and exit */
mutex_exit(&xsp->mu);
return (EIO);
}
}
xsp->busy = 1;
mutex_exit(&xsp->mu);
Although device driver writers generally find it preferable to use cv_timedwait(9F) over cv_wait(9F), there are situations in which cv_wait(9F) is a better choice. For example, cv_wait(9F) would be better when a driver is waiting on:
Internal driver state changes, where such a state change may require some command to be executed, or a set amount of time to pass.
Something the driver needs to single-thread.
Some situation that is already managing a possible timeout, as when “A” depends on “B,” and “B” itself is using cv_timedwait(9F).