summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbryner%brianryner.com <devnull@localhost>2005-05-06 18:46:11 +0000
committerbryner%brianryner.com <devnull@localhost>2005-05-06 18:46:11 +0000
commitda4c475867402e7bf8c810d48a736521dc5f8c24 (patch)
treefdc7e4934e6569d5e0c00252c7dd3e5931cc396a
parentb0dbb161c879365cdb02ee5923ae927baf6eb58e (diff)
downloadnspr-hg-da4c475867402e7bf8c810d48a736521dc5f8c24.tar.gz
Add PR_GetPhysicalMemorySize to determine the amount of system memory installed (bug 292899). r=wtc, a=brendan
-rw-r--r--config/system-headers4
-rw-r--r--pr/include/prsystem.h16
-rw-r--r--pr/src/misc/prsystem.c131
-rw-r--r--pr/src/nspr.def6
-rw-r--r--pr/src/nspr_symvec.opt4
-rw-r--r--pr/tests/system.c1
6 files changed, 159 insertions, 3 deletions
diff --git a/config/system-headers b/config/system-headers
index 7a2869e7..cf0f1149 100644
--- a/config/system-headers
+++ b/config/system-headers
@@ -6,6 +6,7 @@ bsd/syscall.h
bstring.h
builtin.h
c_asm.h
+cf.h
CFBundle.h
CFData.h
CFDictionary.h
@@ -54,6 +55,8 @@ machine/builtins.h
machine/clock.h
machine/endian.h
machine/inline.h
+mach/mach_init.h
+mach/mach_host.h
mach-o/dyld.h
MacTypes.h
Math64.h
@@ -105,6 +108,7 @@ support/TLS.h
synch.h
sys/atomic_op.h
syscall.h
+sys/cfgodm.h
sys/file.h
sys/filio.h
sys/immu.h
diff --git a/pr/include/prsystem.h b/pr/include/prsystem.h
index 0dc420b8..b0dfcf9e 100644
--- a/pr/include/prsystem.h
+++ b/pr/include/prsystem.h
@@ -116,6 +116,22 @@ NSPR_API(PRInt32) PR_GetPageShift(void);
*/
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___ */
diff --git a/pr/src/misc/prsystem.c b/pr/src/misc/prsystem.c
index 898cc3ce..89986d48 100644
--- a/pr/src/misc/prsystem.c
+++ b/pr/src/misc/prsystem.c
@@ -1,4 +1,4 @@
-/* -*- 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
*
@@ -38,6 +38,7 @@
#include "primpl.h"
#include "prsystem.h"
#include "prprf.h"
+#include "prlong.h"
#if defined(BEOS)
#include <kernel/OS.h>
@@ -45,6 +46,7 @@
#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
@@ -60,8 +62,14 @@
#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)
@@ -69,6 +77,29 @@
#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;
@@ -231,3 +262,101 @@ PR_IMPLEMENT(PRInt32) PR_GetNumberOfProcessors( void )
#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 CutAt *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() */
diff --git a/pr/src/nspr.def b/pr/src/nspr.def
index 0549fd04..bfcf5278 100644
--- a/pr/src/nspr.def
+++ b/pr/src/nspr.def
@@ -460,3 +460,9 @@ EXPORTS ;-
PR_GetAddrInfoByName;
PR_GetCanonNameFromAddrInfo;
;+} NSPR_4.4;
+;+
+;+NSPR_4.6 {
+;+ global:
+ PR_GetPhysicalMemorySize;
+;+} NSPR_4.5;
+
diff --git a/pr/src/nspr_symvec.opt b/pr/src/nspr_symvec.opt
index b6a132a8..d9ca566e 100644
--- a/pr/src/nspr_symvec.opt
+++ b/pr/src/nspr_symvec.opt
@@ -41,7 +41,7 @@ case_sensitive=YES
! These replace stubs 49-52
! --------------------------------------------------------------------------
! Ident 2,8 introduced for NSPR 4.6.
-! PR_FindLibrary removed. Replaced by Stub49 (resurrected).
+! PR_FindLibrary removed. Replaced by PR_GetPhysicalMemorySize.
! --------------------------------------------------------------------------
!
SYMBOL_VECTOR=(PR_Accept=PROCEDURE)
@@ -133,7 +133,7 @@ SYMBOL_VECTOR=(PR_FD_ZERO=PROCEDURE)
SYMBOL_VECTOR=(PR_FileDesc2NativeHandle=PROCEDURE)
SYMBOL_VECTOR=(PR_FindFunctionSymbol=PROCEDURE)
SYMBOL_VECTOR=(PR_FindFunctionSymbolAndLibrary=PROCEDURE)
-SYMBOL_VECTOR=(PR_VMS_Stub49=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetPhysicalMemorySize=PROCEDURE)
SYMBOL_VECTOR=(PR_FindSymbol=PROCEDURE)
SYMBOL_VECTOR=(PR_FindSymbolAndLibrary=PROCEDURE)
SYMBOL_VECTOR=(PR_FloorLog2=PROCEDURE)
diff --git a/pr/tests/system.c b/pr/tests/system.c
index b4a89a0a..e75a4520 100644
--- a/pr/tests/system.c
+++ b/pr/tests/system.c
@@ -75,6 +75,7 @@ PRIntn main(PRIntn argc, char **argv)
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 */