Article View: comp.sys.atari.st
Article #32081mshrink & lattice C
From: Peter Knoppers knop
Date: Thu, 21 Apr 1988 23:18
Date: Thu, 21 Apr 1988 23:18
127 lines
5630 bytes
5630 bytes
Bill writes:(Bill Rosenkranz)
>Mshrink is a gemdos call that returns memory to the operating system. a far
>as i know, when you double-click (or otherwise start a program) it take
>ALL available memory for itself. since rsrc_load needs to allocat space
>(using a Malloc call, probably the gemdos version NOT the gemlib malloc,
>there is none available and it would probably bomb. this is why the alcon
>startup file GEMSTART.S does the Mshrink almost as soon as the program tarts.
>the gemstart module is the first thing that executes when your program tarts
>and eventually calls your "main" function. i don't know how lattice
>works but it probably does something similar. check your docs to see if
>they mention something about linking and a certain object that has to b
>first. you should probably solicit a response from lattice hackers.
The alternative startup.asm include in this article was written by my
friend Harm Salomons, who is responsible for its contents. (Reply to me)
The problem:
On startup of a GEM program all available memory is allocated (and zeroed).
This means that sub-processes or resource files cannot allocate any more
memory. Therefore all programs must de-allocate all memory that they do
not need. This is done in the startup routine of the runtime library of
the C-compiler with a call to the mshrink function. Mshrink must be given
two addresses:
1: the address that was returned by rbrk when the program was loaded
(known only inside startup.asm)
2: the size of the memory that must be retained.
Lattice runtime memory layout is as follows:
High | stack | grows down
| ----- |
| |
| ----- |
| heap | grows up
|-------|
|program|
Low |-------|
(Naturally the size of the space between heap and stack must remain
positive at all times)
The position of the stack is determined by startup.asm. With this memory
organization you cannot alter the amount of memory used from within your
C code, because you cannot move the stack to another location.
The solution is to reverse the order of stack and heap.
This assumes lattice C version 3.04.01
I will give only the changes to STARTUP.ASM that is supplied with the C
compiler. (Something similar should be possible with gemstart.asm.)
To the list of XDEF's you must add the line:
--------
XDEF _dealloc
--------
Replace
--------
mem3:
move.l d2,d0 ; d0 = base of free memory
sub.l a1,d0 ; d0 = size of program
add.l d3,d0 ; add heap requirements
add.l _STACK,d0 ; add stack requirements
move.l d0,-(a7) ; length of retained memory
move.l a1,-(a7) ; base of retained memory
clr.w -(a7) ; filler
move.w #gem_shrk,-(a7) ; function code
trap #1 ; Memory now shrunk
addq.l #4,(a7)
tst.l d0 ; check it worked
bne.s abort
;
mem4: move.l d2,a7 ; set up stack
add.l d3,a7 ; add heap size
move.l a7,_base ; set base of stack
add.l _STACK,a7 ; add stack size for new sp
move.l a7,_top ; set top of stack
move.l d2,_mbase ; set base of heap
move.l d2,_mnext ; set heap next pointer
move.l d3,_msize ; set size of heap
--------
by
--------
mem3:
mem4: move.l d2,a7 ; set up stack
move.l a7,_base ; set base of stack
add.l _STACK,a7 ; add stack size for new sp
move.l a7,_top ; set top of stack
move.l a7,_mbase ; set base of heap
move.l a7,_mnext ; set heap next pointer
move.l d3,_msize ; set size of heap
jsr rbrk ; free all level 1 memory
--------
To the end of of the TEXT part of startup.asm you must add the following
lines:
--------
_dealloc:
move.l 4(a7),d0 ; address to dealloc from
sub.l _pbase,d0 ; start address of memory
move.l d0,_msize ; new length
;
move.l d0,-(a7) ; length of retained memory
move.l _pbase,-(a7) ; base of retained memory
clr.w -(a7) ; filler
move.w #gem_shrk,-(a7) ; function code
trap #1 ; Memory now shrunk
adda #12,a7 ; restore stackpointer
rts ; return with result in d0
;
--------
The program must (after startup) decide how much memory it needs for heap
space. The remaining RAM must be released by a call to _dealloc. Example:
Mem_buf = malloc(Max_mem);
if(_dealloc(Mem_buf + Max_mem) != 0)
{
fprintf(stderr, "Not enough memory");
exit(-1);
}
Happy Hacking!
--
Peter Knoppers, Delft Univ. of Technology
...!mcvax!dutrun!dutesta!knop
or
knop@dutesta.UUCP
Technical Details
Message-ID:
<1138@dutesta.UUCP>Path:
arc1-ca.pugleaf.net!utzoo!mnetor!uunet!mcvax!dutrun!dutesta!knopShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!mnetor!uunet!mcvax!dutrun!dutesta!knop From: knop@dutesta.UUCP (Peter Knoppers (knop@dutesta.UUCP)) Newsgroups: comp.sys.atari.st Subject: mshrink & lattice C Message-ID: <1138@dutesta.UUCP> Date: 21 Apr 88 23:18:14 GMT Reply-To: knop@dutesta.UUCP (Peter Knoppers) Organization: Delft University of Technology, Faculty of Electrical Engineering. Lines: 127