Path: 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 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