HDK Technical Reference


lbolt is a signed int that counts the number of clock ticks since the system was booted. Drivers that use traditional driver interfaces use lbolt to keep track of short delays or timeouts.

In earlier operating systems, drivers accessed lbolt values directly. lbolt becomes negative after the system has been up long enough for lbolt to wrap. For example, with a 32-bit clock_t value and a HZ value of 100 ticks-per-second, lbolt becomes negative after approximately 248 days; see ``CLOCK_MAX''. Code that depends on lbolt not becoming negative or that compares old and new values of lbolt may produce unintended results after the system has been up for 248 days.

Beginning with DDI 8 and ODDI 5, drivers can use the TICKS(D3) macros to access lbolt values and avoid the problems traditionally associated with manipulating the lbolt value either directly or, for DDI drivers, with the drv_getparm(D3) function. The TICKS macros are:

determine current lbolt value

determine time interval in ticks since the specified time

determine time interval in ticks between two specified times

determine lbolt value for a time approximately four months in the past

determine lbolt value for a time approximately four months in the future

compare two lbolt times to determine which is more recent

For example, to determine whether or not MAX_TICKS have elapsed since time start_time could be written:
   start_time = TICKS();

/* do something */

if (TICKS_SINCE(start_time) >= MAX_TICKS)

As another example, the following code determines when at least one half second has elapsed:
   start_time = TICKS();

/* do something */

if (TICKS_SINCE(start_time) >= Hz/2)

/* action to take */

Note the use of the Hz variable to represent the number of ticks in a second.

Earlier DDI and ODDI implementations

Drivers written for DDI versions prior to version 8 and ODDI versions prior to version 5 must deal more directly with lbolt operations. DDI drivers use the drv_getparm(D3) function with the LBOLT parameter whereas ODDI drivers access lbolt directly, but similar issues are involved.

An example of the incorrect use of lbolt is the test

Incorrect use of lbolt

   if (lbolt >= (start_time + MAX_TICKS)	/* INCORRECT use of lbolt */
This is intended to determine whether or not MAX_TICKS ticks have passed since time start_time, but fails if start_time and (start_time+MAX_TICKS) are positive while lbolt has wrapped and is negative.

To avoid these problems, compare the lbolt values by subtracting one value from the other, as in:

   if (lbolt - start_time >= MAX_TICKS)	/* CORRECT use of lbolt */
The subtraction works whether lbolt is negative or positive. Both lbolt and start_time must be declared as signed integers. Otherwise, the code will compile and appear to work correctly, but will have problems after the system is up for 248 days.

DDI drivers should never access lbolt directly, but should use the LBOLT flag to the drv_getparm(D3) function. Use the drv_hztousec(D3) and drv_usectohz(D3) functions to convert between clock ticks and microseconds.

The proper way to access lbolt through the drv_getparm( ) function is illustrated below:

Accessing lbolt for DDI versions prior to version 8

   	clock_t start_time, end_time;

drv_getparm(LBOLT, &start_time);

/* do something */

drv_getparm(LBOLT, &end_time); duration_in_usec = drv_hztousec(end_time - start_time); }

Note the final conversion to microseconds, which are implementation-independent units. The driver does not actually know how long a tick is.

ODDI drivers access the lbolt variable directly. The proper way to use lbolt on SCO OpenServer 5 systems is illustrated below. This code determines when at least ten clock ticks have elapsed.

Accessing lbolt for ODDI drivers on SCO OpenServer 5

   start_time = lbolt

/* do something */

if (lbolt - start_time >= 10) {

/* action to take */ }

It is important to test behavior near the 248- and 497-day boundaries, when lbolt wraps from positive to negative and then from negative to positive. Such tests can be done by directly setting lbolt to values a few minutes before each rollover point using the kernel debugger. For SCO OpenServer Release 5.0.4 and later, the user-level scodb(ADM) facility can be used in a script to repeatedly reset lbolt to various boundary values.

UDI implementation

UDI provides timer facilities that hide all these issues from the driver writer. This is necessary to handle the variations in system time units and the implementation difficulties associated with direct access to lbolt. UDI driver writers can access the system timer resolution using the udi_timestamp_t object, but are not allowed to access times directly in ``native'' units.

Chapter 15 of the UDI Specification is dedicated to time management and discusses the functions used to replace lbolt code in a driver: udi_timer_start( ), udi_timer_start_repeating( ), udi_timer_cancel( ), udi_timer_current( ), udi_time_between( ), and udi_time_since( ).

© 2005 The SCO Group, Inc. All rights reserved.
OpenServer 6 and UnixWare (SVR5) HDK - June 2005