delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1999/09/28/07:44:34

Date: Tue, 28 Sep 1999 09:27:27 +0200 (IST)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
X-Sender: eliz AT is
To: Prashant TR <prashant_news AT yahoo DOT com>
cc: djgpp AT delorie DOT com
Subject: Re: Memory hoarding
In-Reply-To: <19990927042859.1834.rocketmail@web1401.mail.yahoo.com>
Message-ID: <Pine.SUN.3.91.990928092701.17309A-100000@is>
MIME-Version: 1.0
Reply-To: djgpp AT delorie DOT com
X-Mailing-List: djgpp AT delorie DOT com
X-Unsubscribes-To: listserv AT delorie DOT com

On Sun, 26 Sep 1999, Prashant TR wrote:

> You asked me for some code to reproduce the malloc
> problem. It's here below.

I played with your test program (modified a bit to suppress compiler
warnings, see the source below), and I don't see anything abnormal.
In particular, the program never hung for me with CWSDPMI.  On a
machine with 64MB physical memory, it successfully allocates 48MB and
then exits.  The last 16MB allocation takes lots of time due to paging
(I explain below why), so perhaps on a slow machine you could become
impatient.

Perhaps there are a few subtle aspects of memory allocation that you
need to be aware of.

First, `malloc' imposes an 8-byte overhead on each chunk it
allocates.  In addition, `sbrk', which `malloc' calls to request
memory from the DPMI host, rounds the chunk size up to the next
multiple of 64KB.  So when you request 16MB of memory, your program
actually asks the DPMI host for 16MB + 64KB.

But this isn't all: the program uses up additional memory for its
static data (mainly for the library functions, since the program
itself is very small) and the 512KB stack.  The call to `printf' also
allocates 16KB of memory (for the buffer of the stdout stream).

And, of course, the first megabyte is already taken by DOS and other
real-mode software.

For these reasons, a 64MB machine can never allocate all of its
64MBytes, only part of it.

Also, your program used the `total_physical_pages' member returned by
`_go32_dpmi_get_free_memory_information'.  This is the total number of
pages managed by the DPMI host, not the number of free pages.  An
attempt to allocate all the pages managed by the DPMI host and lock
them is bound to fail, since some of the memory is in use, as I
explained above, and therefore there's not enough free physically
available pages.  If you remove the _CRT0_FLAG_LOCK_MEMORY bit, you
could have allocated the amount of memory you asked for (some of it
paged out to disk), but the lock bit prevents CWSDPMI from using
virtual memory, so it fails.

Since you are asking for too many locked pages, the last chunk fails
to be locked.  Your code doesn't check if `_go32_dpmi_lock_data'
succeeded, but once I added such a test, it sure enough printed "Not
Locked".

When I tried to replace `total_physical_pages' with
`available_physical_pages', all the memory I asked for was allocated
and locked.

In sum, this is all expected behavior, at least as it worked on my
machine (under DOS 5.0).  If you see something different, please
describe it.

Btw: don't try this program on Windows 9X: it will wedge the entire
machine cold!


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <crt0.h>
#include <go32.h>
#include <dpmi.h>

int _ctr0_startup_flags = _CRT0_FLAG_LOCK_MEMORY | _CRT0_FLAG_FILL_SBRK_MEMORY;

int main()
{
 _go32_dpmi_meminfo ret;
 unsigned long maxmem, f, g = 0;
 char *x[64];

 _go32_dpmi_get_free_memory_information(&ret);
 maxmem = ret.total_physical_pages;
 printf ("Try to allocate and lock %lu pages? ", maxmem);
 fflush (stdout);
 if (getch () != 'Y')
   return 1;

 for(f = 0; f < maxmem * 4 * 1024; f += 16 * 1024 * 1024L, g++)
 {
  x[g] = (char *)malloc(16 * 1024 * 1024L);
  if (!x[g]) break;
  printf("%luM memory malloc'd.\n", f / 1024L / 1024L);
  if (_go32_dpmi_lock_data(x[g], 16 * 1024 * 1024L) == 0)
    puts ("Locked");
  else if (_go32_dpmi_lock_data(x[g], (maxmem * 4 - f / 1024) * 1024) == 0)
    puts ("Partially Locked");
  else
    puts ("Not Locked");
  memset(x[g], 0, 16 * 1024L * 1024L);
 }

 return 0;
}

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019