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).