|
|
#include <sys/clock.h> int timeout(int (routine)(), caddr_t arg, int clock_ticks);int nano_timeout(int (routine)(), caddr_t arg, struct timespec *tp);
void untimeout(int id);
The timeout( ) and nano_timeout( ) functions schedule a routine to be executed at a specific time in the future, returning an integer identification number. The untimeout( ) function cancels a timeout request using this integer identification number.
time_t tv_sec /* seconds since 1970-01-01 00:00:00 UTC */ long tv_nsec /* and nanoseconds */
untimeout( ) has no return value.
These routines can be used in interrupt context only if the interrupt priority level does not block the clock interrupt. Do not use if the spl(D3oddi) level is at spl6( ), spl7( ), splhi( ), splni( ), or spltty( ).
For ODDI versions prior to 6, these functions can be used in initialization context, with this warning: the clock interrupts are not enabled before the init( ) routine is called, so the timeout may not elapse when specified, but will elapse no later than (time_when_clock_started + clock_ticks) multiplied by the length of one clock tick. In general, the suspend(D3oddi) function is a better choice for initialization context.
The behavior of the timeout( ) function is largely unaffected by this work, although your driver may benefit from some bug fixes that are associated with this work.
Drivers that need higher-precision timeout functionality should use the nano_timeout( ) function instead of timeout( ) but must be coded to also call timeout( ) if they are supported for earlier releases.
There is no DDI equivalent to the nano_timeout( ) function; SVR5 uses the PIT-based timer for all system clock operations.
``Clock, system'' in HDK Technical Reference
#define PERIOD 5 /* 5 clock ticks */ #define BUSYPRI (PZERO -1) /* block signals while asleep */Note that the stopwait( ) function executes in interrupt context, so it must only call functions that can be called in interrupt context such as wakeup(D3oddi)./* Declare routine to use in timeout() */ int stopwait();
/* Declare flag used to indicate whether to continue waiting */ int status;
int busywait() /* Wait until status is non-zero */ { while (status == 0) { timeout(stopwait, (caddr_t) &status, PERIOD); sleep(&status, BUSYPRI); } }
int stopwait(caddr_t arg); { if ( /* The desired event has occurred */ ) status = 1; wakeup(arg); }
A device driver should never loop while waiting for a status change unless the delay is less than 100 microseconds. Also, setting a timeout for fewer than three clock ticks may result in the sleep call happening after the timeout has occurred. This results in the driver being hung: that is, it is in a permanent sleep condition.