[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Short sleeps.



"Vesselin I. Peev" wrote:
> 
> Here's a possible solution from
> http://www.linuxdoc.org/HOWTO/mini/IO-Port-Programming-4.html
> 
> "Another way of delaying small numbers of microseconds is port I/O.
> Inputting or outputting any byte from/to port 0x80 (see above for how to do
> it) should wait for almost exactly 1 microsecond independent of your
> processor type and speed. You can do this multiple times to wait a few
> microseconds. The port output should have no harmful side effects on any
> standard machine (and some kernel drivers use it). This is how
> {in|out}[bw]_p() normally do the delay (see asm/io.h).
> Actually, a port I/O instruction on most ports in the 0-0x3ff range takes
> almost exactly 1 microsecond, so if you're, for example, using the parallel
> port directly, just do additional inb()s from that port to delay. "

This has (I think) the same problem as Mark's solution - you aren't giving
up the CPU while you delay.

Whatever the solution to this is, it has to be something that blocks
the process in the kernel (thus letting other processes run) - but causes
the kernel to recieve an interrupt that causes it to re-awaken my process
before the 10ms time-slice elapses for the other process.

* usleep doesn't work because Linux's time-slice (at least on a PC) is 10ms
  and that is therefore the frequency of the kernel's hardware timer interrupt.
  It gives up the CPU alright - but the kernel doesn't check to see if
  your process is ready to run again until it's next timer interrupt - which
  could be 10ms later.

* Your solution of writing to a port doesn't work because it doesn't cause
  the process to block.  The same is true of Mark's suggestion of watching
  some high frequency clock (like gettimeofday() - which has ~one microsecond
  precision).

* My old trick with the serial port *does* work (although it's mightily
  inconvenient) because reading from the serial port causes my process to
  block - waiting for a character to arrive.  9600 baud is close to 1000
  characters per second - so the delay between transmitting a character
  and it looping through the paperclip and back into the kernel is something
  close to one millisecond.

On a modern CPU, quite a lot of work can be done in a millisecond and I
don't want to waste that amount of time.

I was thinking of testing the idea of sending an Ethernet packet to myself
via the 'loopback' address - but if the user has PPP over a modem or something,
I don't think that's going to do what I want.  If I do a "ping loopback" on
my local network, I get ~0.3ms ping times - which would be just fine if that
worked universally.

----------------------------- Steve Baker -------------------------------
Mail : <sjbaker1@airmail.net>   WorkMail: <sjbaker@link.com>
URLs : http://www.sjbaker.org
       http://plib.sf.net http://tuxaqfh.sf.net http://tuxkart.sf.net
       http://prettypoly.sf.net http://freeglut.sf.net
       http://toobular.sf.net   http://lodestone.sf.net