CompuServe Thread

#Code Segment Mgmt …

5 messages in this thread
#132383From: Joe Terry |Manhattan|Jul 19, 1993 4:53 PM
Hi y'all, The following code is used to manage code segment traffic in a large THINK C with objects application. We use the TCL and the Prepare() class libraries. I would like anyone's comments on this code. Anything appreciated. Your payment in full is the code itself. Please maintain the copyright notice. The usage is to make a call like this … void main() … InitSegmentMgr(); … ) // end main() and then else where when the mood hits … UnloadSegment( Routine_In_Segment_Name ); Thanks, // joe /* * SegmentMgr.c – routines for managing code segments * * Copyright ~ 1991 Christopher R. Wysocki. All rights reserved. * */ // #include "SegmentMgr.h" #define __DEBUG__ static long gOrigA6; /* * InitSegmentMgr * * Initialize our segment manager. * This routine should be called as the first function in main(). */ void InitSegmentMgr(void); void InitSegmentMgr(void) { asm { move.l a6,gOrigA6 ; save initial value of a6 } } /* * UnloadSegment * * Call this routine instead of the Toolbox routine _UnloadSeg to unload * a segment. This routine walks through the A6 chain to ensure that no * routine in the segment to be unloaded is in the current calling chain. * */ void UnloadSegment(void *routineAddr); void UnloadSegment(void *routineAddr) { asm { movem.l a3-a4,-(a7) ; save registers on stack movea.l routineAddr,a0 ; get pointer to jump table entry cmpi.w #0xA9F0,4(a0) ; is the segment loaded? beq @4 ; go return if not subq.w #4,a7 ; space for result pea 'CODE' ; push resource type move.w -2(a0),-(a7) ; push segment number (resource ID) _GetResource ; get the appropriate CODE resource move.l (a7)+,a0 ; pop the resource handle #ifdef __DEBUG__ cmpa.l #0,a0 ; is the handle nil? bne.s @0 ; branch if not pea @cantLoadCODERsrc ; push pointer to message _DebugStr ; drop into Macsbug bra.s @4 ; and go return @cantLoadCODERsrc: dc.b "\pUnloadSegment: can't load CODE resource!" @0 #endif move.l (a0),d0 ; get master pointer _StripAddress ; strip off high byte if in 24-bit mode movea.l d0,a3 ; save ptr to start of block in a3 _GetHandleSize ; get size of CODE resource handle movea.l a3,a4 ; keep block ptr in a4 adda.l d0,a4 ; add length to get ptr to byte after block movea.l a6,a1 ; a1 walks through the a6 calling chain @1 cmpa.l gOrigA6,a1 ; are we at the end of the calling chain? beq.s @3 ; exit loop if so move.l 4(a1),d0 ; get return address _StripAddress ; strip off high byte if in 24-bit mode cmp.l a3,d0 ; check if this address is in the segment blo.s @2 ; that we want to unload — if it is, cmp.l a4,d0 ; exit the loop without unloading the blo.s @4 ; segment @2 movea.l (a1),a1 ; the return address isn't in the segment, bra.s @1 ; so get previous contents of a6 and loop @3 move.l routineAddr,-(a7) ; push pointer to routine _UnloadSeg ; unload the segment @4 movem.l (a7)+,a3-a4 ; restore registers from stack } }
#132443From: Robert S. Mah[OSB]Jul 19, 1993 11:50 PM
Joe, Well, one comment I'd like to make is the idea of "defered segment unloading". We use this to clean out the heap at a later time when it is safe to do so. We use a combination of your approach (checking to see if it's in the call chain) and queueing segments until the main event loop is reached before it is de-queued. Works great, and keeps the "UnloadSegs" dependencies out of code. That is, each module unloads itself. Cheers, Rob
#132468From: Steve StockmanJul 20, 1993 4:00 AM
Rob: >>> We use a combination of your approach (checking to see if it's in the call chain) and queueing segments until the main event loop is reached before it is de-queued. <<< Do you queue without allocating memory (so that it can be called at GrowZone time)? Steve
#132493From: Robert S. Mah[OSB]Jul 20, 1993 11:55 AM
===> Do you queue without allocating memory (so that it can be called at GrowZone time)? <=== Yeah, we use a statically allocated queue for just that reason. It really doesn't take too much space. We actually cue up segment ID's and not function pointers. You can convert back and forth from function pointers to segment ID's fairly easily. Cheers, Rob
#132469From: Steve StockmanJul 20, 1993 4:00 AM
Joe: Is the A6 chain still valid during GrowZone? I know that the Think C Debugger loses track of the call chain during the GrowZoneProc, but I haven't actually studied it in TMON to determine whether or not it's the Memory Mgr that's using A6 for something other than a standard frame pointer. This is worth knowing, because "else where when the mood hits" most conveniently would be when you *know* you are pressed for memory. Steve