Subject: Re: _delay: and SCSI
To: Michael Richardson <mcr@latour.sandelman.ocunix.on.ca>
From: David Jones <dej@achilles.net>
List: port-sun3
Date: 12/05/1995 08:23:45
To achieve minimal-overhead delays, we want to sleep for

delaytime * clockfreq
---------------------
     looptime

iterations, where looptime is the time taken to perform one iteration of the
delay loop.  The current code computes (delaytime*clockfreq) in advance,
and suffers due to the time required to do the multiply.

Far better would be to compute (clockfreq/looptime) at boot time using
fixed-point arithmetic, possibly 64-bit if that's warranted.  The result
is a "constant" that can be accumulated until the fixed-point sum is
greater than delaytime, e.g.:

delay(int usecs)
{
long long sum = INT_TO_FIXEDPT(usecs);

    while (sum > 0) sum -= delayval;
}

Where delayval is the calibration constant previously computed.

Of course, this is written in assembler for maximum speed (small granularity)
and INT_TO_FIXEDPT() is at worst a swap instruction, or if 64-bit
values are used, it "disappears" into the multiprecision addition.  The
inner loop could be something like:

1$ sub.l d0,d2
   subx.l d1,d3
   bpl.s 1$

Comments?