This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch] libiberty/physmem support for w32


Hello

This adds physmem support for _WIN32. Note that cygwin doesn't define
_WIN32 by default.  However, cygwin doesn't need this because it has
 working sysconf.

The code may seem overly complicated.  Here is the reason: All win32
system have GlobalMemoryStatus which provides the requested values.
However, GlobalMemoryStatus is broken for physmen > 4GB, returning
physmem modulo 4GB.  GlobalMemoryStatusEx overcomes this, but is onlay
available on Win2k and WinXP, AFAICT.  Hence we try a runtime link to
GlobalMemoryStatusEx in the shared kernel library rather than a load time link.

Tested on mingw32, GCC trunk, with gcc compiler tested on W98
(32MB ram), NT4(64MB), XP (512MB), and the heuristics reported are
as expected.  

What configury magic do I need to attack, or is the _WIN32 condition
sufficient?
  
libiberty/ChangeLog

2003-02-24  Danny Smith  <dannysmith at users dot source dot forge dot net>

	* physmem.c (physmem_total): Add _WIN32 support.
	(physmem_available): Likewise.



Index: physmem.c
===================================================================
RCS file: /cvs/gcc/gcc/libiberty/physmem.c,v
retrieving revision 1.7
diff -c -3 -p -r1.7 physmem.c
*** physmem.c	22 Feb 2003 15:39:16 -0000	1.7
--- physmem.c	23 Feb 2003 23:17:15 -0000
***************
*** 56,61 ****
--- 56,80 ----
  # include <sys/systemcfg.h>
  #endif
  
+ #ifdef _WIN32
+ #define WIN32_LEAN_AND_MEAN
+ #include <windows.h>
+ /*  MEMORYSTATUSEX is missing from older windows headers, so define
+     a local replacement.  */ 
+ typedef struct  {
+ 	DWORD dwLength;
+ 	DWORD dwMemoryLoad;
+ 	DWORDLONG ullTotalPhys;
+ 	DWORDLONG ullAvailPhys;
+ 	DWORDLONG ullTotalPageFile;
+ 	DWORDLONG ullAvailPageFile;
+ 	DWORDLONG ullTotalVirtual;
+ 	DWORDLONG ullAvailVirtual;
+ 	DWORDLONG ullAvailExtendedVirtual;
+ } lMEMORYSTATUSEX;
+ typedef WINBOOL (WINAPI *PFN_MS_EX) (lMEMORYSTATUSEX*);
+ #endif
+ 
  #include "libiberty.h"
  
  /* Return the total amount of physical memory.  */
*************** physmem_total ()
*** 129,134 ****
--- 148,182 ----
    return _system_configuration.physmem;
  #endif
  
+ #if defined _WIN32
+   { /* this works on windows */
+     PFN_MS_EX pfnex; 
+     HMODULE h = GetModuleHandle("kernel32.dll");
+ 
+     if (!h) 
+       return 0.0;
+ 
+     /*  Use GlobalMemoryStatusEx if available.  */ 
+     if ((pfnex = (PFN_MS_EX) GetProcAddress (h, "GlobalMemoryStatusEx")))
+       {
+ 	lMEMORYSTATUSEX lms_ex;
+ 	lms_ex.dwLength = sizeof lms_ex;
+ 	if (!pfnex (&lms_ex))
+ 	  return 0.0;
+ 	return (double)lms_ex.ullTotalPhys;
+       }
+ 
+     /*  Fall back to GlobalMemoryStatus which is always available.
+         but returns wrong results for physical memory > 4GB.  */ 
+     else
+       {
+         MEMORYSTATUS ms;
+         GlobalMemoryStatus (&ms);
+         return (double)ms.dwTotalPhys;
+       }
+    }
+ #endif
+ 
    /* Return 0 if we can't determine the value.  */
    return 0;
  }
*************** physmem_available ()
*** 198,203 ****
--- 246,280 ----
      if (sysctl(mib, ARRAY_SIZE(mib), &usermem, &len, NULL, 0) == 0
  	&& len == sizeof (usermem))
        return (double)usermem;
+   }
+ #endif
+ 
+ #if defined _WIN32
+   { /* this works on windows */
+     PFN_MS_EX pfnex; 
+     HMODULE h = GetModuleHandle ("kernel32.dll");
+ 
+     if (!h)
+       return 0.0;
+ 
+     /*  Use GlobalMemoryStatusEx if available.  */ 
+     if ((pfnex = (PFN_MS_EX) GetProcAddress (h, "GlobalMemoryStatusEx")))
+       {
+ 	lMEMORYSTATUSEX lms_ex;
+ 	lms_ex.dwLength = sizeof lms_ex;
+ 	if (!pfnex (&lms_ex))
+ 	  return 0.0;
+ 	return (double) lms_ex.ullAvailPhys;
+       }
+ 
+     /*  Fall back to GlobalMemoryStatus which is always available.
+         but returns wrong results for physical memory > 4GB  */ 
+     else
+       {
+ 	MEMORYSTATUS ms;
+ 	GlobalMemoryStatus (&ms);
+ 	return (double)ms.dwAvailPhys;
+       }
    }
  #endif
  

http://mobile.yahoo.com.au - Yahoo! Mobile
- Exchange IMs with Messenger friends on your Telstra or Vodafone mobile phone.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]