diff options
author | bryner%brianryner.com <devnull@localhost> | 2005-05-06 18:46:03 +0000 |
---|---|---|
committer | bryner%brianryner.com <devnull@localhost> | 2005-05-06 18:46:03 +0000 |
commit | 298dcda26d03d759ed8c8cd1fea17660c40bf7c6 (patch) | |
tree | 79857f4454c7ab86bb88b8e8184e71b5c6314dd8 | |
parent | 46164cb60f49cf970b1ebba5485b27684803481f (diff) | |
download | nspr-hg-298dcda26d03d759ed8c8cd1fea17660c40bf7c6.tar.gz |
Add PR_GetPhysicalMemorySize to determine the amount of system memory installed (bug 292899). r=wtc, a=brendan
-rw-r--r-- | config/system-headers | 4 | ||||
-rw-r--r-- | pr/include/prsystem.h | 16 | ||||
-rw-r--r-- | pr/src/misc/prsystem.c | 131 | ||||
-rw-r--r-- | pr/src/nspr.def | 6 | ||||
-rw-r--r-- | pr/src/nspr_symvec.opt | 4 | ||||
-rw-r--r-- | pr/tests/system.c | 1 |
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 */ |