[comp.os.msdos.programmer] Available dynamic memory in MSC 6.0

erikt@ume.cs.umu.se (Erik T{rnvik) (03/25/91)

I'm using Microsoft C 6.0 in a major project. During execution I need to know
how much (dynamic) memory is available for allocation. There are some functions
(_maxavail() and _memavail()) that only seems to work in small models,
but since we use large model, I cannot use those functions.

Right now I'm using the obvious but stupid method, I allocate and allocate
until I hit the roof, and then I free the memory again. Not nice,
but it works.



-- 
Erik Tarnvik              University of Umea
erikt@cs.umu.se           Dept. of Computing Science    
TEL:+46-90166583          S-90187 Umea, SWEDEN         "audentes fortuna juvat"

rkl@cbnewsh.att.com (kevin.laux) (03/25/91)

In article <1991Mar25.095017.9802@cs.umu.se>, erikt@ume.cs.umu.se (Erik T{rnvik) writes:
> I'm using Microsoft C 6.0 in a major project. During execution I need to know
> how much (dynamic) memory is available for allocation. There are some functions
> (_maxavail() and _memavail()) that only seems to work in small models,
> but since we use large model, I cannot use those functions.
> 
> Right now I'm using the obvious but stupid method, I allocate and allocate
> until I hit the roof, and then I free the memory again. Not nice,
> but it works.

	Call Int 21h Function 48h (allocate memory) with BX set to FFFFh.
This call will fail because you're asking for a megabyte of memory.  *But*,
it will return the size of the largest block available in BX.  The value
returned in BX is in paragraphs (16 bytes).

-- 
________________________________________________________________________________
	R. Kevin Laux				Email: rkl1@hound.att.com
	AT&T Bell Labs				Voice: (908) 949-1160
	Holmdel, NJ 07733			Fax:   (908) 949-0959

joe@proto.com (Joe Huffman) (03/27/91)

rkl@cbnewsh.att.com (kevin.laux) writes:

>In article <1991Mar25.095017.9802@cs.umu.se>, erikt@ume.cs.umu.se (Erik T{rnvik) writes:
>> I'm using Microsoft C 6.0 in a major project. During execution I need to know
>> how much (dynamic) memory is available for allocation. There are some functions

>	Call Int 21h Function 48h (allocate memory) with BX set to FFFFh.
>This call will fail because you're asking for a megabyte of memory.  *But*,
>it will return the size of the largest block available in BX.  The value
>returned in BX is in paragraphs (16 bytes).

Sorry... nice try though.  This only give you memory available from MSDOS
not from the heap.  Try this little example (requires your int 21 function
to be built):

#include <stdio.h>
#include <stdlib.h>

int main()
{
  char *p;

  printf("DOS says %ld bytes available\n", 
    (long)int_21_func_48_reg_BX() * 16);

  p = malloc(60000);	/* Assuming >= 60000 is available. */
  free(p);

  printf("Now DOS says %ld bytes available\n", 
    (long)int_21_func_48_reg_BX() * 16);

  return 0;
}

What happens is that malloc() requests memory from DOS and free does
not return it to DOS.  It is easy to create an example such that int 21h
func 48 will return 0 bytes available and actually have 100's of K 
available from malloc().

I don't know of any other method than the 'obvious and stupid' test by 
exhaustion.  Suggestions welcome.

-- 
joe@proto.com

rkl@cbnewsh.att.com (kevin.laux) (03/28/91)

In article <1991Mar26.214536.18451@proto.com>, joe@proto.com (Joe Huffman) writes:
> rkl@cbnewsh.att.com (kevin.laux) writes:
> 
> >In article <1991Mar25.095017.9802@cs.umu.se>, erikt@ume.cs.umu.se (Erik T{rnvik) writes:
	<how much dynamic memory; MSC 6.0 Large model>

	<call Int 21h Function 48h (allocate memory)>

> Sorry... nice try though.  This only give you memory available from MSDOS
> not from the heap.  Try this little example (requires your int 21 function
> to be built):

	<example using Int 21h Function 48h, malloc and free>

> What happens is that malloc() requests memory from DOS and free does
> not return it to DOS.  It is easy to create an example such that int 21h
> func 48 will return 0 bytes available and actually have 100's of K 
> available from malloc().
> 
> I don't know of any other method than the 'obvious and stupid' test by 
> exhaustion.  Suggestions welcome.

	I gave the DOS Function 48h as a convenient way to approximate how
much memory is available.  You're right in that it doesn't include the far
heap (in large memory model, malloc () maps to _fmalloc () and free () maps
to _ffree ()).  It's also well known that free () doesn't return memory
back to the operating system because the strategy of malloc () is to get a
large chunk of memory and then dole out smaller portions to the program
(a throwback to Unix where memory allocation was slow but isn't so under DOS).

	However, the example program, while it does point out that the far
heap is initially allocated and not part of the remaining memory that DOS
has, it is misleading for the purpose of determining just how much memory
can be had before any calls to malloc ().  Unless the program is specifically
using near heap or huge allocations, then requests for memory will be from
the far heap, which can grow.  Implicit in this is that the size of the
request must be 64k or less.

	To find out more exactly how much memory is available including both
the far heap and what DOS has, one can use the _fheapwalk () function to
find and tally up the unused chunks of memory in the far heap and add that
to what DOS returns from Function 48h.  This will give a much closer
approximation.  Once the DOS amount is determined it should be possible to
use halloc () to get slightly less than that (on the order of 32 bytes because
of DOS's overhead for managing the MCB's (memory control blocks)) and then
use _heapadd () to add that memory to the far heap in increments of 64k.
Halloc () returns a _huge pointer so 32-bit arithmetic will be used and
since it is a 32-bit pointer, it can be passed to _heapadd () which takes
a far pointer.  _heapadd () determines which heap to add the memory to by
examining the segment and comparing it to the default data segment; if they
match memory is added to the near heap; if they don't it's the far heap.

	Finally, since MSC 6.0 is being used, then the qh (quickhelp) program
is available.  There is a lot of example code for managing and examining the
heaps.

-- 
________________________________________________________________________________
	R. Kevin Laux				Email: rkl1@hound.att.com
	AT&T Bell Labs				Voice: (908) 949-1160
	Holmdel, NJ 07733			Fax:   (908) 949-0959