[comp.sys.mac.programmer] Patching Trap Calling under Multifinder

tomc@mntgfx.mentor.com (Tom Carstensen) (06/16/88)

What are the rules for patching trap calls under
Multifinder?

What I'm trying to do is patch _DrawMenuBar, to
call a routine that simply sets a global flag, and then
calls the actual _DrawMenuBar.

This works great NOT using Multifinder, but BOOM/Crash
under Multifinder.

I tried restoring/installing the patch on suspend/resume
events, but it still crashed.

What can and can't I do??

:------------------------------------------------------------:
: Tom Carstensen         Usenet: tomc@mntgfx.MENTOR.COM      :
: Mentor Graphics                Delphi: CARSTENSEN          :
:                                GEnie:  CARSTENSEN          :
:                                                            :
:         If you are sick and tired, of all your dreadful    :
:         dimensions, let me stretch your TIME!              :
:                                       - Time Operator      :
:------------------------------------------------------------:

tomc@mntgfx.mentor.com (Tom Carstensen) (06/23/88)

I got a reponse to the message stating the the Trap
Dispatch table it kept for each application, but suggested
that perhaps _DrawMenuBar is patched by Multifinder itself.

Here's a repost of my original posting:

> What I'm trying to do is patch _DrawMenuBar, to
> call a routine that simply sets a global flag, and then
> calls the actual _DrawMenuBar.

> This works great NOT using Multifinder, but BOOM/Crash
> under Multifinder.

> I tried restoring/installing the patch on suspend/resume
> events, but it still crashed.

> What can and can't I do??

Thanks.

:------------------------------------------------------------:
: Tom Carstensen         Usenet: tomc@mntgfx.MENTOR.COM      :
: Mentor Graphics                Delphi: CARSTENSEN          :
:                                GEnie:  CARSTENSEN          :
:                                                            :
:         If you are sick and tired, of all your dreadful    :
:         dimensions, let me stretch your TIME!              :
:                                       - Time Operator      :
:------------------------------------------------------------:

Michael_mkahl_Kahl@cup.portal.com (06/26/88)

Try calling SetUpA5() and RestoreA5() in your patch if you need access to
your globals.  Under MultiFinder, A5 may be MultiFinder's A5 when your
patch gets in.

-- Michael Kahl, Symantec

tim@hoptoad.uucp (Tim Maroney) (06/28/88)

In article <1988Jun22.111251.394@mntgfx.mentor.com> tomc@mntgfx.mentor.com
(Tom Carstensen) writes:

>Here's a repost of my original posting:
>> What I'm trying to do is patch _DrawMenuBar, to
>> call a routine that simply sets a global flag, and then
>> calls the actual _DrawMenuBar.
>
>> This works great NOT using Multifinder, but BOOM/Crash
>> under Multifinder.
>
>> I tried restoring/installing the patch on suspend/resume
>> events, but it still crashed.
>
>> What can and can't I do??

What you can't do is patch traps and assume that A5 is the same inside the
patch.  This is explicitly stated in one of the technical notes (I don't
remember the number, but I believe the title was "Don't Use Register A5
Inside Trap Patches", originally enough.)  If you want access to your A5,
you will have to manage it yourself, and be sure to set it back to what the
system passed you when you return.

My guess is that A5 is switched into MultiFinder global space when
DrawMenuBar is called - your global reference is writing into a MultiFinder
global, the task scheduler gets a wee bit confused, and that's all she
wrote.  This is only a guess, so don't hold me to it, but it would account
for what you saw if it's a correct guess.

As the aforementioned technical note also says, don't patch traps if you can
help it, and I have to say that this seems like an odd use of trap patching.
All you're going to catch is DrawMenuBar calls issued by your own
application, so why not set the global flag when you call DrawMenuBar?
Maybe you left out the one part that would make this irridesce with the
lustre of practicality for me - as presented, it seems like an example of
"tricks to avoid".
-- 
Tim Maroney, Consultant, Eclectic Software, sun!hoptoad!tim
"Strong men tremble when they hear it.
 They've got cause enough to fear it;
 It's even blacker than they smear it!
 No one mentions -- my name." - Bill Sykes, "Oliver"

dudek@ai.toronto.edu (Gregory Dudek) (06/30/88)

In article <4778@hoptoad.uucp> tim@hoptoad.UUCP (Tim Maroney) writes:
>In article <1988Jun22.111251.394@mntgfx.mentor.com> tomc@mntgfx.mentor.com
>(Tom Carstensen) writes:
>
>>Here's a repost of my original posting:
>>> What I'm trying to do is patch _DrawMenuBar, to
>>> call a routine that simply sets a global flag, and then
>>> calls the actual _DrawMenuBar.
>>
>>> This works great NOT using Multifinder, but BOOM/Crash
>>> under Multifinder.
>>
>>> I tried restoring/installing the patch on suspend/resume
>>> events, but it still crashed.
>>
>>> What can and can't I do??
>
>What you can't do is patch traps and assume that A5 is the same inside the
>patch.  This is explicitly stated in one of the technical notes (I don't
>remember the number, but I believe the title was "Don't Use Register A5
>Inside Trap Patches", originally enough.)  If you want access to your A5,
>you will have to manage it yourself, and be sure to set it back to what the
>system passed you when you return.
>
    I am pretty sure that  *IF* you de-install your patch on suspend
events (and make sure you don't miss one), you can get your A5 value from
the global "CurrentA5".  You have to be extra careful with patchs that
could get called from interrupt routines, but the one you want isn't
one of those.

    A question I was wondering about, however, is how to install
a permanent patch while running under MultiFinder.  As far as I know,
MF rips out your patches when the task ends.  The MF developer's
package doesn't address this either, so any help would be appreciated.
(I am fearing it's impossible)

  Greg Dudek
-- 
Dept. of Computer Science (vision group)    University of Toronto
Nice mailers:  dudek@ai.utoronto.ca
UUCP: {uunet,decvax,linus,pyramid,
		dalcs,watmath,garfield,ubc-vision,calgary}!utai!dudek
ARPA: user%ai.toronto.edu@relay.cs.net

goldman@Apple.COM (Phil Goldman) (07/02/88)

In article <88Jun30.162844edt.539@neat.ai.toronto.edu> dudek@ai.toronto.edu (Gregory Dudek) writes:
>    I am pretty sure that  *IF* you de-install your patch on suspend
>events (and make sure you don't miss one), you can get your A5 value from
>the global "CurrentA5".  You have to be extra careful with patchs that
>could get called from interrupt routines, but the one you want isn't
>one of those.
>

Every time a context switch occurs MultiFinder will swap out the current tasks's
patches and swap in those for the new task.  The tasks themselves know nothing
about this.  The task only gets a suspend event when a layer switch occurs,
but many context switches will occur in between layer switches.

Therefore, it is not necessary for the app to save and restore its own patches,
nor is it possible.

>    A question I was wondering about, however, is how to install
>a permanent patch while running under MultiFinder.  As far as I know,
>MF rips out your patches when the task ends.  The MF developer's
>package doesn't address this either, so any help would be appreciated.
>(I am fearing it's impossible)

MultiFinder will remove a task's patches when it quits.  Therefore, it is
necessary to do permanent trap patching in an INIT.

-Phil Goldman
Apple Computer