[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [MiNT] Default Stack Size

Miro Kropacek wrote:
About Vincent's idea: something like this is already present. You say in mint.cnf "hey, give every process max. of XX KB for its TPA (i.e. for stack: TPA-text/data/bss segments)". And then, you can use either direct value for stack size (how it's now in mintlib, i.e. 64 KB) or you can use some of that magic values (0, -1, 1, 2 IIRC) which use some relative sizes (all of the remaining TPA, half, ...).

First, some references :

From freemint/doc/examples/mint.cnf

# PROC_MAXMEM= gives the maximum amount of memory that any process
# may use (in kilobytes). The default is to make this unlimited, but
# if you have a lot of memory and/or programs that grab more memory
# than they should, try setting this.
# E.g. to limit processes to 4096K of memory, remove the '#' at the
# beginning of the next line.
# WARNING: the process will not be allowed to allocate memory beyond
# the limit, and it won't "see" more memory as available from the
# system.
# Please understand that programs like "free" (or any other that
# interrogates the system how much memory is available) is a process
# as well, thus it will undergo this limit too!
# Decent shells (desktops) allow you to limit the maximum amount of
# memory independently for each program.


# Set maximum additional TPA size for new processes
# (in kilobytes). The default is 1024. Better keep it low (1024 is
# what we call low) if your machine has 4 MB RAM or less.


From mintlib/mintlib/crtinit.c

 * 01/03/89 ++jrb
 *	The (new) meaning of _stksize: (thanks to allan pratt for the feedback)
 *	_stksize			meaning
 *	  -1L	    keep all of memory (except MINFREE at top) and do
 *		    mallocs from own heap, with heap grown upwards towards
 *		    stack, and the stack growing down towards heap,
 *		    with a minimum slush between them so that they
 *		    dont meet (only checked while malloc'ing). With
 *		    this model, further spawning is not possible, but it is
 *		    well suited for programs such as gcc-cc1 etc.
 *		    Thanks to Piet van Oostrum & Atze Dijkstra for this idea
 *	0L	    keep minimum amount of memory. this is also the
 *		    case when _stksize is undefined by the user.
 *	1L	    keep 1/4 of memory, free 3/4 ( as in Alcyon GEMSTART)
 *	2L	    keep 2/4 (1/2), free rest
 *	3L	    keep 3/4, free 1/4
 *	other	    keep that many bytes
 *	-other	    keep |other| bytes, use the heap for mallocs

1) I want the processes to be able to get as much memory as they want (and I hope they will be sensible and not keep memory if they don't need it). So I leave PROC_MAXMEM commented in mint.cnf

2) By default, TPA_INITIALMEM is implicitly set to 1024 (Ko). That means that the stack will never be able to be bigger that this value. In my MINT.CNF, I set TPA_INITIALMEM=32768. My ARAnyM setup has 64 Mb of FastRAM, so this value is half the memory.

Now the experiments. I use the little program called prstack I posted here long ago. I compiled prstack.tos once, then I modify the stack adjustment with the "stack -S" command.

1) If I set the stack to something like 40M, when I try to run the program I get the Fatal error message added by MiKRO:
Fatal error: insufficient memory
Hint: either decrease stack size using 'stack' command (not recomended)
      or increase TPA_INITIALMEM value in mint.cnf.
This is absolutely normal, because prstack.tos requires a 40 Mb stack, but TPA_INITIALMEM is only 32 Mo. The whole process with its stack cannot fit into the maximum allowed TPA, so it fails itself with a fatal error.

2) If I set the stack value to a reasonable positive value, it works as directed. The program starts with the TPA size specified by TPA_INITIALMEM, but it quickly Mshrink so the new TPA is nearly sizeof(basepage+text+data+bss+requested stack size).

3) The special values of 1, 2 and 3 works as advertised. Note that the ratio is applied to TPA_INITIALMEM.

4) The special value of -1 works well too, in that case the size of the stack is roughly the same as TPA_INITIALMEM. So, as the comment says, it is a good value for stack intensive programs like cc1. In that case, malloc use what is called the "internal heap". It is the space at the bottom of the stack, just after the bss segment. That space would have been used if the stack was going full.

5) The special value 0 is the default stack size (the actual value is hardcoded inside each executable, and equal to 64 Ko). As expected, I get a 64Ko stack. I have checked that "stack -S 0" and "stack -S 64K" give exactly the same result at run time.

6) With negative values, the specified value is used as well as the stack size, and the internal heap is used.

So everything seems to work as advertised ! That's a very good thing. I still have an interrogation: in usual cases, the internal heap is not used, so I guess the memory allocated by malloc() come form the GEMDOS Malloc() ?

Now back to the original question.
Mark complains about "make check". This target builds a lot of small test programs and runs them. It chacks that their output is what is expected. But these small programs have a 64K stack, for some of them it is not enough.

So here are some solutions:

1) Patch the makefile in order to call the "stack" program just after the link in order to set a bigger stack.

2) Patch the linker and add a --stack option (the i386 version of ld has this). So it would be possible to use "make check LFLAGS='--stack 1M'" instead of "make check".

3) Patch the MiNTLib to allow the user to override the hardcoded stack size with the value of an an environment variable.

4) Patch the kernel so it ignores the hardcoded stack size and use a configured default value (my original idea).

Plenty of solutions !

Vincent Rivière