SCO OpenServer


timeout, nano_timeout, untimeout -- schedule a time to execute a routine


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


routine to be executed after the specified number of clock_ticks has elapsed. This routine executes in interrupt context; see ``Context of a driver'' in HDK Technical Reference.

Parameter passed to routine.

Pointer to a timespec structure that defines the number of seconds and nanoseconds to wait before calling routine. This structure includes the following members:
   time_t  tv_sec			/* seconds since 1970-01-01 00:00:00 UTC */
   long    tv_nsec			/* and nanoseconds */

Identification number returned by the timeout( ) call.

Return values

timeout( ) and nano_timeout( ) return an integer identification number for the timeout, if one is available. 0 (zero) is returned and the specified routine called immediately if no timeouts are available.

untimeout( ) has no return value.


For ODDI Version 6, timeout( ) is implemented using nano_timeout( ).

Context and synchronization

timeout( ) and nano_timeout( ) should normally only be used in non-blockable, initiator, or blockable context.

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.

Hardware applicability


Version applicability

timeout, untimeout
oddi: 1, 2, 2mp, 3, 3mp, 4, 4mp, 5, 5mp, 6, 6mp

oddi: 6, 6mp

Differences between versions

SCO OpenServer Release 5.0.6 includes improved clock precision that is reflected in ODDI Version 6; see ``Clock, system'' in HDK Technical Reference for more information.

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.

SVR5 DDI compatibility

The timeout(D3) function is supported in early DDI versions although the type casts of the arguments are different. The itimeout(D3) function provides similar functionality for current DDI versions.

There is no DDI equivalent to the nano_timeout( ) function; SVR5 uses the PIT-based timer for all system clock operations.


delay(D3oddi), sleep(D3oddi), spl(D3oddi), wakeup(D3oddi)

``Clock, system'' in HDK Technical Reference


timeout( ), sleep(D3oddi) and wakeup(D3oddi) can be combined to provide a ``busy wait'' function. The following code sample illustrates this possible functionality. Note that this example is only to illustrate the use of the functions; the delay(D3oddi) function actually does exactly this.
   #define PERIOD 5          	/* 5 clock ticks */
   #define BUSYPRI  (PZERO -1)  	/* block signals while asleep */

/* 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); }

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

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.

19 June 2005
© 2005 The SCO Group, Inc. All rights reserved.
OpenServer 5 HDK - June 2005