Add PR_GetPhysicalMemorySize to determine the amount of system memory installed (bug 292899). r=wtc, a=brendan

This commit is contained in:
bryner%brianryner.com 2005-05-06 18:46:11 +00:00
Родитель ed538371bf
Коммит dc837452de
6 изменённых файлов: 159 добавлений и 3 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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___ */

Просмотреть файл

@ -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() */

Просмотреть файл

@ -460,3 +460,9 @@ EXPORTS ;-
PR_GetAddrInfoByName;
PR_GetCanonNameFromAddrInfo;
;+} NSPR_4.4;
;+
;+NSPR_4.6 {
;+ global:
PR_GetPhysicalMemorySize;
;+} NSPR_4.5;

Просмотреть файл

@ -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)

Просмотреть файл

@ -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 */