Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/nsprpub/pr/src/misc/prsystem.c
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
#include "primpl.h"
7
#include "prsystem.h"
8
#include "prprf.h"
9
#include "prlong.h"
10
11
#if defined(BEOS)
12
#include <kernel/OS.h>
13
#endif
14
15
#if defined(OS2)
16
#define INCL_DOS
17
#define INCL_DOSMISC
18
#include <os2.h>
19
/* define the required constant if it is not already defined in the headers */
20
#ifndef QSV_NUMPROCESSORS
21
#define QSV_NUMPROCESSORS 26
22
#endif
23
#endif
24
25
/* BSD-derived systems use sysctl() to get the number of processors */
26
#if defined(BSDI) || defined(FREEBSD) || defined(NETBSD) \
27
    || defined(OPENBSD) || defined(DRAGONFLY) || defined(DARWIN)
28
#define _PR_HAVE_SYSCTL
29
#include <sys/param.h>
30
#include <sys/sysctl.h>
31
#endif
32
33
#if defined(DARWIN)
34
#include <mach/mach_init.h>
35
#include <mach/mach_host.h>
36
#include <mach/mach_port.h>
37
#endif
38
39
#if defined(HPUX)
40
#include <sys/mpctl.h>
41
#include <sys/pstat.h>
42
#endif
43
44
#if defined(XP_UNIX)
45
#include <unistd.h>
46
#include <sys/utsname.h>
47
#endif
48
49
#if defined(LINUX)
50
#include <string.h>
51
#include <ctype.h>
52
0
#define MAX_LINE 512
53
#endif
54
55
#if defined(AIX)
56
#include <cf.h>
57
#include <sys/cfgodm.h>
58
#endif
59
60
PR_IMPLEMENT(char) PR_GetDirectorySeparator(void)
61
0
{
62
0
    return PR_DIRECTORY_SEPARATOR;
63
0
}  /* PR_GetDirectorySeparator */
64
65
/*
66
** OBSOLETE -- the function name is misspelled.
67
*/
68
PR_IMPLEMENT(char) PR_GetDirectorySepartor(void)
69
0
{
70
#if defined(DEBUG)
71
    static PRBool warn = PR_TRUE;
72
    if (warn) {
73
        warn = _PR_Obsolete("PR_GetDirectorySepartor()",
74
                "PR_GetDirectorySeparator()");
75
    }
76
#endif
77
    return PR_GetDirectorySeparator();
78
0
}  /* PR_GetDirectorySepartor */
79
80
PR_IMPLEMENT(char) PR_GetPathSeparator(void)
81
0
{
82
0
    return PR_PATH_SEPARATOR;
83
0
}  /* PR_GetPathSeparator */
84
85
PR_IMPLEMENT(PRStatus) PR_GetSystemInfo(PRSysInfo cmd, char *buf, PRUint32 buflen)
86
1
{
87
1
    PRUintn len = 0;
88
1
89
1
    if (!_pr_initialized) _PR_ImplicitInitialization();
90
1
91
1
    switch(cmd)
92
1
    {
93
1
      case PR_SI_HOSTNAME:
94
0
      case PR_SI_HOSTNAME_UNTRUNCATED:
95
0
        if (PR_FAILURE == _PR_MD_GETHOSTNAME(buf, (PRUintn)buflen))
96
0
            return PR_FAILURE;
97
0
98
0
        if (cmd == PR_SI_HOSTNAME_UNTRUNCATED)
99
0
            break;
100
0
        /*
101
0
         * On some platforms a system does not have a hostname and
102
0
         * its IP address is returned instead.   The following code
103
0
         * should be skipped on those platforms.
104
0
         */
105
0
#ifndef _PR_GET_HOST_ADDR_AS_NAME
106
0
        /* Return the unqualified hostname */
107
0
            while (buf[len] && (len < buflen)) {
108
0
                if (buf[len] == '.') {
109
0
                    buf[len] = '\0';
110
0
                    break;
111
0
                }
112
0
                len += 1;
113
0
            }    
114
0
#endif
115
0
         break;
116
0
117
0
      case PR_SI_SYSNAME:
118
0
        /* Return the operating system name */
119
0
#if defined(XP_UNIX) || defined(WIN32)
120
0
        if (PR_FAILURE == _PR_MD_GETSYSINFO(cmd, buf, (PRUintn)buflen))
121
0
            return PR_FAILURE;
122
#else
123
        (void)PR_snprintf(buf, buflen, _PR_SI_SYSNAME);
124
#endif
125
0
        break;
126
0
127
1
      case PR_SI_RELEASE:
128
1
        /* Return the version of the operating system */
129
1
#if defined(XP_UNIX) || defined(WIN32)
130
1
        if (PR_FAILURE == _PR_MD_GETSYSINFO(cmd, buf, (PRUintn)buflen))
131
0
            return PR_FAILURE;
132
1
#endif
133
#if defined(XP_OS2)
134
        {
135
            ULONG os2ver[2] = {0};
136
            DosQuerySysInfo(QSV_VERSION_MINOR, QSV_VERSION_REVISION,
137
                            &os2ver, sizeof(os2ver));
138
            /* Formatting for normal usage (2.11, 3.0, 4.0, 4.5); officially,
139
               Warp 4 is version 2.40.00, WSeB 2.45.00 */
140
            if (os2ver[0] < 30)
141
              (void)PR_snprintf(buf, buflen, "%s%lu",
142
                                "2.", os2ver[0]);
143
            else if (os2ver[0] < 45)
144
              (void)PR_snprintf(buf, buflen, "%lu%s%lu",
145
                                os2ver[0]/10, ".", os2ver[1]);
146
            else
147
              (void)PR_snprintf(buf, buflen, "%.1f",
148
                                os2ver[0]/10.0);
149
        }
150
#endif /* OS2 */
151
1
        break;
152
1
153
1
      case PR_SI_ARCHITECTURE:
154
0
        /* Return the architecture of the machine (ie. x86, mips, alpha, ...)*/
155
0
        (void)PR_snprintf(buf, buflen, _PR_SI_ARCHITECTURE);
156
0
        break;
157
1
    default:
158
0
      PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
159
0
      return PR_FAILURE;
160
1
    }
161
1
    return PR_SUCCESS;
162
1
}
163
164
/*
165
** PR_GetNumberOfProcessors()
166
** 
167
** Implementation notes:
168
**   Every platform does it a bit different.
169
**     numCpus is the returned value.
170
**   for each platform's "if defined" section
171
**     declare your local variable
172
**     do your thing, assign to numCpus
173
**   order of the if defined()s may be important,
174
**     especially for unix variants. Do platform
175
**     specific implementations before XP_UNIX.
176
** 
177
*/
178
PR_IMPLEMENT(PRInt32) PR_GetNumberOfProcessors( void )
179
0
{
180
0
    PRInt32     numCpus;
181
#if defined(WIN32)
182
    SYSTEM_INFO     info;
183
184
    GetSystemInfo( &info );
185
    numCpus = info.dwNumberOfProcessors;
186
#elif defined(BEOS)
187
    system_info sysInfo;
188
189
    get_system_info(&sysInfo);
190
    numCpus = sysInfo.cpu_count;
191
#elif defined(OS2)
192
    DosQuerySysInfo( QSV_NUMPROCESSORS, QSV_NUMPROCESSORS, &numCpus, sizeof(numCpus));
193
#elif defined(_PR_HAVE_SYSCTL)
194
    int mib[2];
195
    int rc;
196
    size_t len = sizeof(numCpus);
197
198
    mib[0] = CTL_HW;
199
    mib[1] = HW_NCPU;
200
    rc = sysctl( mib, 2, &numCpus, &len, NULL, 0 );
201
    if ( -1 == rc )  {
202
        numCpus = -1; /* set to -1 for return value on error */
203
        _PR_MD_MAP_DEFAULT_ERROR( _MD_ERRNO() );
204
    }
205
#elif defined(HPUX)
206
    numCpus = mpctl( MPC_GETNUMSPUS, 0, 0 );
207
    if ( numCpus < 1 )  {
208
        numCpus = -1; /* set to -1 for return value on error */
209
        _PR_MD_MAP_DEFAULT_ERROR( _MD_ERRNO() );
210
    }
211
#elif defined(IRIX)
212
    numCpus = sysconf( _SC_NPROC_ONLN );
213
#elif defined(RISCOS) || defined(SYMBIAN)
214
    numCpus = 1;
215
#elif defined(LINUX)
216
    /* for the benefit of devices with advanced power-saving, that
217
0
       actually hotplug their cpus in heavy load, try to figure out
218
0
       the real number of CPUs */
219
0
    char buf[MAX_LINE];
220
0
    FILE *fin;
221
0
    const char *cpu_present = "/sys/devices/system/cpu/present";
222
0
    size_t strsize;
223
0
    numCpus = 0;
224
0
    fin = fopen(cpu_present, "r");
225
0
    if (fin != NULL) {
226
0
        if (fgets(buf, MAX_LINE, fin) != NULL) {
227
0
            /* check that the format is what we expect */
228
0
            if (buf[0] == '0') {
229
0
                strsize = strlen(buf);
230
0
                if (strsize == 1) {
231
0
                    /* single core */
232
0
                    numCpus = 1;
233
0
                } else if (strsize >= 3 && strsize <= 5) {
234
0
                    /* should be of the form 0-999 */
235
0
                    /* parse the part after the 0-, note count is 0-based */
236
0
                    if (buf[1] == '-' && isdigit(buf[2])) {
237
0
                        numCpus = 1 + atoi(buf + 2);
238
0
                    }
239
0
                }
240
0
            }
241
0
        }
242
0
        fclose(fin);
243
0
    }
244
0
    /* if that fails, fall back to more standard methods */
245
0
    if (!numCpus) {
246
0
        numCpus = sysconf( _SC_NPROCESSORS_CONF );
247
0
    }
248
#elif defined(XP_UNIX)
249
    numCpus = sysconf( _SC_NPROCESSORS_CONF );
250
#else
251
#error "An implementation is required"
252
#endif
253
    return(numCpus);
254
0
} /* end PR_GetNumberOfProcessors() */
255
256
/*
257
** PR_GetPhysicalMemorySize()
258
** 
259
** Implementation notes:
260
**   Every platform does it a bit different.
261
**     bytes is the returned value.
262
**   for each platform's "if defined" section
263
**     declare your local variable
264
**     do your thing, assign to bytes.
265
** 
266
*/
267
PR_IMPLEMENT(PRUint64) PR_GetPhysicalMemorySize(void)
268
3
{
269
3
    PRUint64 bytes = 0;
270
3
271
3
#if defined(LINUX) || defined(SOLARIS)
272
3
273
3
    long pageSize = sysconf(_SC_PAGESIZE);
274
3
    long pageCount = sysconf(_SC_PHYS_PAGES);
275
3
    if (pageSize >= 0 && pageCount >= 0)
276
3
        bytes = (PRUint64) pageSize * pageCount;
277
3
278
#elif defined(NETBSD) || defined(OPENBSD) \
279
    || defined(FREEBSD) || defined(DRAGONFLY)
280
281
    int mib[2];
282
    int rc;
283
#ifdef HW_PHYSMEM64
284
    uint64_t memSize;
285
#else
286
    unsigned long memSize;
287
#endif
288
    size_t len = sizeof(memSize);
289
290
    mib[0] = CTL_HW;
291
#ifdef HW_PHYSMEM64
292
    mib[1] = HW_PHYSMEM64;
293
#else
294
    mib[1] = HW_PHYSMEM;
295
#endif
296
    rc = sysctl(mib, 2, &memSize, &len, NULL, 0);
297
    if (-1 != rc)  {
298
        bytes = memSize;
299
    }
300
301
#elif defined(HPUX)
302
303
    struct pst_static info;
304
    int result = pstat_getstatic(&info, sizeof(info), 1, 0);
305
    if (result == 1)
306
        bytes = (PRUint64) info.physical_memory * info.page_size;
307
308
#elif defined(DARWIN)
309
310
    mach_port_t mach_host = mach_host_self();
311
    struct host_basic_info hInfo;
312
    mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
313
314
    int result = host_info(mach_host,
315
                           HOST_BASIC_INFO,
316
                           (host_info_t) &hInfo,
317
                           &count);
318
    mach_port_deallocate(mach_task_self(), mach_host);
319
    if (result == KERN_SUCCESS)
320
        bytes = hInfo.max_mem;
321
322
#elif defined(WIN32)
323
324
    MEMORYSTATUSEX memStat;
325
    memStat.dwLength = sizeof(memStat);
326
    if (GlobalMemoryStatusEx(&memStat))
327
        bytes = memStat.ullTotalPhys;
328
329
#elif defined(OS2)
330
331
    ULONG ulPhysMem;
332
    DosQuerySysInfo(QSV_TOTPHYSMEM,
333
                    QSV_TOTPHYSMEM,
334
                    &ulPhysMem,
335
                    sizeof(ulPhysMem));
336
    bytes = ulPhysMem;
337
338
#elif defined(AIX)
339
340
    if (odm_initialize() == 0) {
341
        int how_many;
342
        struct CuAt *obj = getattr("sys0", "realmem", 0, &how_many);
343
        if (obj != NULL) {
344
            bytes = (PRUint64) atoi(obj->value) * 1024;
345
            free(obj);
346
        }
347
        odm_terminate();
348
    }
349
350
#else
351
352
    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
353
354
#endif
355
356
3
    return bytes;
357
3
} /* end PR_GetPhysicalMemorySize() */