[comp.sys.mac.programmer] doing real work at interrupts

u-lchoqu%peruvian.utah.edu@cs.utah.edu (Lee Choquette) (10/31/90)

In article <2303@heavens-gate.lucid.com> pab@lucid.com (Peter Benson) writes:
>
> It seems like what is needed is a general mechanism whereby any sort of
> task can be initiated at interrupt level.  This would have to be done by
> apple, but the right thing to have is a call that effectively says "call
> this function with these arguments at the next possible opportunity."

How about opening a "device driver" that doesn't actually do any
reading or writing to a device, but has its "dNeedTime" flag set,
indicating the system should call its control routine at specific
intervals--or as often as possible if the drvrDelay word is zero.  The
system doesn't actually call the control routine until the application
calls SystemTask, but at that time you can go ahead and do all the
memory movement you want.  I believe you can even do drawing and
window management.

The Device Manager chapter (II-193) says that your control routine
should be interrupt-driven, but that apparently applies only to device
drivers that can be called asynchronously.  Since your driver isn't
really running a device, and since nobody will be calling it but
SystemTask, you don't have to worry about being asynchronous.

If you put your driver in the system heap, it should stay around until
the machine is shut down.  I have an example of a driver which I
install in the application heap whose only function is to perform
periodic actions, like the tasks you're talking about.  Given interest
I'll put it in postable form.

The main disadvantage to this scheme is that such drivers won't get
called when the application is not calling SystemTask or
WaitNextEvent, such as while it's busy reading a file, but in these
days of MultiFinder, applications which don't hog the processor but
let other tasks have time for housekeeping are becoming more and more
common.
Lee Choquette                        Internet: u-lchoqu@peruvian.utah.edu
3846 Barbara Wy                      Bitnet:   choquette@utahcca
Salt Lake City, UT  84124-2304       UUCP:     utah-cs!peruvian!u-lchoqu
(801) 581-8810, 278-0826

Lewis_P@cc.curtin.edu.au (Peter Lewis) (10/31/90)

In article <1990Oct30.131140.10113@hellgate.utah.edu>,
     u-lchoqu%peruvian.utah.edu@cs.utah.edu (Lee Choquette) writes:
> In article <2303@heavens-gate.lucid.com> pab@lucid.com (Peter Benson) writes:
>>
>> It seems like what is needed is a general mechanism whereby any sort of
>> task can be initiated at interrupt level.  This would have to be done by
> 
> How about opening a "device driver" that doesn't actually do any
> reading or writing to a device, but has its "dNeedTime" flag set,
> indicating the system should call its control routine at specific
> intervals--or as often as possible if the drvrDelay word is zero.  The
> system doesn't actually call the control routine until the application
> calls SystemTask, but at that time you can go ahead and do all the
> memory movement you want.  I believe you can even do drawing and
> window management.
> 
> The main disadvantage to this scheme is that such drivers won't get
> called when the application is not calling SystemTask or WaitNextEvent,

   If you don't mind waiting until SystemTask is called, you could patch
SystemTask at the same time as you install your interupt handler.  Then
you could have the interupt handler set a variable (PC relative) to true
when the interupt occurs, and have your SystemTask patch test this and
do the interupt handling if it is true, and then call SystemTask.

   Pseudo Code -
NewSystemTask:        TEST    an_interupt_occured
                      JSR NE  Handle_Interupt
                      JMP     (original_SystemTask)

an_interupt_occured:  DC.W    0

InterupHandler:       SET     an_interupt_occured
                      RTS

(I assume SystemTask can move memory, I don't have IM handy.)

   I don't know if its any better/worse to install a patch or a device
driver, but its probably easier to install a patch. I really home Apple's 
Thought Police haven't been listening in to this discusion!

Happy Hacking,
   Peter.

PS: The UMPG looks really good!  Anyone who wants to post a question should
look there first (it answered my last posted question)
-- 
Disclaimer:Curtin & I have an agreement:Neither of us listen to either of us.
*-------+---------+---------+---------+---------+---------+---------+-------*
Internet: Lewis_P@cc.curtin.edu.au              I Peter Lewis
ACSnet: Lewis_P@cc.cut.oz.au                    I NCRPDA, Curtin University
Bitnet: Lewis_P%cc.curtin.edu.au@cunyvm.bitnet  I GPO Box U1987
UUCP: uunet!munnari.oz!cc.curtin.edu.au!Lewis_P I Perth, WA, 6001, AUSTRALIA
"!thgir  s'ti  naem  t'nseod  yaw  taht  ti  seod  enoyreve  esuaceb  tsuJ"

nick@cs.edinburgh.ac.uk (Nick Rothwell) (10/31/90)

In article <1990Oct30.131140.10113@hellgate.utah.edu>, u-lchoqu%peruvian.utah.edu@cs.utah.edu (Lee Choquette) writes:
> In article <2303@heavens-gate.lucid.com> pab@lucid.com (Peter Benson) writes:
> >
> > It seems like what is needed is a general mechanism whereby any sort of
> > task can be initiated at interrupt level.  This would have to be done by
> > apple, but the right thing to have is a call that effectively says "call
> > this function with these arguments at the next possible opportunity."
> 
> How about opening a "device driver" that doesn't actually do any
> reading or writing to a device, but has its "dNeedTime" flag set,

Why bother? Just declare a static circular buffer, have the interrupt
routine place messages into it in some format, and have the main
application examine it somewhere in the event loop.

I did this for error messages from the MIDI Manager. It's about
1/2 hour's work, and works fine.

-- 
Nick Rothwell,	Laboratory for Foundations of Computer Science, Edinburgh.
		nick@lfcs.ed.ac.uk    <Atlantic Ocean>!mcsun!ukc!lfcs!nick
~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~
 "Now remember - and this is most important - you must think in Russian."

llama@eleazar.dartmouth.edu (Joe Francis) (11/01/90)

someone writes:
>> How about opening a "device driver" that doesn't actually do any
>> reading or writing to a device, but has its "dNeedTime" flag set,

In article <1185@skye.cs.ed.ac.uk> nick@lfcs.ed.ac.uk writes:>
Why bother? Just declare a static circular buffer, have the interrupt
>routine place messages into it in some format, and have the main
>application examine it somewhere in the event loop.

An even simpler (in my opinion) solution is for the interrupt handler to
post events to the app.  PostEvent() and PPostEvent() are not on the
"forbidden interupt time ToolBox calls" list.  Can anyone confirm they are
indeed safe in this situation?

--------------------------------------------------------------------------
"Read My Lips: No Nude Texans!" - George Bush clearing up misunderstanding

llama@eleazar.dartmouth.edu (Joe Francis) (11/01/90)

In article <4249.272ea016@cc.curtin.edu.au> Peter Lewis writes:

>In article <1990Oct30.131140.10113@hellgate.utah.edu> Lee Choquette writes:

>> The main disadvantage to this scheme is that such drivers won't get
>> called when the application is not calling SystemTask or WaitNextEvent,

>   If you don't mind waiting until SystemTask is called, you could patch
>SystemTask at the same time as you install your interupt handler.  Then
>you could have the interupt handler set a variable (PC relative) to true
>when the interupt occurs, and have your SystemTask patch test this and
>do the interupt handling if it is true, and then call SystemTask.


I must be missing something here.  If you are only going to process pending
tasks when you can make an explicit call (in this case SystemTask), why
patch a ToolBox trap to do it?

Just write MySystemTask:

extern long taskToDo;

void MySystemTask()
{
   SystemTask();
   switch (taskToDo) {
     case doNothing:
        break;
     case pukeOnUser:
        DoPukeOnUserTask();
        break;
     case eraseDrive:
        DoEraseDriveTask();
        break;
     .
     .
     .
     default:
        MyError(kBadTaskIDString);
}

----------------------------------------------------------------------------
"Read My Lips: No Nude Texans!" - George Bush clearing up a misunderstanding

urlichs@smurf.sub.org (Matthias Urlichs) (11/02/90)

In comp.sys.mac.programmer, article <25478@dartvax.Dartmouth.EDU>,
  llama@eleazar.dartmouth.edu (Joe Francis) writes:
< 
< In article <1185@skye.cs.ed.ac.uk> nick@lfcs.ed.ac.uk writes:>
< Why bother? Just declare a static circular buffer, have the interrupt
< >routine place messages into it in some format, and have the main
< >application examine it somewhere in the event loop.
< 
< An even simpler (in my opinion) solution is for the interrupt handler to
< post events to the app.  PostEvent() and PPostEvent() are not on the
< "forbidden interupt time ToolBox calls" list.  Can anyone confirm they are
< indeed safe in this situation?
< 
PostEvent is in fact safe -- but there's another problem:
Who says that _your_ application is going to receive these events?
Under MultiFinder, it doesn't matter which app is applciation posts these
events -- the frontmost application gets them.
The user might even switch programs between your PostEvent() and the next
WaitNextEvent().

-- 
Matthias Urlichs -- urlichs@smurf.sub.org -- urlichs@smurf.ira.uka.de     /(o\
Humboldtstrasse 7 - 7500 Karlsruhe 1 - FRG -- +49+721+621127(0700-2330)   \o)/

lefty@twg.com ("Lefty") (11/06/90)

In article <1185@skye.cs.ed.ac.uk> nick@cs.edinburgh.ac.uk (Nick Rothwell) 
writes:
> In article <1990Oct30.131140.10113@hellgate.utah.edu>, 
u-lchoqu%peruvian.utah.edu@cs.utah.edu (Lee Choquette) writes:
> > In article <2303@heavens-gate.lucid.com> pab@lucid.com (Peter Benson) 
writes:
> > >
> > > It seems like what is needed is a general mechanism whereby any sort of
> > > task can be initiated at interrupt level.  This would have to be done by
> > > apple, but the right thing to have is a call that effectively says "call
> > > this function with these arguments at the next possible opportunity."
> > 
> > How about opening a "device driver" that doesn't actually do any
> > reading or writing to a device, but has its "dNeedTime" flag set,
> 
> Why bother? Just declare a static circular buffer, have the interrupt
> routine place messages into it in some format, and have the main
> application examine it somewhere in the event loop.

Actually, an _real_ easy way to do this is to use Apple's Notification 
Manager.  Set up an "invisible" notification (i.e. no icon, no sound, no 
dialog), and do the work necessary in the notification proc.

I've tried it; real easy to do, and it works just fine.  My application 
was a requirement to release a block of memory in response to an 
interupt-level event.


--
Lefty  (lefty@twg.com)                        "And you may ask yourself,
DoD # 0152                                       'How do I work this?'"

pete@csc-sun.mckinsey.com (Peter Gaston) (11/10/90)

In comp.sys.mac.programmer, article <25478@dartvax.Dartmouth.EDU>,
  llama@eleazar.dartmouth.edu (Joe Francis) writes:

< An even simpler (in my opinion) solution is for the interrupt handler to
< post events to the app.  PostEvent() and PPostEvent() are not on the
< "forbidden interupt time ToolBox calls" list.  Can anyone confirm they are
< indeed safe in this situation?
< 

Do y'all remember when we were cautioned about not depending upon
AppleTalk completion information coming from the event queue?

Right, the event queue could overflow.  In general not a great
idea.

pete gaston
mckinsey & co.