Author: Jim Merritt (rev. Steven Glass & Rich Williams)
Year: 1987
... describes a technique which permits an application to dispose of any memory it has used with a single Memory Manager call without clobbering other system components or itself.
Apple II
Technical Notes
_____________________________________________________________________________
Developer Technical Support
Apple IIGS
#17: Application Memory Management and the MMStartUp User ID
Revised by: Steven Glass & Rich Williams November 1988
Written by: Jim Merritt June 1987
This Technical Note describes a technique which permits an application to
dispose of any memory it has used with a single Memory Manager call without
clobbering other system components or itself.
_____________________________________________________________________________
Ground Rules for Application Memory Usage
Apple IIGS programs must be responsible for allocating and disposing of any
memory they use, over and above that which the operating system itself gives
them. In general, no IIGS program should use any memory except that which the
Memory Manager has explicitly granted to it. A program may request additional
memory for its own use at any time with one or more calls to the NewHandle
routine. At program termination, the application is responsible for
explicitly disposing of any memory that it explicitly acquired, and if it
fails to do so, it could leave the IIGS memory management system in a
corrupted state.
You may dispose of memory on a handle-by-handle basis, or you may dispose of
it en masse by calling DisposeAll, but you should never use DisposeAll with
the user ID that the MMStartUp routine provides. This user ID is the "master
user ID" for the application, and it tags the memory space which the operating
system reserves for the program's code and static data at load time. Calling
DisposeAll with this user ID results in immediate deallocation of the memory
in which the calling program resides; therefore, an application which
allocates dynamic data space using only the user ID that MMStartUp gives it
should not use DisposeAll to deallocate that space, but rather use
DisposeHandle to deallocate it handle by handle.
Cleaning Up With DisposeAll
It is possible, however, for a program to use a different, unique user ID when
allocating its own RAM, then pass that user ID to DisposeAll when it
terminates to deallocate all of its private memory at once without endangering
itself or other parts of the IIGS system. With this technique, the question
is how best to acquire a new user ID? One method to acquire a new user ID is
to request a completely new one of the appropriate type from the User ID
Manager in the Miscellaneous Tools. In this case, when the application
terminates, it must not only deallocate the memory it used, but also the
additional user ID which it requested from the User ID Manager.
Actually, it is not necessary for a program to acquire a completely new user
ID to use DisposeAll without clobbering itself. Instead, the application may
modify the auxID field of the master user ID which MMStartUp assigns to create
a unique user ID for allocating its own memory. The 16-bit user ID contains
the auxID field in bits $8 - $B. The value of this field, which may range
from $0 to $F, is always zero in the application's master user ID, but you can
fill it with any non-zero value to create up to 15 new and distinct user IDs,
each of which you can pass to NewHandle to allocate memory.and to DisposeAll
to deallocate memory without endangering the memory tagged by the master user
ID. The following assembly code fragment illustrates this technique:
; assumes full native mode
pushword #0 ; room for user ID
_MMStartUp
pla ; master user ID
sta MasterID
ora #$0100 ; auxID:= 1
; (COULD HAVE BEEN ANYTHING FROM $1 to $F)
sta MyID ; use this to allocate private memory
...
etc.
...
; ready to exit program
pushword MyID
_DisposeAll ; dumps only my own RAM
; now do any remaining processing related to termination
You do not need to explicitly deallocate any user ID that you derive by
changing the auxID field of a valid master user ID. When the system (usually
the one to deallocate the master) deallocates the master user ID, it also
deallocates its derivatives.
One Word of Caution
Several of the Memory Manager's "All" calls (e.g., DisposeAll) treat a zeroed
auxID field as a wildcard which matches any value that the field may contain,
thus if you call DisposeAll with the application's master user ID (where the
auxID field is zero), the Memory Manager will not only deallocate all memory
belonging to the master user ID, but also all handles and memory segments that
are associated with user IDs which are derived from that master. The
operating system's QUIT mechanism typically executes such a call when cleaning
up after a normal (i.e., non-restartable) application to keep the memory
management system from clogging. This action is purely a defensive measure,
and well-behaved applications - particularly restartable ones - should dispose
of their own memory and never rely upon the operating system to clean up after
them.
Further Reference
o Apple IIGS Toolbox Reference, Volume 1