[comp.sys.transputer] Dynamically determining memory size

norman@cs.purdue.EDU (Victor Todd Norman) (01/18/90)

Question:  Is there a way for a program to dynamically figure out how
large the memory space is?  I have tried to figure out this value by
having my program write a value to memory and then read it back,
checking if the value is the same.  I start doing this somewhere
that I know exists and try to walk off the end of memory.  I was
hoping that as soon as I fell off the end, the value would be changed.
But, this doesn't work since, as I've found out, memory seems to wrap
around.

Example:
	I am using a T414 (2K on-chip) with 2M external memory.
Thus, the highest address is #80200800.  But, when I write a value to
somewhere off in never-never land, like #802037be, I can read the
value back from that location.  Or, I can find the value in #800037be
(which is where it actually exists all along).

So, my idea of checking legal addresses by writing to them doesn't
seem to work too well.  

Any suggestions?

Victor Norman

rohran@ADAM.BYU.EDU (Richard Ohran) (01/18/90)

Here is a procedure written in Modula-2 which finds all the memory
between the top of the process and the top of memory.
It returns the starting address in the variable "adr" and the
number of available bytes in "size". It checks for both
memory wraparound and non-existent memory address regions.
 
 
PROCEDURE Allocate(VAR adr: POINTER TO BITSET; VAR size: CARDINAL);
 
  VAR x: POINTER TO ProcessState; 
      z,zchanged:BITSET;
      b:POINTER TO BITSET;
BEGIN (*size is in bytes*)
  InitProcessPtr(x);
  adr:=x^.ProcessTop;    (* adr now has the first memory address above
                           the running program*)
  size:=0;
  LOOP
    INC(adr,200H);
    b:=CARDINAL(adr) MOD 10000H + 80000000H; (*creating wraparound address*)
    IF adr^=b^ THEN (*potential memory wraparound*)
      z:=adr^;
      zchanged:=z/{0..31}; (*exclusive or*)
      adr^:=zchanged;
      IF adr^=b^ THEN (*wraparound*)
        adr^:=z;
        EXIT
      END
    END;
    (*now check for non-existent memory*)
    z:=adr^;
    z:=z/{0..31}; (* exclusive or*)
    adr^:=z;
    IF adr^<>z THEN EXIT END;
    adr^:= z/{0..31};(*restore data for valid word*)
    INC(size,200H);
  END;
  adr:=x^.ProcessTop;
END Allocate;
 
Hope this helps. If you have any questions about how it
works, call me at 801-226-8978.
 
Richard Ohran

EDMONDS@prlvax1.prl.philips.co.uk (Mark from Philips) (01/18/90)

You can determine memory size dynamically by using the variable 'freespace'.
freespace gives you the total amount of memory left over after your program
(and other programs, e.g. compiler on a host) has been loaded.  Since occam has
no dynamic features, freespace is a constant.  You can even use it, e.g. as an
array: 

VAL freesize IS freespace :
[]INT array IS [freespace FROM 0 FOR freesize] :


However, you do need to know what other programs are currently loaded into
memory and the size of their program and data spaces - but that shouldn't be
too tricky to work out.

In fact, you could even write a process (a memory manager) that allocates
freespace to itself, and accepts requests from other processes for bits of it.
That way, you can (sort of) have some sort of dynamic memory arrangement
(procedural abstraction?). 


Mark Edmonds
Philips Research Labs

edmonds@uk.co.philips.prl