diff --git a/nsprpub/config/system-headers b/nsprpub/config/system-headers index 7a2869e78421..cf0f11498f5f 100644 --- a/nsprpub/config/system-headers +++ b/nsprpub/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/nsprpub/pr/include/prsystem.h b/nsprpub/pr/include/prsystem.h index 0dc420b8df16..b0dfcf9e0905 100644 --- a/nsprpub/pr/include/prsystem.h +++ b/nsprpub/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/nsprpub/pr/src/misc/prsystem.c b/nsprpub/pr/src/misc/prsystem.c index 898cc3ceb868..89986d483d79 100644 --- a/nsprpub/pr/src/misc/prsystem.c +++ b/nsprpub/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 @@ -45,6 +46,7 @@ #if defined(OS2) #define INCL_DOS +#define INCL_DOSMISC #include /* define the required constant if it is not already defined in the headers */ #ifndef QSV_NUMPROCESSORS @@ -60,8 +62,14 @@ #include #endif +#if defined(DARWIN) +#include +#include +#endif + #if defined(HPUX) #include +#include #endif #if defined(XP_UNIX) @@ -69,6 +77,29 @@ #include #endif +#if defined(AIX) +#include +#include +#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/nsprpub/pr/src/nspr.def b/nsprpub/pr/src/nspr.def index 0549fd048d8e..bfcf527841f7 100644 --- a/nsprpub/pr/src/nspr.def +++ b/nsprpub/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/nsprpub/pr/src/nspr_symvec.opt b/nsprpub/pr/src/nspr_symvec.opt index b6a132a8917d..d9ca566ecffe 100644 --- a/nsprpub/pr/src/nspr_symvec.opt +++ b/nsprpub/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/nsprpub/pr/tests/system.c b/nsprpub/pr/tests/system.c index b4a89a0a20db..e75a452071a0 100644 --- a/nsprpub/pr/tests/system.c +++ b/nsprpub/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 */