Mail Archives: djgpp-workers/2003/03/09/22:02:19
Example code. It doesn't protect calibration over midnight, doesn't protect
_rdtsc() against 486 class machines running NT. But I've played with it and
it seems to work. _rdtsc() protection will return _rdtsc() as zero - I'll
try to add that this week as time permits.
By the way, I disabled the version check and tested it on a P60 running
W98 and it works as expected.
Comments? The documentation for uclock() says it shouldn't be used over
midnight, but we do correct for that in the current code, so I'll fix this
to handle calibration over midnight.
--- uclock.c Tue Dec 11 21:28:06 2001
+++ uclocktk.c Sun Mar 9 20:11:58 2003
@@ -10,6 +10,7 @@
#include <go32.h>
#include <dpmi.h>
#include <libc/bss.h>
+#include <dos.h>
static int uclock_bss = -1;
@@ -29,6 +30,25 @@
unsigned long tics, otics;
uclock_t rv;
+ _farsetsel(_dos_ds);
+
+ if(_os_trueversion == 0x532) { /* Windows NT, 2000, XP */
+ #define CALIBRATION_TICS 5 /* Testing shows 1.7% std error */
+ static long divider;
+ static unsigned long long otsc;
+ if (uclock_bss != __bss_count) {
+ otics = _farnspeekl(0x46c);
+ while ( (tics = _farnspeekl(0x46c)) == otics);
+ otsc = _rdtsc();
+ otics = tics;
+ while ( (tics = _farnspeekl(0x46c)) <= otics+CALIBRATION_TICS);
+ divider = (_rdtsc() - otsc) / ((tics - otics)*65536);
+ if (divider) uclock_bss = __bss_count;
+ }
+ if (divider) /* On failure fall through */
+ return (_rdtsc() - otsc) / divider;
+ }
+
if (uclock_bss != __bss_count)
{
int e = errno;
@@ -51,7 +71,6 @@
first 55 msec after the timer was reprogrammed still look as
if the timer worked in mode 3. So we simply wait for one clock
tick when we run on Windows. */
- _farsetsel(_dos_ds);
otics = _farnspeekl(0x46c);
do {
errno = 0;
@@ -62,11 +81,11 @@
/* Make sure the numbers we get are consistent */
do {
- otics = _farpeekl(_dos_ds, 0x46c);
+ otics = _farnspeekl(0x46c);
outportb(0x43, 0x00);
lsb = inportb(0x40);
msb = inportb(0x40);
- tics = _farpeekl(_dos_ds, 0x46c);
+ tics = _farnspeekl(0x46c);
} while (otics != tics);
/* calculate absolute time */
- Raw text -