~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to ksysguard/ksysguardd/FreeBSD/cpuinfo.c

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    KSysGuard, the KDE System Guard
 
3
 
 
4
    Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
 
5
    Copyright (c) 2010 David Naylor <naylor.b.david@gmail.com>
 
6
 
 
7
    This program is free software; you can redistribute it and/or modify
 
8
    it under the terms of the GNU General Public License as published by
 
9
    the Free Software Foundation; either version 2 of the License, or
 
10
    (at your option) any later version.
 
11
 
 
12
    This program is distributed in the hope that it will be useful,
 
13
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
    GNU General Public License for more details.
 
16
 
 
17
    You should have received a copy of the GNU General Public License
 
18
    along with this program; if not, write to the Free Software
 
19
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
20
 
 
21
*/
 
22
 
 
23
#include <sys/types.h>
 
24
 
 
25
#include <sys/resource.h>
 
26
#include <sys/sysctl.h>
 
27
 
 
28
#include <devstat.h>
 
29
#include <fcntl.h>
 
30
#include <nlist.h>
 
31
#include <stdio.h>
 
32
#include <stdlib.h>
 
33
#include <string.h>
 
34
 
 
35
#include "cpuinfo.h"
 
36
#include "Command.h"
 
37
#include "ksysguardd.h"
 
38
 
 
39
#define FREQ_LEVEL_BUFFER 256
 
40
#define SYSCTL_ID_LEN 35
 
41
 
 
42
static void get_mmfreq(int, int*, int*);
 
43
 
 
44
static long percentages(int cnt, long *out, long *new, long *old, long *diffs);
 
45
 
 
46
static long (*cp_time)[CPUSTATES] = NULL;
 
47
static long (*cp_old)[CPUSTATES] = NULL;
 
48
static long (*cp_diff)[CPUSTATES] = NULL;
 
49
 
 
50
static int maxcpus = 1;
 
51
static int cpus = 1;
 
52
static int cores = 1;
 
53
static int (*freq)[3] = NULL;
 
54
static int *temp = NULL;
 
55
 
 
56
static long (*cpu_states)[CPUSTATES] = NULL;
 
57
 
 
58
void
 
59
initCpuInfo(struct SensorModul* sm)
 
60
{
 
61
    size_t len;
 
62
    int id;
 
63
    char name[SYSCTL_ID_LEN];
 
64
    int minfreq, maxfreq;
 
65
 
 
66
    len = sizeof(cpus);
 
67
    // XXX: this is a guess
 
68
    sysctlbyname("kern.smp.active", &cpus, &len, NULL, 0);
 
69
    // NOTE: cpus may be 0, which implies 1
 
70
    cpus = cpus ? cpus : 1;
 
71
 
 
72
    len = sizeof(cores);
 
73
    sysctlbyname("kern.smp.cpus", &cores, &len, NULL, 0);
 
74
 
 
75
    len = sizeof(maxcpus);
 
76
    sysctlbyname("kern.smp.maxcpus", &maxcpus, &len, NULL, 0);
 
77
 
 
78
    /* Core/process count */
 
79
    registerMonitor("system/processors", "integer", printNumCpus, printNumCpusInfo, sm);
 
80
    registerMonitor("system/cores", "integer", printNumCores, printNumCoresInfo, sm);
 
81
 
 
82
    /*
 
83
     * CPU Loads
 
84
     */
 
85
    if ((cp_time = malloc(sizeof(long) * CPUSTATES * (cores * 4 + 1))) == NULL) {
 
86
        log_error("out of memory for cp_time");
 
87
        return;
 
88
    }
 
89
    cp_old = &cp_time[cores];
 
90
    cp_diff = &cp_old[cores];
 
91
    cpu_states = &cp_diff[cores];
 
92
 
 
93
    /* Total CPU load */
 
94
    registerMonitor("cpu/system/user", "float", printCPUUser, printCPUUserInfo, sm);
 
95
    registerMonitor("cpu/system/nice", "float", printCPUNice, printCPUNiceInfo, sm);
 
96
    registerMonitor("cpu/system/sys", "float", printCPUSys, printCPUSysInfo, sm);
 
97
    registerMonitor("cpu/system/TotalLoad", "float", printCPUTotalLoad, printCPUTotalLoadInfo, sm);
 
98
    registerMonitor("cpu/system/intr", "float", printCPUIntr, printCPUIntrInfo, sm);
 
99
    registerMonitor("cpu/system/idle", "float", printCPUIdle, printCPUIdleInfo, sm);
 
100
 
 
101
    /* Monitor names changed from kde3 => kde4. Remain compatible with legacy requests when possible. */
 
102
    registerLegacyMonitor("cpu/user", "float", printCPUUser, printCPUUserInfo, sm);
 
103
    registerLegacyMonitor("cpu/nice", "float", printCPUNice, printCPUNiceInfo, sm);
 
104
    registerLegacyMonitor("cpu/sys", "float", printCPUSys, printCPUSysInfo, sm);
 
105
    registerLegacyMonitor("cpu/idle", "float", printCPUIdle, printCPUIdleInfo, sm);
 
106
 
 
107
    for (id = 0; id < cores; ++id) {
 
108
        snprintf(name, SYSCTL_ID_LEN, "cpu/cpu%d/user", id);
 
109
        registerMonitor(name, "float", printCPUxUser, printCPUxUserInfo, sm);
 
110
        snprintf(name, SYSCTL_ID_LEN, "cpu/cpu%d/nice", id);
 
111
        registerMonitor(name, "float", printCPUxNice, printCPUxNiceInfo, sm);
 
112
        snprintf(name, SYSCTL_ID_LEN, "cpu/cpu%d/sys", id);
 
113
        registerMonitor(name, "float", printCPUxSys, printCPUxSysInfo, sm);
 
114
        snprintf(name, SYSCTL_ID_LEN, "cpu/cpu%d/TotalLoad", id);
 
115
        registerMonitor(name, "float", printCPUxTotalLoad, printCPUxTotalLoadInfo, sm);
 
116
        snprintf(name, SYSCTL_ID_LEN, "cpu/cpu%d/intr", id);
 
117
        registerMonitor(name, "float", printCPUxIntr, printCPUxIntrInfo, sm);
 
118
        snprintf(name, SYSCTL_ID_LEN, "cpu/cpu%d/idle", id);
 
119
        registerMonitor(name, "float", printCPUxIdle, printCPUxIdleInfo, sm);
 
120
    }
 
121
 
 
122
    /*
 
123
     * CPU frequencies
 
124
     */
 
125
    if ((freq = malloc(sizeof(int) * 3 * (cores + 1))) == NULL) {
 
126
        log_error("out of memory for freq");
 
127
        return;
 
128
    }
 
129
 
 
130
    registerMonitor("cpu/system/AverageClock", "float", printCPUClock, printCPUClockInfo, sm);
 
131
    for (id = 0; id < cores; ++id) {
 
132
        len = sizeof(int);
 
133
        snprintf(name, SYSCTL_ID_LEN, "dev.cpu.%d.freq", id);
 
134
        if (!sysctlbyname(name, &freq[id][0], &len, NULL, 0)) {
 
135
            get_mmfreq(id, &freq[id][1], &freq[id][2]);
 
136
            snprintf(name, SYSCTL_ID_LEN, "cpu/cpu%d/clock", id);
 
137
            registerMonitor(name, "integer", printCPUxClock, printCPUxClockInfo, sm);
 
138
        } else {
 
139
            freq[id][0] = -1;
 
140
            freq[id][1] = 0;
 
141
            freq[id][2] = 0;
 
142
        }
 
143
    }
 
144
 
 
145
    minfreq = freq[0][1];
 
146
    maxfreq = freq[0][2];
 
147
    for (id = 1; id < cores; ++id)
 
148
        if (freq[id][0] != -1) {
 
149
            minfreq = minfreq > freq[id][1] ? freq[id][1] : minfreq;
 
150
            maxfreq = maxfreq < freq[id][2] ? freq[id][2] : maxfreq;
 
151
        }
 
152
    freq[cores][1] = minfreq;
 
153
    freq[cores][2] = maxfreq;
 
154
 
 
155
    /*
 
156
     * CPU temperature
 
157
     */
 
158
    if ((temp = malloc(sizeof(int) * (cores + 1))) == NULL) {
 
159
        log_error("out of memory for temp");
 
160
        return;
 
161
    }
 
162
    registerMonitor("cpu/system/AverageTemperature", "float", printCPUTemperature, printCPUTemperatureInfo, sm);
 
163
    for (id = 0; id < cores; ++id) {
 
164
        len = sizeof(int);
 
165
        snprintf(name, SYSCTL_ID_LEN, "dev.cpu.%d.temperature", id);
 
166
        if (!sysctlbyname(name, &temp[id], &len, NULL, 0)) {
 
167
            snprintf(name, SYSCTL_ID_LEN, "cpu/cpu%d/temperature", id);
 
168
            registerMonitor(name, "float", printCPUxTemperature, printCPUxTemperatureInfo, sm);
 
169
        } else
 
170
            temp[id] = -1;
 
171
    }
 
172
 
 
173
    updateCpuInfo();
 
174
}
 
175
 
 
176
void
 
177
exitCpuInfo(void)
 
178
{
 
179
    int id;
 
180
    char name[SYSCTL_ID_LEN];
 
181
 
 
182
    removeMonitor("system/processors");
 
183
    removeMonitor("system/cores");
 
184
 
 
185
    if (cp_time != NULL) {
 
186
        removeMonitor("cpu/system/user");
 
187
        removeMonitor("cpu/system/nice");
 
188
        removeMonitor("cpu/system/sys");
 
189
        removeMonitor("cpu/system/TotalLoad");
 
190
        removeMonitor("cpu/system/intr");
 
191
        removeMonitor("cpu/system/idle");
 
192
 
 
193
        /* These were registered as legacy monitors */
 
194
        removeMonitor("cpu/user");
 
195
        removeMonitor("cpu/nice");
 
196
        removeMonitor("cpu/sys");
 
197
        removeMonitor("cpu/idle");
 
198
 
 
199
        for (id = 0; id < cores; ++id) {
 
200
            snprintf(name, SYSCTL_ID_LEN, "cpu/cpu%d/user", id);
 
201
            removeMonitor(name);
 
202
            snprintf(name, SYSCTL_ID_LEN, "cpu/cpu%d/nice", id);
 
203
            removeMonitor(name);
 
204
            snprintf(name, SYSCTL_ID_LEN, "cpu/cpu%d/sys", id);
 
205
            removeMonitor(name);
 
206
            snprintf(name, SYSCTL_ID_LEN, "cpu/cpu%d/TotalLoad", id);
 
207
            removeMonitor(name);
 
208
            snprintf(name, SYSCTL_ID_LEN, "cpu/cpu%d/intr", id);
 
209
            removeMonitor(name);
 
210
            snprintf(name, SYSCTL_ID_LEN, "cpu/cpu%d/idle", id);
 
211
            removeMonitor(name);
 
212
 
 
213
            if (freq != NULL && freq[id][0] != -1) {
 
214
                snprintf(name, SYSCTL_ID_LEN, "cpu/cpu%d/clock", id);
 
215
                removeMonitor(name);
 
216
            }
 
217
            if (temp != NULL && temp[id] != -1) {
 
218
                snprintf(name, SYSCTL_ID_LEN, "cpu/cpu%d/temperature", id);
 
219
                removeMonitor(name);
 
220
            }
 
221
        }
 
222
 
 
223
        free(cp_time);
 
224
        cp_time = NULL;
 
225
    }
 
226
 
 
227
    if (freq != NULL) {
 
228
        removeMonitor("cpu/system/AverageClock");
 
229
        for (id = 0; id < cores; ++id)
 
230
            if (freq[id][0] != -1) {
 
231
                snprintf(name, SYSCTL_ID_LEN, "cpu/cpu%d/clock", id);
 
232
                removeMonitor(name);
 
233
            }
 
234
        free(freq);
 
235
        freq = NULL;
 
236
    }
 
237
 
 
238
    if (temp != NULL) {
 
239
        removeMonitor("cpu/system/AverageTemperature");
 
240
        for (id = 0; id < cores; ++id)
 
241
            if (temp[id] != -1) {
 
242
                snprintf(name, SYSCTL_ID_LEN, "cpu/cpu%d/temperature", id);
 
243
                removeMonitor(name);
 
244
            }
 
245
        free(temp);
 
246
        temp = NULL;
 
247
    }
 
248
 
 
249
}
 
250
 
 
251
int
 
252
updateCpuInfo(void)
 
253
{
 
254
    int sid, id, tot_freq = 0, tot_temp = 0, freq_count = 0, temp_count = 0;
 
255
    char name[SYSCTL_ID_LEN];
 
256
 
 
257
    if (cp_time == NULL || freq == NULL || temp == NULL)
 
258
        return (0);
 
259
 
 
260
        size_t len = sizeof(long) * CPUSTATES * cores;
 
261
        sysctlbyname("kern.cp_times", cp_time, &len, NULL, 0);
 
262
    for (sid = 0; sid < CPUSTATES; ++sid)
 
263
        cpu_states[cores][sid] = 0;
 
264
    for (id = 0; id < cores; ++id) {
 
265
        percentages(CPUSTATES, cpu_states[id], cp_time[id], cp_old[id], cp_diff[id]);
 
266
        for (sid = 0; sid < CPUSTATES; ++sid)
 
267
            cpu_states[cores][sid] += cpu_states[id][sid];
 
268
    }
 
269
    for (id = 0; id < cores; ++id) {
 
270
        if (freq[id][0] != -1) {
 
271
            len = sizeof(int);
 
272
            snprintf(name, SYSCTL_ID_LEN, "dev.cpu.%d.freq", id);
 
273
            freq[id][0] = 0;
 
274
            if (!sysctlbyname(name, &freq[id][0], &len, NULL, 0)) {
 
275
                freq_count += 1;
 
276
                tot_freq += freq[id][0];
 
277
            }
 
278
        }
 
279
        if (temp[id] != -1) {
 
280
            len = sizeof(int);
 
281
            snprintf(name, SYSCTL_ID_LEN, "dev.cpu.%d.temperature", id);
 
282
            temp[id] = 0.0;
 
283
            if (!sysctlbyname(name, &temp[id], &len, NULL, 0)) {
 
284
                temp_count += 1;
 
285
                tot_temp += temp[id];
 
286
            }
 
287
        }
 
288
    }
 
289
    freq[cores][0] = freq_count == 0 ? 0 : tot_freq * 100 / freq_count;
 
290
    temp[cores] = temp_count == 0 ? 0.0 : tot_temp * 100 / temp_count;
 
291
 
 
292
    return (0);
 
293
}
 
294
 
 
295
void
 
296
printCPUUser(const char* cmd)
 
297
{
 
298
    fprintf(CurrentClient, "%f\n", cpu_states[cores][CP_USER] / 10.0 / cores);
 
299
}
 
300
 
 
301
void
 
302
printCPUUserInfo(const char* cmd)
 
303
{
 
304
    fprintf(CurrentClient, "CPU User Load\t0\t100\t%%\n");
 
305
}
 
306
 
 
307
void
 
308
printCPUNice(const char* cmd)
 
309
{
 
310
    fprintf(CurrentClient, "%f\n", cpu_states[cores][CP_NICE] / 10.0 / cores);
 
311
}
 
312
 
 
313
void
 
314
printCPUNiceInfo(const char* cmd)
 
315
{
 
316
    fprintf(CurrentClient, "CPU Nice Load\t0\t100\t%%\n");
 
317
}
 
318
 
 
319
void
 
320
printCPUSys(const char* cmd)
 
321
{
 
322
    fprintf(CurrentClient, "%f\n", cpu_states[cores][CP_SYS] / 10.0 / cores);
 
323
}
 
324
 
 
325
void
 
326
printCPUSysInfo(const char* cmd)
 
327
{
 
328
    fprintf(CurrentClient, "CPU System Load\t0\t100\t%%\n");
 
329
}
 
330
 
 
331
void
 
332
printCPUTotalLoad(const char* cmd)
 
333
{
 
334
    fprintf(CurrentClient, "%f\n", (cpu_states[cores][CP_SYS] + cpu_states[cores][CP_USER] +
 
335
        cpu_states[cores][CP_NICE] + cpu_states[cores][CP_INTR]) / 10.0 / cores);
 
336
}
 
337
 
 
338
void
 
339
printCPUTotalLoadInfo(const char* cmd)
 
340
{
 
341
        fprintf(CurrentClient, "CPU Total Load\t0\t100\t%%\n");
 
342
}
 
343
 
 
344
void
 
345
printCPUIntr(const char* cmd)
 
346
{
 
347
        fprintf(CurrentClient, "%f\n", cpu_states[cores][CP_INTR] / 10.0 / cores);
 
348
}
 
349
 
 
350
void
 
351
printCPUIntrInfo(const char* cmd)
 
352
{
 
353
        fprintf(CurrentClient, "CPU Interrupt Load\t0\t100\t%%\n");
 
354
}
 
355
 
 
356
void
 
357
printCPUIdle(const char* cmd)
 
358
{
 
359
    fprintf(CurrentClient, "%f\n", cpu_states[cores][CP_IDLE] / 10.0 / cores);
 
360
}
 
361
 
 
362
void
 
363
printCPUIdleInfo(const char* cmd)
 
364
{
 
365
    fprintf(CurrentClient, "CPU Idle Load\t0\t100\t%%\n");
 
366
}
 
367
 
 
368
void
 
369
printCPUxUser(const char* cmd)
 
370
{
 
371
    int id;
 
372
 
 
373
    sscanf(cmd + 7, "%d", &id);
 
374
    fprintf(CurrentClient, "%0.1f\n", cpu_states[id][CP_USER] / 10.0);
 
375
}
 
376
 
 
377
void
 
378
printCPUxUserInfo(const char* cmd)
 
379
{
 
380
    int id;
 
381
 
 
382
    sscanf(cmd + 7, "%d", &id);
 
383
    fprintf(CurrentClient, "CPU%d User Load\t0\t100\t%%\n", id + 1);
 
384
}
 
385
 
 
386
void
 
387
printCPUxNice(const char* cmd)
 
388
{
 
389
    int id;
 
390
 
 
391
    sscanf(cmd + 7, "%d", &id);
 
392
    fprintf(CurrentClient, "%0.1f\n", cpu_states[id][CP_NICE] / 10.0);
 
393
}
 
394
 
 
395
void
 
396
printCPUxNiceInfo(const char* cmd)
 
397
{
 
398
    int id;
 
399
 
 
400
    sscanf(cmd + 7, "%d", &id);
 
401
    fprintf(CurrentClient, "CPU%d Nice Load\t0\t100\t%%\n", id + 1);
 
402
}
 
403
 
 
404
void
 
405
printCPUxSys(const char* cmd)
 
406
{
 
407
    int id;
 
408
 
 
409
    sscanf(cmd + 7, "%d", &id);
 
410
    fprintf(CurrentClient, "%0.1f\n", cpu_states[id][CP_SYS] / 10.0);
 
411
}
 
412
 
 
413
void
 
414
printCPUxSysInfo(const char* cmd)
 
415
{
 
416
    int id;
 
417
 
 
418
    sscanf(cmd + 7, "%d", &id);
 
419
    fprintf(CurrentClient, "CPU%d System Load\t0\t100\t%%\n", id + 1);
 
420
}
 
421
 
 
422
void
 
423
printCPUxTotalLoad(const char* cmd)
 
424
{
 
425
    int id;
 
426
 
 
427
    sscanf(cmd + 7, "%d", &id);
 
428
    fprintf(CurrentClient, "%f\n", (cpu_states[id][CP_SYS] + cpu_states[id][CP_USER] +
 
429
        cpu_states[id][CP_NICE] + cpu_states[id][CP_INTR]) / 10.0);
 
430
}
 
431
 
 
432
void
 
433
printCPUxTotalLoadInfo(const char* cmd)
 
434
{
 
435
    int id;
 
436
 
 
437
    sscanf(cmd + 7, "%d", &id);
 
438
    fprintf(CurrentClient, "CPU%d Total Load\t0\t100\t%%\n", id + 1);
 
439
}
 
440
 
 
441
void
 
442
printCPUxIntr(const char* cmd)
 
443
{
 
444
    int id;
 
445
 
 
446
    sscanf(cmd + 7, "%d", &id);
 
447
        fprintf(CurrentClient, "%0.1f\n", cpu_states[id][CP_INTR] / 10.0);
 
448
}
 
449
 
 
450
void
 
451
printCPUxIntrInfo(const char* cmd)
 
452
{
 
453
    int id;
 
454
 
 
455
    sscanf(cmd + 7, "%d", &id);
 
456
    fprintf(CurrentClient, "CPU%d Interrupt Load\t0\t100\t%%\n", id + 1);
 
457
}
 
458
 
 
459
void
 
460
printCPUxIdle(const char* cmd)
 
461
{
 
462
    int id;
 
463
 
 
464
    sscanf(cmd + 7, "%d", &id);
 
465
    fprintf(CurrentClient, "%0.1f\n", cpu_states[id][CP_IDLE] / 10.0);
 
466
}
 
467
 
 
468
void
 
469
printCPUxIdleInfo(const char* cmd)
 
470
{
 
471
    int id;
 
472
 
 
473
    sscanf(cmd + 7, "%d", &id);
 
474
    fprintf(CurrentClient, "CPU%d Idle Load\t0\t100\t%%\n", id + 1);
 
475
}
 
476
 
 
477
void printCPUxClock(const char* cmd)
 
478
{
 
479
    int id;
 
480
 
 
481
    sscanf(cmd + 7, "%d", &id);
 
482
    fprintf(CurrentClient, "%d\n", freq[id][0]);
 
483
}
 
484
 
 
485
void printCPUxClockInfo(const char* cmd)
 
486
{
 
487
    int id;
 
488
 
 
489
    sscanf(cmd + 7, "%d", &id);
 
490
    fprintf(CurrentClient, "CPU%d Clock Frequency\t%d\t%d\tMHz\n", id + 1,
 
491
        freq[id][1], freq[id][2]);
 
492
}
 
493
 
 
494
void printCPUClock(const char* cmd)
 
495
{
 
496
    fprintf(CurrentClient, "%f\n", freq[cores][0] / 100.0);
 
497
}
 
498
 
 
499
void printCPUClockInfo(const char* cmd)
 
500
{
 
501
    fprintf(CurrentClient, "CPU Clock Frequency\t%d\t%d\tMHz\n", freq[cores][1], freq[cores][2]);
 
502
}
 
503
 
 
504
void printCPUxTemperature(const char* cmd)
 
505
{
 
506
    int id;
 
507
 
 
508
    sscanf(cmd + 7, "%d", &id);
 
509
    fprintf(CurrentClient, "%0.1f\n", (temp[id] - 2732) / 10.0);
 
510
}
 
511
 
 
512
void printCPUxTemperatureInfo(const char* cmd)
 
513
{
 
514
    int id;
 
515
 
 
516
    sscanf(cmd + 7, "%d", &id);
 
517
    fprintf(CurrentClient, "CPU%d Temperature\t0\t0\tC\n", id + 1);
 
518
}
 
519
 
 
520
void printCPUTemperature(const char* cmd)
 
521
{
 
522
    fprintf(CurrentClient, "%0.3f\n", (temp[cores] - 273200) / 1000.0);
 
523
}
 
524
 
 
525
void printCPUTemperatureInfo(const char* cmd)
 
526
{
 
527
    fprintf(CurrentClient, "CPU Temperature\t0\t0\tC\n");
 
528
}
 
529
 
 
530
void printNumCpus(const char* cmd)
 
531
{
 
532
    fprintf(CurrentClient, "%d\n", cpus);
 
533
}
 
534
 
 
535
void printNumCpusInfo(const char* cmd)
 
536
{
 
537
    fprintf(CurrentClient, "Number of physical CPUs\t0\t%d\t\n", maxcpus);
 
538
}
 
539
 
 
540
void printNumCores(const char* cmd)
 
541
{
 
542
    fprintf(CurrentClient, "%d\n", cores);
 
543
}
 
544
 
 
545
void printNumCoresInfo(const char* cmd)
 
546
{
 
547
    fprintf(CurrentClient, "Total number of processor cores\t0\t%d\t\n", maxcpus);
 
548
}
 
549
 
 
550
void get_mmfreq(int id, int* minfreq, int* maxfreq)
 
551
{
 
552
    char buf[FREQ_LEVEL_BUFFER];
 
553
    char mid[SYSCTL_ID_LEN];
 
554
    size_t len = FREQ_LEVEL_BUFFER;
 
555
 
 
556
    *minfreq = 0;
 
557
    *maxfreq = 0;
 
558
 
 
559
    snprintf(mid, sizeof(mid), "dev.cpu.%d.freq_levels", id);
 
560
    if (!sysctlbyname(mid, buf, &len, NULL, 0))
 
561
    {
 
562
        char *start = buf;
 
563
        char *end;
 
564
 
 
565
        /*
 
566
         * The string is ([[freq]]/[[num]] )*([[freq]]/[[num]] ), so
 
567
         * for each frequency we get we must also skip over another
 
568
         * set of numbers
 
569
         */
 
570
        while (1)
 
571
        {
 
572
            // Get the first number
 
573
            int number = strtol(start, &end, 10);
 
574
            if (start == end)
 
575
                break;
 
576
            if (!*maxfreq)
 
577
                *maxfreq = number;
 
578
            else
 
579
                *minfreq = number;
 
580
            if (!*end)
 
581
                break;
 
582
            start = end + 1;
 
583
 
 
584
            // Skip over the next number
 
585
            strtol(start, &end, 10);
 
586
            if (start == end || !*end)
 
587
                break;
 
588
            start = end + 1;
 
589
        }
 
590
    }
 
591
}
 
592
 
 
593
/* The part ripped from top... */
 
594
/*
 
595
 *  Top users/processes display for Unix
 
596
 *  Version 3
 
597
 *
 
598
 *  This program may be freely redistributed,
 
599
 *  but this entire comment MUST remain intact.
 
600
 *
 
601
 *  Copyright (c) 1984, 1989, William LeFebvre, Rice University
 
602
 *  Copyright (c) 1989, 1990, 1992, William LeFebvre, Northwestern University
 
603
 */
 
604
 
 
605
/*
 
606
 *  percentages(cnt, out, new, old, diffs) - calculate percentage change
 
607
 *    between array "old" and "new", putting the percentages i "out".
 
608
 *    "cnt" is size of each array and "diffs" is used for scratch space.
 
609
 *    The array "old" is updated on each call.
 
610
 *    The routine assumes modulo arithmetic.  This function is especially
 
611
 *    useful on BSD mchines for calculating cpu state percentages.
 
612
 */
 
613
long percentages(int cnt, long *out, long *new, long *old, long *diffs)
 
614
{
 
615
    int i;
 
616
    long change;
 
617
    long total_change;
 
618
    long *dp;
 
619
    long half_total;
 
620
 
 
621
    /* initialization */
 
622
    total_change = 0;
 
623
    dp = diffs;
 
624
 
 
625
    /* calculate changes for each state and the overall change */
 
626
    for (i = 0; i < cnt; i++)
 
627
    {
 
628
    if ((change = *new - *old) < 0)
 
629
    {
 
630
        /* this only happens when the counter wraps */
 
631
        change = (int)
 
632
        ((unsigned long)*new-(unsigned long)*old);
 
633
    }
 
634
    total_change += (*dp++ = change);
 
635
    *old++ = *new++;
 
636
    }
 
637
 
 
638
    /* avoid divide by zero potential */
 
639
    if (total_change == 0)
 
640
    {
 
641
    total_change = 1;
 
642
    }
 
643
 
 
644
    /* calculate percentages based on overall change, rounding up */
 
645
    half_total = total_change / 2l;
 
646
 
 
647
    /* Do not divide by 0. Causes Floating point exception */
 
648
    for (i = 0; i < cnt; i++)
 
649
    {
 
650
    *out++ = (int)((*diffs++ * 1000 + half_total) / total_change);
 
651
    }
 
652
 
 
653
    /* return the total in case the caller wants to use it */
 
654
    return(total_change);
 
655
}