Adding PR_GetPhysicalMemorySize to WINCE Branch. NSPRPUB_PRE_4_2_WINCE_BRANCH
authordougt%meer.net
Wed, 22 Jun 2005 05:16:18 +0000
branchNSPRPUB_PRE_4_2_WINCE_BRANCH
changeset 3409 c38bf117a809cc4947e3f9fd91bb39aac4777d23
parent 3352 2ef06dcd11dac1d84933ebb1e4819df8b54e1a53
child 3424 770f91cf95814ea6ed2e6cf855da39d872890ccc
push idunknown
push userunknown
push dateunknown
Adding PR_GetPhysicalMemorySize to WINCE Branch.
pr/include/prsystem.h
pr/src/misc/prsystem.c
pr/tests/system.c
--- a/pr/include/prsystem.h
+++ b/pr/include/prsystem.h
@@ -111,11 +111,27 @@ NSPR_API(PRInt32) PR_GetPageShift(void);
 **   none
 **
 ** Returns:
 **   The number of available processors or -1 on error
 ** 
 */
 NSPR_API(PRInt32) PR_GetNumberOfProcessors( void );
 
+/*
+** PR_GetPhysicalMemorySize() -- returns the amount of system RAM
+**
+** Description:
+** PR_GetPhysicalMemorySize() determines the amount of physical RAM
+** in the system and returns the size in bytes.
+**
+** Parameters:
+**   none
+**
+** Returns:
+**   The amount of system RAM, or 0 on failure.
+**
+*/
+NSPR_API(PRUint64) PR_GetPhysicalMemorySize(void);
+
 PR_END_EXTERN_C
 
 #endif /* prsystem_h___ */
--- a/pr/src/misc/prsystem.c
+++ b/pr/src/misc/prsystem.c
@@ -1,9 +1,9 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* ***** BEGIN LICENSE BLOCK *****
  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  *
  * The contents of this file are subject to the Mozilla Public License Version
  * 1.1 (the "License"); you may not use this file except in compliance with
  * the License. You may obtain a copy of the License at
  * http://www.mozilla.org/MPL/
  *
@@ -33,47 +33,78 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "primpl.h"
 #include "prsystem.h"
 #include "prprf.h"
+#include "prlong.h"
 
 #if defined(BEOS)
 #include <kernel/OS.h>
 #endif
 
 #if defined(OS2)
 #define INCL_DOS
+#define INCL_DOSMISC
 #include <os2.h>
 /* define the required constant if it is not already defined in the headers */
 #ifndef QSV_NUMPROCESSORS
 #define QSV_NUMPROCESSORS 26
 #endif
 #endif
 
 /* BSD-derived systems use sysctl() to get the number of processors */
 #if defined(BSDI) || defined(FREEBSD) || defined(NETBSD) \
     || defined(OPENBSD) || defined(DARWIN)
 #define _PR_HAVE_SYSCTL
 #include <sys/param.h>
 #include <sys/sysctl.h>
 #endif
 
+#if defined(DARWIN)
+#include <mach/mach_init.h>
+#include <mach/mach_host.h>
+#endif
+
 #if defined(HPUX)
 #include <sys/mpctl.h>
+#include <sys/pstat.h>
 #endif
 
 #if defined(XP_UNIX)
 #include <unistd.h>
 #include <sys/utsname.h>
 #endif
 
+#if defined(AIX)
+#include <cf.h>
+#include <sys/cfgodm.h>
+#endif
+
+#if defined(WIN32)
+/* This struct is not present in VC6 headers, so declare it here */
+typedef struct {
+    DWORD dwLength;
+    DWORD dwMemoryLoad;
+    DWORDLONG ullTotalPhys;
+    DWORDLONG ullAvailPhys;
+    DWORDLONG ullToalPageFile;
+    DWORDLONG ullAvailPageFile;
+    DWORDLONG ullTotalVirtual;
+    DWORDLONG ullAvailVirtual;
+    DWORDLONG ullAvailExtendedVirtual;
+} PR_MEMORYSTATUSEX;
+
+/* Typedef for dynamic lookup of GlobalMemoryStatusEx(). */
+typedef BOOL (WINAPI *GlobalMemoryStatusExFn)(PR_MEMORYSTATUSEX *);
+#endif
+
 PR_IMPLEMENT(char) PR_GetDirectorySeparator(void)
 {
     return PR_DIRECTORY_SEPARATOR;
 }  /* PR_GetDirectorySeparator */
 
 /*
 ** OBSOLETE -- the function name is misspelled.
 */
@@ -226,8 +257,106 @@ PR_IMPLEMENT(PRInt32) PR_GetNumberOfProc
     numCpus = sysconf( _SC_NPROC_ONLN );
 #elif defined(XP_UNIX)
     numCpus = sysconf( _SC_NPROCESSORS_ONLN );
 #else
 #error "An implementation is required"
 #endif
     return(numCpus);
 } /* end PR_GetNumberOfProcessors() */
+
+/*
+** PR_GetPhysicalMemorySize()
+** 
+** Implementation notes:
+**   Every platform does it a bit different.
+**     bytes is the returned value.
+**   for each platform's "if defined" section
+**     declare your local variable
+**     do your thing, assign to bytes.
+** 
+*/
+PR_IMPLEMENT(PRUint64) PR_GetPhysicalMemorySize(void)
+{
+    PRUint64 bytes = LL_ZERO;
+
+#if defined(LINUX) || defined(SOLARIS)
+
+    long pageSize = sysconf(_SC_PAGESIZE);
+    long pageCount = sysconf(_SC_PHYS_PAGES);
+    LL_I2L(bytes, pageSize * pageCount);
+
+#elif defined(HPUX)
+
+    struct pst_static info;
+    int result = pstat_getstatic(&info, sizeof(info), 1, 0);
+    if (result == 1)
+        LL_I2L(bytes, info.physical_memory * info.page_size);
+
+#elif defined(DARWIN)
+
+    struct host_basic_info hInfo;
+    mach_msg_type_number_t count;
+
+    int result = host_info(mach_host_self(),
+                           HOST_BASIC_INFO,
+                           (host_info_t) &hInfo,
+                           &count);
+    if (result == KERN_SUCCESS)
+        LL_I2L(bytes, hInfo.memory_size);
+
+#elif defined(WIN32)
+
+    /* Try to use the newer GlobalMemoryStatusEx API for Windows 2000+. */
+    GlobalMemoryStatusExFn globalMemory = (GlobalMemoryStatusExFn) NULL;
+    HMODULE module = GetModuleHandle("kernel32.dll");
+
+    if (module) {
+        globalMemory = (GlobalMemoryStatusExFn)GetProcAddress(module, "GlobalMemoryStatusEx");
+
+        if (globalMemory) {
+            PR_MEMORYSTATUSEX memStat;
+            memStat.dwLength = sizeof(memStat);
+
+            if (globalMemory(&memStat))
+                LL_UI2L(bytes, memStat.ullTotalPhys);
+        }
+    }
+
+    if (LL_EQ(bytes, LL_ZERO)) {
+        /* Fall back to the older API. */
+        MEMORYSTATUS memStat;
+        memset(&memStat, 0, sizeof(memStat));
+        GlobalMemoryStatus(&memStat);
+        LL_I2L(bytes, memStat.dwTotalPhys);
+    }
+
+#elif defined(OS2)
+
+    ULONG ulPhysMem;
+    DosQuerySysInfo(QSV_TOTPHYSMEM,
+                    QSV_TOTPHYSMEM,
+                    &ulPhysMem,
+                    sizeof(ulPhysMem));
+    LL_I2L(bytes, ulPhysMem);
+
+#elif defined(AIX)
+
+    if (odm_initialize() == 0) {
+        int how_many;
+        struct CuAt *obj = getattr("sys0", "realmem", 0, &how_many);
+        if (obj != NULL) {
+            PRUint64 kbytes;
+            LL_I2L(kbytes, atoi(obj->value));
+            LL_MUL(bytes, kbytes, 1024);
+            free(obj);
+        }
+        odm_terminate();
+    }
+
+#else
+
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+
+#endif
+
+    return bytes;
+} /* end PR_GetPhysicalMemorySize() */
--- a/pr/tests/system.c
+++ b/pr/tests/system.c
@@ -70,13 +70,14 @@ PRIntn main(PRIntn argc, char **argv)
         if (PR_SUCCESS == rv) PR_fprintf(output, "%s: %s\n", tag[cmd], info);
         else PL_FPrintError(output, tag[cmd]);
     }
     PR_DELETE(info);
 
     PR_fprintf(output, "Host page size is %d\n", PR_GetPageSize());
     PR_fprintf(output, "Page shift is %d\n", PR_GetPageShift());
     PR_fprintf(output, "Number of processors is: %d\n", PR_GetNumberOfProcessors());
+    PR_fprintf(output, "Physical memory size is: %llu\n", PR_GetPhysicalMemorySize());
 
     return 0;
 }  /* main */
 
 /* system.c */