nsprpub/pr/src/misc/prsystem.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/nsprpub/pr/src/misc/prsystem.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,348 @@
     1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#include "primpl.h"
    1.10 +#include "prsystem.h"
    1.11 +#include "prprf.h"
    1.12 +#include "prlong.h"
    1.13 +
    1.14 +#if defined(BEOS)
    1.15 +#include <kernel/OS.h>
    1.16 +#endif
    1.17 +
    1.18 +#if defined(OS2)
    1.19 +#define INCL_DOS
    1.20 +#define INCL_DOSMISC
    1.21 +#include <os2.h>
    1.22 +/* define the required constant if it is not already defined in the headers */
    1.23 +#ifndef QSV_NUMPROCESSORS
    1.24 +#define QSV_NUMPROCESSORS 26
    1.25 +#endif
    1.26 +#endif
    1.27 +
    1.28 +/* BSD-derived systems use sysctl() to get the number of processors */
    1.29 +#if defined(BSDI) || defined(FREEBSD) || defined(NETBSD) \
    1.30 +    || defined(OPENBSD) || defined(DARWIN)
    1.31 +#define _PR_HAVE_SYSCTL
    1.32 +#include <sys/param.h>
    1.33 +#include <sys/sysctl.h>
    1.34 +#endif
    1.35 +
    1.36 +#if defined(DARWIN)
    1.37 +#include <mach/mach_init.h>
    1.38 +#include <mach/mach_host.h>
    1.39 +#include <mach/mach_port.h>
    1.40 +#endif
    1.41 +
    1.42 +#if defined(HPUX)
    1.43 +#include <sys/mpctl.h>
    1.44 +#include <sys/pstat.h>
    1.45 +#endif
    1.46 +
    1.47 +#if defined(XP_UNIX)
    1.48 +#include <unistd.h>
    1.49 +#include <sys/utsname.h>
    1.50 +#endif
    1.51 +
    1.52 +#if defined(LINUX)
    1.53 +#include <string.h>
    1.54 +#include <ctype.h>
    1.55 +#define MAX_LINE 512
    1.56 +#endif
    1.57 +
    1.58 +#if defined(AIX)
    1.59 +#include <cf.h>
    1.60 +#include <sys/cfgodm.h>
    1.61 +#endif
    1.62 +
    1.63 +PR_IMPLEMENT(char) PR_GetDirectorySeparator(void)
    1.64 +{
    1.65 +    return PR_DIRECTORY_SEPARATOR;
    1.66 +}  /* PR_GetDirectorySeparator */
    1.67 +
    1.68 +/*
    1.69 +** OBSOLETE -- the function name is misspelled.
    1.70 +*/
    1.71 +PR_IMPLEMENT(char) PR_GetDirectorySepartor(void)
    1.72 +{
    1.73 +#if defined(DEBUG)
    1.74 +    static PRBool warn = PR_TRUE;
    1.75 +    if (warn) {
    1.76 +        warn = _PR_Obsolete("PR_GetDirectorySepartor()",
    1.77 +                "PR_GetDirectorySeparator()");
    1.78 +    }
    1.79 +#endif
    1.80 +    return PR_GetDirectorySeparator();
    1.81 +}  /* PR_GetDirectorySepartor */
    1.82 +
    1.83 +PR_IMPLEMENT(char) PR_GetPathSeparator(void)
    1.84 +{
    1.85 +    return PR_PATH_SEPARATOR;
    1.86 +}  /* PR_GetPathSeparator */
    1.87 +
    1.88 +PR_IMPLEMENT(PRStatus) PR_GetSystemInfo(PRSysInfo cmd, char *buf, PRUint32 buflen)
    1.89 +{
    1.90 +    PRUintn len = 0;
    1.91 +
    1.92 +    if (!_pr_initialized) _PR_ImplicitInitialization();
    1.93 +
    1.94 +    switch(cmd)
    1.95 +    {
    1.96 +      case PR_SI_HOSTNAME:
    1.97 +      case PR_SI_HOSTNAME_UNTRUNCATED:
    1.98 +        if (PR_FAILURE == _PR_MD_GETHOSTNAME(buf, (PRUintn)buflen))
    1.99 +            return PR_FAILURE;
   1.100 +
   1.101 +        if (cmd == PR_SI_HOSTNAME_UNTRUNCATED)
   1.102 +            break;
   1.103 +        /*
   1.104 +         * On some platforms a system does not have a hostname and
   1.105 +         * its IP address is returned instead.   The following code
   1.106 +         * should be skipped on those platforms.
   1.107 +         */
   1.108 +#ifndef _PR_GET_HOST_ADDR_AS_NAME
   1.109 +        /* Return the unqualified hostname */
   1.110 +            while (buf[len] && (len < buflen)) {
   1.111 +                if (buf[len] == '.') {
   1.112 +                    buf[len] = '\0';
   1.113 +                    break;
   1.114 +                }
   1.115 +                len += 1;
   1.116 +            }    
   1.117 +#endif
   1.118 +         break;
   1.119 +
   1.120 +      case PR_SI_SYSNAME:
   1.121 +        /* Return the operating system name */
   1.122 +#if defined(XP_UNIX) || defined(WIN32)
   1.123 +        if (PR_FAILURE == _PR_MD_GETSYSINFO(cmd, buf, (PRUintn)buflen))
   1.124 +            return PR_FAILURE;
   1.125 +#else
   1.126 +        (void)PR_snprintf(buf, buflen, _PR_SI_SYSNAME);
   1.127 +#endif
   1.128 +        break;
   1.129 +
   1.130 +      case PR_SI_RELEASE:
   1.131 +        /* Return the version of the operating system */
   1.132 +#if defined(XP_UNIX) || defined(WIN32)
   1.133 +        if (PR_FAILURE == _PR_MD_GETSYSINFO(cmd, buf, (PRUintn)buflen))
   1.134 +            return PR_FAILURE;
   1.135 +#endif
   1.136 +#if defined(XP_OS2)
   1.137 +        {
   1.138 +            ULONG os2ver[2] = {0};
   1.139 +            DosQuerySysInfo(QSV_VERSION_MINOR, QSV_VERSION_REVISION,
   1.140 +                            &os2ver, sizeof(os2ver));
   1.141 +            /* Formatting for normal usage (2.11, 3.0, 4.0, 4.5); officially,
   1.142 +               Warp 4 is version 2.40.00, WSeB 2.45.00 */
   1.143 +            if (os2ver[0] < 30)
   1.144 +              (void)PR_snprintf(buf, buflen, "%s%lu",
   1.145 +                                "2.", os2ver[0]);
   1.146 +            else if (os2ver[0] < 45)
   1.147 +              (void)PR_snprintf(buf, buflen, "%lu%s%lu",
   1.148 +                                os2ver[0]/10, ".", os2ver[1]);
   1.149 +            else
   1.150 +              (void)PR_snprintf(buf, buflen, "%.1f",
   1.151 +                                os2ver[0]/10.0);
   1.152 +        }
   1.153 +#endif /* OS2 */
   1.154 +        break;
   1.155 +
   1.156 +      case PR_SI_ARCHITECTURE:
   1.157 +        /* Return the architecture of the machine (ie. x86, mips, alpha, ...)*/
   1.158 +        (void)PR_snprintf(buf, buflen, _PR_SI_ARCHITECTURE);
   1.159 +        break;
   1.160 +	  default:
   1.161 +			PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
   1.162 +			return PR_FAILURE;
   1.163 +    }
   1.164 +    return PR_SUCCESS;
   1.165 +}
   1.166 +
   1.167 +/*
   1.168 +** PR_GetNumberOfProcessors()
   1.169 +** 
   1.170 +** Implementation notes:
   1.171 +**   Every platform does it a bit different.
   1.172 +**     numCpus is the returned value.
   1.173 +**   for each platform's "if defined" section
   1.174 +**     declare your local variable
   1.175 +**     do your thing, assign to numCpus
   1.176 +**   order of the if defined()s may be important,
   1.177 +**     especially for unix variants. Do platform
   1.178 +**     specific implementations before XP_UNIX.
   1.179 +** 
   1.180 +*/
   1.181 +PR_IMPLEMENT(PRInt32) PR_GetNumberOfProcessors( void )
   1.182 +{
   1.183 +    PRInt32     numCpus;
   1.184 +#if defined(WIN32)
   1.185 +    SYSTEM_INFO     info;
   1.186 +
   1.187 +    GetSystemInfo( &info );
   1.188 +    numCpus = info.dwNumberOfProcessors;
   1.189 +#elif defined(BEOS)
   1.190 +    system_info sysInfo;
   1.191 +
   1.192 +    get_system_info(&sysInfo);
   1.193 +    numCpus = sysInfo.cpu_count;
   1.194 +#elif defined(OS2)
   1.195 +    DosQuerySysInfo( QSV_NUMPROCESSORS, QSV_NUMPROCESSORS, &numCpus, sizeof(numCpus));
   1.196 +#elif defined(_PR_HAVE_SYSCTL)
   1.197 +    int mib[2];
   1.198 +    int rc;
   1.199 +    size_t len = sizeof(numCpus);
   1.200 +
   1.201 +    mib[0] = CTL_HW;
   1.202 +    mib[1] = HW_NCPU;
   1.203 +    rc = sysctl( mib, 2, &numCpus, &len, NULL, 0 );
   1.204 +    if ( -1 == rc )  {
   1.205 +        numCpus = -1; /* set to -1 for return value on error */
   1.206 +        _PR_MD_MAP_DEFAULT_ERROR( _MD_ERRNO() );
   1.207 +    }
   1.208 +#elif defined(HPUX)
   1.209 +    numCpus = mpctl( MPC_GETNUMSPUS, 0, 0 );
   1.210 +    if ( numCpus < 1 )  {
   1.211 +        numCpus = -1; /* set to -1 for return value on error */
   1.212 +        _PR_MD_MAP_DEFAULT_ERROR( _MD_ERRNO() );
   1.213 +    }
   1.214 +#elif defined(IRIX)
   1.215 +    numCpus = sysconf( _SC_NPROC_ONLN );
   1.216 +#elif defined(RISCOS) || defined(SYMBIAN)
   1.217 +    numCpus = 1;
   1.218 +#elif defined(LINUX)
   1.219 +    /* for the benefit of devices with advanced power-saving, that
   1.220 +       actually hotplug their cpus in heavy load, try to figure out
   1.221 +       the real number of CPUs */
   1.222 +    char buf[MAX_LINE];
   1.223 +    FILE *fin;
   1.224 +    const char *cpu_present = "/sys/devices/system/cpu/present";
   1.225 +    size_t strsize;
   1.226 +    numCpus = 0;
   1.227 +    fin = fopen(cpu_present, "r");
   1.228 +    if (fin != NULL) {
   1.229 +        if (fgets(buf, MAX_LINE, fin) != NULL) {
   1.230 +            /* check that the format is what we expect */
   1.231 +            if (buf[0] == '0') {
   1.232 +                strsize = strlen(buf);
   1.233 +                if (strsize == 1) {
   1.234 +                    /* single core */
   1.235 +                    numCpus = 1;
   1.236 +                } else if (strsize >= 3 && strsize <= 5) {
   1.237 +                    /* should be of the form 0-999 */
   1.238 +                    /* parse the part after the 0-, note count is 0-based */
   1.239 +                    if (buf[1] == '-' && isdigit(buf[2])) {
   1.240 +                        numCpus = 1 + atoi(buf + 2);
   1.241 +                    }
   1.242 +                }
   1.243 +            }
   1.244 +        }
   1.245 +        fclose(fin);
   1.246 +    }
   1.247 +    /* if that fails, fall back to more standard methods */
   1.248 +    if (!numCpus) {
   1.249 +        numCpus = sysconf( _SC_NPROCESSORS_CONF );
   1.250 +    }
   1.251 +#elif defined(XP_UNIX)
   1.252 +    numCpus = sysconf( _SC_NPROCESSORS_CONF );
   1.253 +#else
   1.254 +#error "An implementation is required"
   1.255 +#endif
   1.256 +    return(numCpus);
   1.257 +} /* end PR_GetNumberOfProcessors() */
   1.258 +
   1.259 +/*
   1.260 +** PR_GetPhysicalMemorySize()
   1.261 +** 
   1.262 +** Implementation notes:
   1.263 +**   Every platform does it a bit different.
   1.264 +**     bytes is the returned value.
   1.265 +**   for each platform's "if defined" section
   1.266 +**     declare your local variable
   1.267 +**     do your thing, assign to bytes.
   1.268 +** 
   1.269 +*/
   1.270 +PR_IMPLEMENT(PRUint64) PR_GetPhysicalMemorySize(void)
   1.271 +{
   1.272 +    PRUint64 bytes = 0;
   1.273 +
   1.274 +#if defined(LINUX) || defined(SOLARIS)
   1.275 +
   1.276 +    long pageSize = sysconf(_SC_PAGESIZE);
   1.277 +    long pageCount = sysconf(_SC_PHYS_PAGES);
   1.278 +    if (pageSize >= 0 && pageCount >= 0)
   1.279 +        bytes = (PRUint64) pageSize * pageCount;
   1.280 +
   1.281 +#elif defined(NETBSD) || defined(OPENBSD)
   1.282 +
   1.283 +    int mib[2];
   1.284 +    int rc;
   1.285 +    uint64_t memSize;
   1.286 +    size_t len = sizeof(memSize);
   1.287 +
   1.288 +    mib[0] = CTL_HW;
   1.289 +    mib[1] = HW_PHYSMEM64;
   1.290 +    rc = sysctl(mib, 2, &memSize, &len, NULL, 0);
   1.291 +    if (-1 != rc)  {
   1.292 +        bytes = memSize;
   1.293 +    }
   1.294 +
   1.295 +#elif defined(HPUX)
   1.296 +
   1.297 +    struct pst_static info;
   1.298 +    int result = pstat_getstatic(&info, sizeof(info), 1, 0);
   1.299 +    if (result == 1)
   1.300 +        bytes = (PRUint64) info.physical_memory * info.page_size;
   1.301 +
   1.302 +#elif defined(DARWIN)
   1.303 +
   1.304 +    mach_port_t mach_host = mach_host_self();
   1.305 +    struct host_basic_info hInfo;
   1.306 +    mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
   1.307 +
   1.308 +    int result = host_info(mach_host,
   1.309 +                           HOST_BASIC_INFO,
   1.310 +                           (host_info_t) &hInfo,
   1.311 +                           &count);
   1.312 +    mach_port_deallocate(mach_task_self(), mach_host);
   1.313 +    if (result == KERN_SUCCESS)
   1.314 +        bytes = hInfo.max_mem;
   1.315 +
   1.316 +#elif defined(WIN32)
   1.317 +
   1.318 +    MEMORYSTATUSEX memStat;
   1.319 +    memStat.dwLength = sizeof(memStat);
   1.320 +    if (GlobalMemoryStatusEx(&memStat))
   1.321 +        bytes = memStat.ullTotalPhys;
   1.322 +
   1.323 +#elif defined(OS2)
   1.324 +
   1.325 +    ULONG ulPhysMem;
   1.326 +    DosQuerySysInfo(QSV_TOTPHYSMEM,
   1.327 +                    QSV_TOTPHYSMEM,
   1.328 +                    &ulPhysMem,
   1.329 +                    sizeof(ulPhysMem));
   1.330 +    bytes = ulPhysMem;
   1.331 +
   1.332 +#elif defined(AIX)
   1.333 +
   1.334 +    if (odm_initialize() == 0) {
   1.335 +        int how_many;
   1.336 +        struct CuAt *obj = getattr("sys0", "realmem", 0, &how_many);
   1.337 +        if (obj != NULL) {
   1.338 +            bytes = (PRUint64) atoi(obj->value) * 1024;
   1.339 +            free(obj);
   1.340 +        }
   1.341 +        odm_terminate();
   1.342 +    }
   1.343 +
   1.344 +#else
   1.345 +
   1.346 +    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
   1.347 +
   1.348 +#endif
   1.349 +
   1.350 +    return bytes;
   1.351 +} /* end PR_GetPhysicalMemorySize() */

mercurial