Delay for less than time slice or system tick?

Delay for less than time slice or system tick?

Post by ian_goldb » Wed, 26 Apr 2006 17:09:23


What is the best way in OS-9 to make some code delay for a period of
time less than the length of the system tick? (I.e. less than the
minimum time offered by _os_sleep() and friends.)

We need this to drive some rather esoteric hardware. We don't want to
change the system tick time from its default of 10 ms, but we need
delays of the order of 10 microseconds.

We would like to write this in C if possible so that it is
processor-independent, but if it has to be in assembler - well, we're
currently using a Motorola PPC processor. Ideally, the delay function
should not be dependent on processor clock speed, since we are using a
variety of differently clocked processors.

Thanks in advance for any suggestions.
 
 
 

Delay for less than time slice or system tick?

Post by OS-9 A » Wed, 26 Apr 2006 23:11:08

The kernel only knows tick rates, so you cannot sleep for less than a
tick count. Realistically, it's n-1, (2 ticks minimum) since 1 tick
isn't useful (it could be anywhere within the tick depending on the
current timeslice).

So, if the hardware ticker is set to 100 ticks per second and you want
to sleep with greater resolution that your hardware ticker, you have to
use a different hardware timer source. If you have a programmable
timer, you could create a simple device driver OR system state
application program that sends a wakeup signal.

Then, you could do something like:

_os_sigmask(1); /* mask signals until I am ready */
/* notify signal "driver" or app code here */
count = 0; /* forever! */
_os_sleep(&count,&sigval); /* sleep unmasks signals for us */

So, your app would just go to sleep forever (or set to high timeout
value in case something happens) and your "notify signal" part would
set up a hardware timer to respond to, then send a signal to the above
process.

The best way -- and the way OS-9 was designed -- is to increase the
ticker resolution. You can set the high bit in F_Sleep to make the
kernel calculate based on 256ths of a tick -- ie,

time = (1<<31) | (x * 256);

x = 256; /* 256 256ths of a tick; 1 second on any system */

But you will see that some values won't make sense on a 100 tick per
second system. ie, "1" there would be 1/256, which would be rounded up
to one tick.

But, this does let you leave your C code alone and run on any system
that has a ticker at the highest resolution.

By the way, what version of OS-9 are you running? PowerPC 4.5 is the
latest release, and just came out a few months ago. It not only has
various bug fixes and updates, but also some optimizations. Kernel
event creation is now even faster in certain situations, and there has
been some new power management support added for certain PPC families.
If you have a support contract, you can get the update free (well, not
"free" since that's why you pay the support contract, but you know what
I mean).

Allan Batteiger in Dallas (www.rtsi.com) handles distribution/updates
for Microware OS-9 in the USA.

-- Al

 
 
 

Delay for less than time slice or system tick?

Post by Ian » Thu, 27 Apr 2006 00:37:02

Thanks, Al.

Regarding increasing the ticker rate, if I multiply the ticker rate by
5000 (to give 2 microsecond resolution, just about the minimum I could
get away with) and also multiply the ticks per timeslice by 5000 to
keep the timeslice unchanged, will this place any additional burden on
the CPU? My guess is that will place a considerable additional burden
on the CPU, which is why I don't want to do this. I'm not even sure the
Kontron VMP1 card we are using is capable of ticking that fast.

Our first attempt at creating short delays was to write a loop doing
some floating point arithmetic and calibrating it empirically. The
problem is that the timings are not consistent, and also depend on the
processor clock speed. I'm looking for something better than this.

Incidently, whenever I want to sleep for a certain duration, I always
calculate the number of ticks from CLOCKS_PER_SEC, so they are already
independent of the ticker rate.
 
 
 

Delay for less than time slice or system tick?

Post by Allan R. B » Thu, 27 Apr 2006 01:14:36

Ian
The only way to get a fine resolution clock is to use some HW to
generate an interrupt and have the interrupt handler send your process a
signal. The way this is handled in teh Traffic Signal world, is we
created an API that defines a high resolution clock at 100us. You can
then call the clock to send you a signal at so many "ticks" ( not system
clock tick). This has an advantage over increasing the system ticker
rate which will place an additional overhead on the system as a whole.
Using a seperate HW high speed timer, the overhead is only when you need
it. The VMP1 has an 8240 chip which I belive has several high speed
timers available in it. You can define your own tick rate, and API
quite easily.


Allan R. Batteiger


@i40g2000cwc.googlegroups.com:
 
 
 

Delay for less than time slice or system tick?

Post by OS-9 A » Thu, 27 Apr 2006 06:47:49

Here's some examples of CPU usage at different tick rates -- you may be
surprised at how small an impact it really makes. I would pump IRQs on
an old 75Mhz 486 laptop to 44,000/second to play audio, for instance...
Here's a snippet:

How busy is the system? How much can you get done? What is the overhead
of all the other stuff going on? This program tries to answer these
questions by sitting in a tight loop, counting, for a certain amount of
time. The end result can be used to measure
this. Sorta.

Usage: Run this program at the highest priority (65535) and see how
high the counter can count. On a system with a higher ticker rate,
more time will be taken up by IRQ/kernel functions, so the program will
count to a lower number. For example, on a PowerPC MVME2100 at 1000
ticks per second:

$ business ^65535
d_tcksec = 1000 (0x03e8)
d_ticks = 8000 (0x1f40)
d_ticks = 18020 (0x4664)
Counted to 333350788 in 10020 ticks (10.020000 seconds).

But on the same system, running the MAX tick rate of 65535:

$ business ^65535
d_tcksec = 65535 (0xffff)
d_ticks = 487934 (0x771fe)
d_ticks = 1143302 (0x117206)
Counted to 295289670 in 655368 ticks (10.000275 seconds).

And using a stock tick rate of 100:

$ business ^65535
d_tcksec = 203 (0x00cb)
d_ticks = 1305 (0x0519)
d_ticks = 3345 (0x0d11)
Counted to 334712547 in 2040 ticks (10.049261 seconds).

As you can see, a higher tick rate will give less CPU time to your
processes. Since pre-emption can occur at any point during a time
slice, a higher tick rate is really only needed when alarms or sleeps
need a finer granularity than the default of 100 ticks per
second.
 
 
 

Delay for less than time slice or system tick?

Post by Ric Yeate » Thu, 27 Apr 2006 10:13:06

If you don't need to sleep during this delay, the following might be
helpful:

The PowerPC also has a time base register that's constantly counting up.
It's a 64-bit register (two 32-bit SPRs). The rate at which it counts is
clock-rate specific, but it wouldn't be too hard to dynamically
determine at which clock rate you're running by knowing the
ticks-per-second and counting how many TBR counts happened over 1 or
several ticks.

The manual I looked at said user-state code could read the TBR without a
problem.

Ric
 
 
 

Delay for less than time slice or system tick?

Post by Ian » Thu, 27 Apr 2006 17:25:39

Thanks again for all of the replies.

I now see that despite not loading the CPU as much as I thought,
increasing the tick rate to its maximum, 65535 ticks per second, will
only give a resolution of 15 microseconds - not really enough for our
purposes.

Allan's suggestion of using the onboard 8204 timer to generate an
interrupt is a great one.

In fact we don't really need to sleep during the delay, so Ric's
suggestion of using the time base register sounds like our best bet.
The driver can calibrate this on initialisation.