Date: Tue, 28 Sep 1999 09:27:27 +0200 (IST) From: Eli Zaretskii X-Sender: eliz AT is To: Prashant TR cc: djgpp AT delorie DOT com Subject: Re: Memory hoarding In-Reply-To: <19990927042859.1834.rocketmail@web1401.mail.yahoo.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Reply-To: djgpp AT delorie DOT com X-Mailing-List: djgpp AT delorie DOT com X-Unsubscribes-To: listserv AT delorie DOT com Precedence: bulk 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 #include #include #include #include #include #include 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; }