Marten Jan de Ruiter wrote:
I got some trouble compiling a finite element program called charles.
I used
GNU Pascal version 20020910, based on gcc-2.95.2 19991024 (release).
to compile the program with profiling using the switch -pg. Because the program took an unusual amount of time running, I made a profile. Profiling the run yields that Preparedisposepointer uses exceedingly long times. This is the result for a fairly small problem, used to get output for this mail. I have seen 95% time use for Preparedisposepointer, but lost that profile testing other versions of gpc, and I am not patient enough to regenerate it, now that this output also shows the problem:
I don't know what system you are using, but many C systems have great problems with free() when there are many items to free. I would expect that gpc's new/dispose is using the C runtime malloc/free implementation, but I am prepared for Frank to refute this.
For DJGPP I wrote a replacement, called nmalloc, and available at:
http://cbfalconer.home.att.net/download/nmalloc.zip
which avoids this problem, because free is now an O(1) process in place of O(n). The original O(n) expands to O(n**2) when many items are to be freed.
nmalloc can create a malloc.o object file, which can be linked ahead of the CRT0 library module, and eliminates the problem. This is only tested under DJGPP, and compiled with GCC. The only system dependance is the use of sbrk() to acquire memory to manage. The module (compiled with NDEBUG set) generates the malloc, free, and realloc functions.
If you are willing to descend to C you can use the included evilalgo.c program to see some of the effects. The problem also shows up dramatically in:
http://cbfalconer.home.att.net/download/hashlib.zip
where some of the tests isolate the effect. In particular try:
hashtest 4 100000 (which does all the frees)
vs
hashtest 4 100001 (which suppresses the frees)
and time the runs. Use larger values if needed. The 'oddness' of the second parameter does the free suppression. Hashlib is completely portable, while nmalloc is not. However most Unices etc. supply the raw memory via sbrk, so compilation of nmalloc there (with gcc) should usually function.
Aside to Frank: If I am correct, you are perfectly free to incorporate nmalloc in the gpc system. It also detects a subset of possible trashed arenas, and raises SIGABRT in those cases.