max/memavail

Frank Heckenbach frank at g-n-u.de
Tue Sep 24 13:50:18 CEST 2002


Michael Behm wrote:

> i have the following questions: i've been working with
> borland pascal under DOS for quite a long time, and
> now i changed to gpc under Solaris 8 on a SUN Blade
> 1000. i've to admit that i don't know much of UNIX
> itself.
> when i use the functions Max/MemAvail, the program
> seems to halt (it doesn't crash, just waits until i
> destroy via ctrl-c). 

This should not happen. Try the following patch:

--- p/units/system.pas.orig	Tue Sep 24 13:17:29 2002
+++ p/units/system.pas	Tue Sep 24 13:21:26 2002
@@ -642,7 +642,7 @@
 begin
   Size := StartSize;
   p := CGetMem (Size);
-  while p <> nil do
+  while (p <> nil) and (Size <= High (Size) div 2) do
     begin
       Size := 2 * Size;
       CFreeMem (p);
@@ -634,6 +634,7 @@
   StartSize     = $100000;  { 1MB }
   MinSize       = $10;
   PrecisionBits = 5;
+  MaxBlocks     = $10;
 
 function FindLargestMemBlock (var p: Pointer): SizeType;
 var
@@ -685,9 +686,11 @@
   TotalSize, NewSize: SizeType;
   MemList, p: PMemList;
   LargeEnough: Boolean;
+  Blocks: Integer;
 begin
   TotalSize := MaxAvail;
   MemList := nil;
+  Blocks := 0;
   repeat
     NewSize := FindLargestMemBlock (p);
     Inc (TotalSize, NewSize);
@@ -695,9 +698,11 @@
     if LargeEnough then
       begin
         p^ := MemList;
-        MemList := p
+        MemList := p;
+        p := nil;
+        Inc (Blocks)
       end
-  until not LargeEnough;
+  until not LargeEnough or (Blocks >= MaxBlocks);
   if p <> nil then CFreeMem (p);
   while MemList <> nil do
     begin

> i suppose that MaxAvail/MemAvail does only make sense
> under DOS - i don't know if there is anything like a
> heap in UNIX.

Memory management is quite a bit different on Unix (and on any
multitasking system, probably even including Windows). The pool of
free memory is (mostly) global and can be shared by all processes,
according to their needs (though one can set limits per process).

A consequence is that even if you get the correct amount of free
memory at some moment, it might be wrong a microsecond later because
another process (maybe by another user, or a system process)
allocated some memory.

Another story is that the OS does automatic swapping (i.e., moves
memory to the disk temporarily if processes need more than RAM is
available), so the total free memory is really the amount of main
memory plus swap space set up. That's the total amount of memory
processes can use, though usage might be quite slow due to swapping.

There are ways to get the total free memory (both total and main
only) and the process limits from the system, but they are somewhat
system-dependent and it would be of bit of work to get it right.
Because of the general unreliability (see above), I'm not sure if it
would be worth the effort.

So what GPC's System unit does instead is to tentatively allocate
some memory (one block in MaxAvail, possibly several blocks in
MemAvail) as large as possible. In the case of MaxAvail, it keeps
the block allocated, so an immediately following GetMem of the size
returned by MaxAvail will return this block (even if other processes
tried to allocate much memory in the meantime).

> are there any similiar functions (which work) in
> gpc/UNIX ? how can i determine the space which is free
> for a single pointer variable ?

If you know how much memory you need and want to avoid a runtime
error, then as stated in the comment in the System unit you might
want to use CGetMem which works similar to GetMem, but returns nil
instead of causing a runtime error when not enough memory is
available.

> with GetMem,
> can i address the whole memory (which is 1 GByte) ?

Yes, unless the OS or the user puts some limit. But with "only" 1 GB
the former is unlikely. On a 32 machine, the virtual address space
is 4 GB. The system reserves some part of it (I think 1 GB under
Linux, not sure about Solaris), but the rest should be freely
allocatable.

As for user limits, you can enter `limit' (if your shell is
csh/tcsh) or `ulimit -a' to see if any are set (but I also don't
expect a problem there).

Frank

-- 
Frank Heckenbach, frank at g-n-u.de, http://fjf.gnu.de/, 7977168E
GPC To-Do list, latest features, fixed bugs:
http://www.gnu-pascal.de/todo.html
GPC download signing key: 51FF C1F0 1A77 C6C2 4482  4DDC 117A 9773 7F88 1707




More information about the Gpc mailing list