delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/06/12/12:50:50

Message-ID: <01BC7742.2B312840@TAURUS>
From: Steve Higgins <steve AT psp-digital DOT co DOT uk>
To: "'DJGPP Mail List'" <djgpp AT delorie DOT com>
Subject: Intermittent uclock() failure under DOS.
Date: Thu, 12 Jun 1997 15:06:11 +0100
MIME-Version: 1.0


Hi All,

I've been using uclock() to time some routines.

i.e.,
start = uclock();

// some stuff taking a few ms

end= uclock();

duration = end-start;

Very occasionally even under DOS I've been getting strange results - negative 
values for duration, etc.

I've finally worked out the cause. 

The function re-programs the timer to produce the low bit (0-15) of the time and 
uses the BIOS entry for ticks since midnight to generate the high order bits. 

The problem is that no attempt is made to line these two timing sources up, so if your first call to uclock() happens to occur half way between BIOS ticks, we get the low order numbers wrapping to 0 before the high order numbers have incremented.

This causes 'end' to be less than 'start' in the above example.

My bodge work around is to call the this function at the start of main().

void startup_uclock()
{
    unsigned long tics;
    
    tics = _farpeekl(_dos_ds,0x46c);
    
    /* wait for a BIOS tick */
    while(tics == _farpeekl(_dos_ds,0x46c));
    /* initialise uclock() */
    uclock();
}

Obviously this isn't perfect - An interrupt could get in between the while loop and the 
uclock() call, delaying the uclock() initialisation, etc.

This does however, seem to have fixed my problem.


Steve.


- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019