Coverage Report

Created: 2024-05-20 06:23

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