[comp.sys.mac.programmer] C function ptrs & Mac mem segments

siegel@endor.harvard.edu (Rich Siegel) (05/02/90)

In article <3550@dogie.macc.wisc.edu> yahnke@vms.macc.wisc.edu (Ross Yahnke, MACC) writes:
>
>The init code, all of the C functions themselves and the routine
>that actually does the referencing (jumping) to the functions
>are all in one segment, but not the main one, (it's too big - 
>not enuf room left in the main segment to squeeze it in.) 
>
>Do I ever have to worry about the Mac memory manager purging and
>then reloading this segment thereby possibly causing the address's
>to become invalid? Should I just assume that if I'm in the 
>segment I should lock it somehow, or make it non-purgeable?
>Or perhaps just simply re-init the addresses every time I go
>into the segment?

	Not a problem. When you take the address of a function in THINK C,
what you get is the address of its jumptable entry, which, when jumped to,
will cause the segment to be loaded if it is unloaded, and in either case
you'll end up at your routine.

R.
~~~~~~~~~~~~~~~
 Rich Siegel
 Staff Software Developer
 Symantec Corporation, Language Products Group
 Internet: siegel@endor.harvard.edu
 UUCP: ..harvard!endor!siegel

"Don't try to understand 'em, just rope, throw, and brand 'em."

~~~~~~~~~~~~~~~

dce@smsc.sony.com (David Elliott) (05/02/90)

In article <5524@helios.ee.lbl.gov> beard@ux1.lbl.gov (Patrick C Beard) writes:
>Another point:  Even if the segment was unloaded, THINK C (and most other
>C compilers for the Mac that I've used) generates function pointers as
>pointers to jump table entries.  When you call a function by jump table,
>the segment is automatically loaded into memory (by the segment loader).

This is good news.

>As long as the jump table stays in memory, you don't have to worry about
>the staleness of the pointers in your structure.

How can this be assured?  For example, if one implements a new class
that has programmer-defined callbacks associated with it, how does one
save the callback function pointers so that these are assured to be
there?

I guess the real questions are:

	How do you make sure that the jump table stays in memory?

	What do you do if the jump table goes away?

-- 
David Elliott
dce@smsc.sony.com | ...!{uunet,mips}!sonyusa!dce
(408)944-4073
"Nature hates both a vacuum and a vacuum cleaner too" -- The Residents

russotto@eng.umd.edu (Matthew T. Russotto) (05/03/90)

In article <1990May2.144237.2978@smsc.sony.com> dce@Sony.COM (David Elliott) writes:

>I guess the real questions are:
>
>	How do you make sure that the jump table stays in memory?
Don't call ExitToShell.  While your program is running it always will
stay in memory.  A lot would break if this wasn't true.
>
>	What do you do if the jump table goes away?
Crash.  But it won't
--
Matthew T. Russotto	russotto@eng.umd.edu	russotto@wam.umd.edu
][, ][+, ///, ///+, //e, //c, IIGS, //c+ --- Any questions?

rmh@apple.com (Rick Holzgrafe) (05/03/90)

In article <263DD5DE.1BCE@intercon.com> amanda@mermaid.intercon.com 
(Amanda Walker) writes:
> In article <3550@dogie.macc.wisc.edu>, yahnke@vms.macc.wisc.edu (Ross 
Yahnke,
> MACC) writes:
> >[about C function pointers]
> > Do I ever have to worry about the Mac memory manager purging and
> > then reloading this segment thereby possibly causing the address's
> > to become invalid?
> 
> I believe that both THINK C and MPW C implement function pointers as
> pointers to the jump table entry for the function, not as pointers to
> the beginning of the actual code for the function.  Since the jump
> table is always resident and never moves function pointers won't move.
> Also, CODE segments oonly get unloaded if you call UnloadSeg on them
> explicitly.
> 
> The thing you do have to watch out for is unloading a segment that
> contains a routine that will be called at interrupt time, since calling
> LoadSeg at interrupt time would be bad.

All perfectly correct. One other thing to watch out for: don't unload a 
segment containing a routine which is still on the stack. That is: if code 
in segment A calls a routine in segment B, segment B better not unload 
segment A. The reason is that the return address on the stack is a real 
pointer into segment A, and isn't one of these "magical" pointers into the 
jump table.

Often recommended is to keep your main event loop in segment 1 (which, 
like the jump table, is locked and can't be moved or unloaded), and each 
time through the loop call UnloadSeg on every other segment.

==========================================================================
Rick Holzgrafe              |    {sun,voder,nsc,mtxinu,dual}!apple!rmh
Software Engineer           | AppleLink HOLZGRAFE1          rmh@apple.com
Apple Computer, Inc.        |  "All opinions expressed are mine, and do
20525 Mariani Ave. MS: 77-A |    not necessarily represent those of my
Cupertino, CA 95014         |        employer, Apple Computer Inc."