Subject: Re: What do you use NetBSD/Mac68k for??
To: Michael R. Zucca <mrz5149@acm.org>
From: David Gatwood <dgatwood@gatwood.net>
List: port-mac68k
Date: 11/20/2002 13:33:08
On Wed, 20 Nov 2002, Michael R. Zucca wrote:

> I know I must be making horse-paste saying this, but is there a free 
> running counter register somewhere on the 68k Macs that we could use to 
> adjust for lost clock ticks?

Don't think so.  But you could use a VIA 1 second tick or something to get
a very coarse-grained correction.  Unlikely that interrupts would ever be
blocked for more than a second.  :-P

A few months ago, I was working on a fix for the clock drift problem, but
I ran into a snag where I couldn't create a kernel thread successfully
without causing a panic.  If I have time, I'd like to try to fix that
sometime.

The idea was to set up an interrupt handler thread scheme similar to the
design Mac OS X uses (although a much simpler).

The design is fairly straightforward.  The interrupt handlers are replaced
by stubs that do nothing byt clear the interrupt and increment a counter.  
After servicing an interrupt, the interrupt service thread (IST) is woken
up and the interrupt service routine (ISR) is called.  The IST also
executes periodically when interrupts do not occur, to prevent certain
race conditions that might otherwise be possible.

The major changes needed are to rip out all the splfoo calls in the
interrupt handlers, rename them as a static function, move the code that
clears the pending interrupt into a new stub handler, and add an call to
register the ISR with the IST in the driver init code.

The big advantage to this scheme is that, with the exception of the few
milliseconds needed to increment a simple counter, interrupts are never
disabled, which means interrupts never get lost, although clock interrupts
can get queued up for a while in the worst case.  The only significant
disadvantage is that there might be a slight drop in i/o performance,
since most I/O would now be handled in a thread (albeit a high priority
kernel thread).

Communication between the low level interrupt handlers and the IST occurs
using two counters: interrupts_pending and interrupts_serviced.  These
increase monotonically, rolling over as needed.  Both start at zero.  
When an interrupt occurs, the interrupt handler increases the value stored
in interrupts_pending.  When the IST gets to execute, it compares the
values in a loop, calling the ISR and increasing interrupts_serviced each
time through the loop, until the values are equal.  It then repeats for
any other ISRs that are registered in the ISR table.

As an added note, certain drivers that don't block for a long period of
time and need low latency (the ADB driver comes to mind) should probably
be handled directly as it is now.  Depending on the IPL of the ADB
hardware, this might even improve perceived responsiveness on the console.


Comments?
David

---------------------------------------------------------------------
David A. Gatwood                                dgatwood@gatwood.net
Developer Docs Writer                             dgatwood@apple.com
Apple Computer                                  dgatwood@mklinux.org

                    Check out my weekly web comic:
                     http://www.techmagazine.org