perfmonger 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +5 -13
  2. data/.gitignore +6 -0
  3. data/.tachikoma.yml +1 -0
  4. data/.travis.yml +18 -6
  5. data/Gemfile +1 -3
  6. data/Guardfile +26 -0
  7. data/NEWS +21 -0
  8. data/README.md +8 -9
  9. data/Rakefile +33 -1
  10. data/core/Makefile +23 -0
  11. data/core/build.sh +48 -0
  12. data/core/perfmonger-player.go +165 -0
  13. data/core/perfmonger-recorder.go +296 -0
  14. data/core/perfmonger-summarizer.go +207 -0
  15. data/core/subsystem/Makefile +3 -0
  16. data/core/subsystem/perfmonger.go +60 -0
  17. data/core/subsystem/perfmonger_darwin.go +22 -0
  18. data/core/subsystem/perfmonger_linux.go +292 -0
  19. data/core/subsystem/perfmonger_linux_test.go +73 -0
  20. data/core/subsystem/stat.go +214 -0
  21. data/core/subsystem/stat_test.go +281 -0
  22. data/core/subsystem/usage.go +410 -0
  23. data/core/subsystem/usage_test.go +496 -0
  24. data/lib/exec/operationBinding.rb.svn-base +59 -0
  25. data/lib/exec/perfmonger-player_darwin_amd64 +0 -0
  26. data/lib/exec/perfmonger-player_linux_386 +0 -0
  27. data/lib/exec/perfmonger-player_linux_amd64 +0 -0
  28. data/lib/exec/perfmonger-recorder_darwin_amd64 +0 -0
  29. data/lib/exec/perfmonger-recorder_linux_386 +0 -0
  30. data/lib/exec/perfmonger-recorder_linux_amd64 +0 -0
  31. data/lib/exec/perfmonger-summarizer_darwin_amd64 +0 -0
  32. data/lib/exec/perfmonger-summarizer_linux_386 +0 -0
  33. data/lib/exec/perfmonger-summarizer_linux_amd64 +0 -0
  34. data/lib/exec/perfmonger-summary_linux_386 +0 -0
  35. data/lib/exec/perfmonger-summary_linux_amd64 +0 -0
  36. data/lib/perfmonger/cli.rb +8 -3
  37. data/lib/perfmonger/command/core.rb +62 -0
  38. data/lib/perfmonger/command/live.rb +39 -0
  39. data/lib/perfmonger/command/play.rb +56 -0
  40. data/lib/perfmonger/command/plot.rb +30 -22
  41. data/lib/perfmonger/command/record.rb +3 -2
  42. data/lib/perfmonger/command/record_option.rb +40 -59
  43. data/lib/perfmonger/command/server.rb +7 -2
  44. data/lib/perfmonger/command/stat.rb +2 -2
  45. data/lib/perfmonger/command/stat_option.rb +1 -1
  46. data/lib/perfmonger/command/summary.rb +11 -326
  47. data/lib/perfmonger/version.rb +1 -3
  48. data/lib/perfmonger.rb +3 -0
  49. data/misc/_perfmonger +128 -0
  50. data/misc/perfmonger-completion.bash +49 -0
  51. data/perfmonger.gemspec +6 -5
  52. data/spec/data/busy100.pgr +0 -0
  53. data/spec/fingerprint_spec.rb +35 -0
  54. data/spec/live_spec.rb +25 -0
  55. data/spec/perfmonger_spec.rb +37 -0
  56. data/spec/play_spec.rb +21 -0
  57. data/spec/plot_spec.rb +42 -0
  58. data/spec/record_spec.rb +15 -0
  59. data/spec/spec_helper.rb +33 -0
  60. data/spec/stat_spec.rb +15 -0
  61. data/spec/summary_spec.rb +51 -0
  62. data/spec/support/aruba.rb +11 -0
  63. data/wercker.yml +59 -0
  64. metadata +117 -45
  65. data/ext/perfmonger/extconf.rb +0 -19
  66. data/ext/perfmonger/perfmonger.h +0 -58
  67. data/ext/perfmonger/perfmonger_record.c +0 -754
  68. data/ext/perfmonger/sysstat/common.c +0 -627
  69. data/ext/perfmonger/sysstat/common.h +0 -207
  70. data/ext/perfmonger/sysstat/ioconf.c +0 -515
  71. data/ext/perfmonger/sysstat/ioconf.h +0 -84
  72. data/ext/perfmonger/sysstat/iostat.c +0 -1100
  73. data/ext/perfmonger/sysstat/iostat.h +0 -121
  74. data/ext/perfmonger/sysstat/libsysstat.h +0 -19
  75. data/ext/perfmonger/sysstat/mpstat.c +0 -953
  76. data/ext/perfmonger/sysstat/mpstat.h +0 -79
  77. data/ext/perfmonger/sysstat/rd_stats.c +0 -2388
  78. data/ext/perfmonger/sysstat/rd_stats.h +0 -651
  79. data/ext/perfmonger/sysstat/sysconfig.h +0 -13
  80. data/test/run-test.sh +0 -39
  81. data/test/spec/bin_spec.rb +0 -37
  82. data/test/spec/data/2devices.expected +0 -42
  83. data/test/spec/data/2devices.output +0 -42
  84. data/test/spec/spec_helper.rb +0 -20
  85. data/test/spec/summary_spec.rb +0 -193
  86. data/test/test-perfmonger.c +0 -145
  87. data/test/test.h +0 -9
@@ -1,953 +0,0 @@
1
- /*
2
- * mpstat: per-processor statistics
3
- * (C) 2000-2010 by Sebastien GODARD (sysstat <at> orange.fr)
4
- *
5
- ***************************************************************************
6
- * This program is free software; you can redistribute it and/or modify it *
7
- * under the terms of the GNU General Public License as published by the *
8
- * Free Software Foundation; either version 2 of the License, or (at your *
9
- * option) any later version. *
10
- * *
11
- * This program is distributed in the hope that it will be useful, but *
12
- * WITHOUT ANY WARRANTY; without the implied warranty of MERCHANTABILITY *
13
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
14
- * for more details. *
15
- * *
16
- * You should have received a copy of the GNU General Public License along *
17
- * with this program; if not, write to the Free Software Foundation, Inc., *
18
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
19
- ***************************************************************************
20
- */
21
-
22
- #include <stdio.h>
23
- #include <string.h>
24
- #include <stdlib.h>
25
- #include <unistd.h>
26
- #include <signal.h>
27
- #include <errno.h>
28
- #include <ctype.h>
29
- #include <sys/utsname.h>
30
-
31
- #include "mpstat.h"
32
- #include "common.h"
33
- #include "rd_stats.h"
34
-
35
- #ifdef USE_NLS
36
- #include <locale.h>
37
- #include <libintl.h>
38
- #define _(string) gettext(string)
39
- #else
40
- #define _(string) (string)
41
- #endif
42
-
43
- unsigned long long uptime[3] = {0, 0, 0};
44
- unsigned long long uptime0[3] = {0, 0, 0};
45
-
46
- /* NOTE: Use array of _char_ for bitmaps to avoid endianness problems...*/
47
- unsigned char *cpu_bitmap; /* Bit 0: Global; Bit 1: 1st proc; etc. */
48
-
49
- /* Structures used to store stats */
50
- struct stats_cpu *st_cpu[3];
51
- struct stats_irq *st_irq[3];
52
- struct stats_irqcpu *st_irqcpu[3];
53
- struct stats_irqcpu *st_softirqcpu[3];
54
-
55
- struct tm mp_tstamp[3];
56
-
57
- /* Activity flag */
58
- unsigned int actflags = 0;
59
- // unsigned int flags = 0;
60
-
61
- /* Interval and count parameters */
62
- extern long interval;
63
- long count = 0;
64
-
65
- /* Nb of processors on the machine */
66
- extern int cpu_nr;
67
- /* Nb of interrupts per processor */
68
- int irqcpu_nr = 0;
69
- /* Nb of soft interrupts per processor */
70
- int softirqcpu_nr = 0;
71
-
72
- /*
73
- ***************************************************************************
74
- * Allocate stats structures and cpu bitmap.
75
- *
76
- * IN:
77
- * @nr_cpus Number of CPUs. This is the real number of available CPUs + 1
78
- * because we also have to allocate a structure for CPU 'all'.
79
- ***************************************************************************
80
- */
81
- void salloc_mp_struct(int nr_cpus)
82
- {
83
- int i;
84
-
85
- for (i = 0; i < 3; i++) {
86
-
87
- if ((st_cpu[i] = (struct stats_cpu *) malloc(STATS_CPU_SIZE * nr_cpus))
88
- == NULL) {
89
- perror("malloc");
90
- exit(4);
91
- }
92
- memset(st_cpu[i], 0, STATS_CPU_SIZE * nr_cpus);
93
-
94
- if ((st_irq[i] = (struct stats_irq *) malloc(STATS_IRQ_SIZE * nr_cpus))
95
- == NULL) {
96
- perror("malloc");
97
- exit(4);
98
- }
99
- memset(st_irq[i], 0, STATS_IRQ_SIZE * nr_cpus);
100
-
101
- if ((st_irqcpu[i] = (struct stats_irqcpu *) malloc(STATS_IRQCPU_SIZE * nr_cpus * irqcpu_nr))
102
- == NULL) {
103
- perror("malloc");
104
- exit(4);
105
- }
106
- memset(st_irqcpu[i], 0, STATS_IRQCPU_SIZE * nr_cpus * irqcpu_nr);
107
-
108
- if ((st_softirqcpu[i] = (struct stats_irqcpu *) malloc(STATS_IRQCPU_SIZE * nr_cpus * softirqcpu_nr))
109
- == NULL) {
110
- perror("malloc");
111
- exit(4);
112
- }
113
- memset(st_softirqcpu[i], 0, STATS_IRQCPU_SIZE * nr_cpus * softirqcpu_nr);
114
- }
115
-
116
- if ((cpu_bitmap = (unsigned char *) malloc((nr_cpus >> 3) + 1)) == NULL) {
117
- perror("malloc");
118
- exit(4);
119
- }
120
- memset(cpu_bitmap, 0, (nr_cpus >> 3) + 1);
121
- }
122
-
123
- /*
124
- ***************************************************************************
125
- * Free structures and bitmap.
126
- ***************************************************************************
127
- */
128
- void sfree_mp_struct(void)
129
- {
130
- int i;
131
-
132
- for (i = 0; i < 3; i++) {
133
-
134
- if (st_cpu[i]) {
135
- free(st_cpu[i]);
136
- }
137
- if (st_irq[i]) {
138
- free(st_irq[i]);
139
- }
140
- if (st_irqcpu[i]) {
141
- free(st_irqcpu[i]);
142
- }
143
- if (st_softirqcpu[i]) {
144
- free(st_softirqcpu[i]);
145
- }
146
- }
147
-
148
- if (cpu_bitmap) {
149
- free(cpu_bitmap);
150
- }
151
- }
152
-
153
- /*
154
- ***************************************************************************
155
- * Display per CPU statistics.
156
- *
157
- * IN:
158
- * @st_ic Array for per-CPU statistics.
159
- * @ic_nr Number of interrupts (hard or soft) per CPU.
160
- * @dis TRUE if a header line must be printed.
161
- * @itv Interval value.
162
- * @prev Position in array where statistics used as reference are.
163
- * Stats used as reference may be the previous ones read, or
164
- * the very first ones when calculating the average.
165
- * @curr Position in array where current statistics will be saved.
166
- * @prev_string String displayed at the beginning of a header line. This is
167
- * the timestamp of the previous sample, or "Average" when
168
- * displaying average stats.
169
- * @curr_string String displayed at the beginning of current sample stats.
170
- * This is the timestamp of the current sample, or "Average"
171
- * when displaying average stats.
172
- ***************************************************************************
173
- */
174
- /* void write_irqcpu_stats(struct stats_irqcpu *st_ic[], int ic_nr, int dis, */
175
- /* unsigned long long itv, int prev, int curr, */
176
- /* char *prev_string, char *curr_string) */
177
- /* { */
178
- /* int j = 0, offset, cpu; */
179
- /* struct stats_irqcpu *p, *q, *p0, *q0; */
180
-
181
- /* /\* */
182
- /* * Check if number of interrupts has changed. */
183
- /* * NB: A null interval value indicates that we are */
184
- /* * displaying statistics since system startup. */
185
- /* *\/ */
186
- /* if (!dis && interval) { */
187
- /* do { */
188
- /* p0 = st_ic[curr] + j; */
189
- /* if (p0->irq_name[0] != '\0') { */
190
- /* q0 = st_ic[prev] + j; */
191
- /* if (strcmp(p0->irq_name, q0->irq_name)) { */
192
- /* /\* These are two different irq *\/ */
193
- /* j = -2; */
194
- /* } */
195
- /* } */
196
- /* j++; */
197
- /* } */
198
- /* while ((j > 0) && (j <= ic_nr)); */
199
- /* } */
200
-
201
- /* if (dis || (j < 0)) { */
202
- /* /\* Print header *\/ */
203
- /* printf("\n%-11s CPU", prev_string); */
204
- /* for (j = 0; j < ic_nr; j++) { */
205
- /* p0 = st_ic[curr] + j; */
206
- /* if (p0->irq_name[0] != '\0') { /\* Nb of irq per proc may have varied... *\/ */
207
- /* printf(" %8s/s", p0->irq_name); */
208
- /* } */
209
- /* } */
210
- /* printf("\n"); */
211
- /* } */
212
-
213
- /* for (cpu = 1; cpu <= cpu_nr; cpu++) { */
214
-
215
- /* /\* */
216
- /* * Check if we want stats about this CPU. */
217
- /* * CPU must have been explicitly selected using option -P, */
218
- /* * else we display every CPU. */
219
- /* *\/ */
220
- /* if (!(*(cpu_bitmap + (cpu >> 3)) & (1 << (cpu & 0x07))) && USE_P_OPTION(flags)) */
221
- /* continue; */
222
-
223
- /* printf("%-11s %3d", curr_string, cpu - 1); */
224
-
225
- /* for (j = 0; j < ic_nr; j++) { */
226
- /* p0 = st_ic[curr] + j; /\* irq field set only for proc #0 *\/ */
227
- /* /\* */
228
- /* * An empty string for irq name means it is a remaining interrupt */
229
- /* * which is no longer used, for example because the */
230
- /* * number of interrupts has decreased in /proc/interrupts. */
231
- /* *\/ */
232
- /* if (p0->irq_name[0] != '\0') { */
233
- /* q0 = st_ic[prev] + j; */
234
- /* offset = j; */
235
-
236
- /* /\* */
237
- /* * If we want stats for the time since system startup, */
238
- /* * we have p0->irq != q0->irq, since q0 structure is */
239
- /* * completely set to zero. */
240
- /* *\/ */
241
- /* if (strcmp(p0->irq_name, q0->irq_name) && interval) { */
242
- /* if (j) */
243
- /* offset = j - 1; */
244
- /* q0 = st_ic[prev] + offset; */
245
- /* if (strcmp(p0->irq_name, q0->irq_name) && (j + 1 < ic_nr)) */
246
- /* offset = j + 1; */
247
- /* q0 = st_ic[prev] + offset; */
248
- /* } */
249
-
250
- /* if (!strcmp(p0->irq_name, q0->irq_name) || !interval) { */
251
- /* p = st_ic[curr] + (cpu - 1) * ic_nr + j; */
252
- /* q = st_ic[prev] + (cpu - 1) * ic_nr + offset; */
253
- /* printf(" %10.2f", */
254
- /* S_VALUE(q->interrupt, p->interrupt, itv)); */
255
- /* } */
256
- /* else */
257
- /* printf(" N/A"); */
258
- /* } */
259
- /* } */
260
- /* printf("\n"); */
261
- /* } */
262
- /* } */
263
-
264
- /*
265
- ***************************************************************************
266
- * Core function used to display statistics
267
- *
268
- * IN:
269
- * @prev Position in array where statistics used as reference are.
270
- * Stats used as reference may be the previous ones read, or
271
- * the very first ones when calculating the average.
272
- * @curr Position in array where statistics for current sample are.
273
- * @dis TRUE if a header line must be printed.
274
- * @prev_string String displayed at the beginning of a header line. This is
275
- * the timestamp of the previous sample, or "Average" when
276
- * displaying average stats.
277
- * @curr_string String displayed at the beginning of current sample stats.
278
- * This is the timestamp of the current sample, or "Average"
279
- * when displaying average stats.
280
- ***************************************************************************
281
- */
282
- /* void write_stats_core(int prev, int curr, int dis, */
283
- /* char *prev_string, char *curr_string) */
284
- /* { */
285
- /* struct stats_cpu *scc, *scp; */
286
- /* unsigned long long itv, pc_itv, g_itv; */
287
- /* int cpu; */
288
-
289
- /* /\* Test stdout *\/ */
290
- /* TEST_STDOUT(STDOUT_FILENO); */
291
-
292
- /* /\* Compute time interval *\/ */
293
- /* g_itv = get_interval(uptime[prev], uptime[curr]); */
294
-
295
- /* /\* Reduce interval value to one processor *\/ */
296
- /* if (cpu_nr > 1) { */
297
- /* itv = get_interval(uptime0[prev], uptime0[curr]); */
298
- /* } */
299
- /* else { */
300
- /* itv = g_itv; */
301
- /* } */
302
-
303
- /* /\* Print CPU stats *\/ */
304
- /* if (DISPLAY_CPU(actflags)) { */
305
- /* if (dis) { */
306
- /* printf("\n%-11s CPU %%usr %%nice %%sys %%iowait %%irq " */
307
- /* "%%soft %%steal %%guest %%idle\n", */
308
- /* prev_string); */
309
- /* } */
310
-
311
- /* /\* Check if we want global stats among all proc *\/ */
312
- /* if (*cpu_bitmap & 1) { */
313
-
314
- /* printf("%-11s all", curr_string); */
315
-
316
- /* printf(" %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f\n", */
317
- /* (st_cpu[curr]->cpu_user - st_cpu[curr]->cpu_guest) < */
318
- /* (st_cpu[prev]->cpu_user - st_cpu[prev]->cpu_guest) ? */
319
- /* 0.0 : */
320
- /* ll_sp_value(st_cpu[prev]->cpu_user - st_cpu[prev]->cpu_guest, */
321
- /* st_cpu[curr]->cpu_user - st_cpu[curr]->cpu_guest, */
322
- /* g_itv), */
323
- /* ll_sp_value(st_cpu[prev]->cpu_nice, */
324
- /* st_cpu[curr]->cpu_nice, */
325
- /* g_itv), */
326
- /* ll_sp_value(st_cpu[prev]->cpu_sys, */
327
- /* st_cpu[curr]->cpu_sys, */
328
- /* g_itv), */
329
- /* ll_sp_value(st_cpu[prev]->cpu_iowait, */
330
- /* st_cpu[curr]->cpu_iowait, */
331
- /* g_itv), */
332
- /* ll_sp_value(st_cpu[prev]->cpu_hardirq, */
333
- /* st_cpu[curr]->cpu_hardirq, */
334
- /* g_itv), */
335
- /* ll_sp_value(st_cpu[prev]->cpu_softirq, */
336
- /* st_cpu[curr]->cpu_softirq, */
337
- /* g_itv), */
338
- /* ll_sp_value(st_cpu[prev]->cpu_steal, */
339
- /* st_cpu[curr]->cpu_steal, */
340
- /* g_itv), */
341
- /* ll_sp_value(st_cpu[prev]->cpu_guest, */
342
- /* st_cpu[curr]->cpu_guest, */
343
- /* g_itv), */
344
- /* (st_cpu[curr]->cpu_idle < st_cpu[prev]->cpu_idle) ? */
345
- /* 0.0 : */
346
- /* ll_sp_value(st_cpu[prev]->cpu_idle, */
347
- /* st_cpu[curr]->cpu_idle, */
348
- /* g_itv)); */
349
- /* } */
350
-
351
- /* for (cpu = 1; cpu <= cpu_nr; cpu++) { */
352
-
353
- /* scc = st_cpu[curr] + cpu; */
354
- /* scp = st_cpu[prev] + cpu; */
355
-
356
- /* /\* Check if we want stats about this proc *\/ */
357
- /* if (!(*(cpu_bitmap + (cpu >> 3)) & (1 << (cpu & 0x07)))) */
358
- /* continue; */
359
-
360
- /* printf("%-11s %4d", curr_string, cpu - 1); */
361
-
362
- /* /\* */
363
- /* * If the CPU is offline then it is omited from /proc/stat */
364
- /* * and the sum of all values is zero. */
365
- /* * (Remember that guest time is already included in user mode.) */
366
- /* *\/ */
367
- /* if ((scc->cpu_user + scc->cpu_nice + scc->cpu_sys + */
368
- /* scc->cpu_iowait + scc->cpu_idle + scc->cpu_steal + */
369
- /* scc->cpu_hardirq + scc->cpu_softirq) == 0) { */
370
- /* /\* */
371
- /* * Set current struct fields (which have been set to zero) */
372
- /* * to values from previous iteration. Hence their values won't */
373
- /* * jump from zero when the CPU comes back online. */
374
- /* *\/ */
375
- /* *scc = *scp; */
376
-
377
- /* printf(" %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f" */
378
- /* " %6.2f %6.2f %6.2f\n", */
379
- /* 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); */
380
- /* continue; */
381
- /* } */
382
-
383
- /* /\* Recalculate itv for current proc *\/ */
384
- /* pc_itv = get_per_cpu_interval(scc, scp); */
385
-
386
- /* if (!pc_itv) { */
387
- /* /\* */
388
- /* * If the CPU is tickless then there is no change in CPU values */
389
- /* * but the sum of values is not zero. */
390
- /* *\/ */
391
- /* printf(" %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f" */
392
- /* " %6.2f %6.2f %6.2f\n", */
393
- /* 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 100.0); */
394
- /* } */
395
-
396
- /* else { */
397
- /* printf(" %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f" */
398
- /* " %6.2f %6.2f %6.2f\n", */
399
- /* (scc->cpu_user - scc->cpu_guest) < (scp->cpu_user - scp->cpu_guest) ? */
400
- /* 0.0 : */
401
- /* ll_sp_value(scp->cpu_user - scp->cpu_guest, */
402
- /* scc->cpu_user - scc->cpu_guest, */
403
- /* pc_itv), */
404
- /* ll_sp_value(scp->cpu_nice, */
405
- /* scc->cpu_nice, */
406
- /* pc_itv), */
407
- /* ll_sp_value(scp->cpu_sys, */
408
- /* scc->cpu_sys, */
409
- /* pc_itv), */
410
- /* ll_sp_value(scp->cpu_iowait, */
411
- /* scc->cpu_iowait, */
412
- /* pc_itv), */
413
- /* ll_sp_value(scp->cpu_hardirq, */
414
- /* scc->cpu_hardirq, */
415
- /* pc_itv), */
416
- /* ll_sp_value(scp->cpu_softirq, */
417
- /* scc->cpu_softirq, */
418
- /* pc_itv), */
419
- /* ll_sp_value(scp->cpu_steal, */
420
- /* scc->cpu_steal, */
421
- /* pc_itv), */
422
- /* ll_sp_value(scp->cpu_guest, */
423
- /* scc->cpu_guest, */
424
- /* pc_itv), */
425
- /* (scc->cpu_idle < scp->cpu_idle) ? */
426
- /* 0.0 : */
427
- /* ll_sp_value(scp->cpu_idle, */
428
- /* scc->cpu_idle, */
429
- /* pc_itv)); */
430
- /* } */
431
- /* } */
432
- /* } */
433
-
434
- /* /\* Print total number of interrupts per processor *\/ */
435
- /* if (DISPLAY_IRQ_SUM(actflags)) { */
436
- /* struct stats_irq *sic, *sip; */
437
-
438
- /* if (dis) { */
439
- /* printf("\n%-11s CPU intr/s\n", prev_string); */
440
- /* } */
441
-
442
- /* if (*cpu_bitmap & 1) { */
443
- /* printf("%-11s all %9.2f\n", curr_string, */
444
- /* ll_s_value(st_irq[prev]->irq_nr, st_irq[curr]->irq_nr, itv)); */
445
- /* } */
446
-
447
- /* for (cpu = 1; cpu <= cpu_nr; cpu++) { */
448
-
449
- /* sic = st_irq[curr] + cpu; */
450
- /* sip = st_irq[prev] + cpu; */
451
-
452
- /* scc = st_cpu[curr] + cpu; */
453
- /* scp = st_cpu[prev] + cpu; */
454
-
455
- /* /\* Check if we want stats about this proc *\/ */
456
- /* if (!(*(cpu_bitmap + (cpu >> 3)) & (1 << (cpu & 0x07)))) */
457
- /* continue; */
458
-
459
- /* printf("%-11s %4d", curr_string, cpu - 1); */
460
-
461
- /* /\* Recalculate itv for current proc *\/ */
462
- /* pc_itv = get_per_cpu_interval(scc, scp); */
463
-
464
- /* if (!pc_itv) { */
465
- /* /\* Current CPU is offline *\/ */
466
- /* printf(" %9.2f\n", 0.0); */
467
- /* } */
468
- /* else { */
469
- /* printf(" %9.2f\n", */
470
- /* ll_s_value(sip->irq_nr, sic->irq_nr, itv)); */
471
- /* } */
472
- /* } */
473
- /* } */
474
-
475
- /* if (DISPLAY_IRQ_CPU(actflags)) { */
476
- /* write_irqcpu_stats(st_irqcpu, irqcpu_nr, dis, itv, prev, curr, */
477
- /* prev_string, curr_string); */
478
- /* } */
479
-
480
- /* if (DISPLAY_SOFTIRQS(actflags)) { */
481
- /* write_irqcpu_stats(st_softirqcpu, softirqcpu_nr, dis, itv, prev, curr, */
482
- /* prev_string, curr_string); */
483
- /* } */
484
- /* } */
485
-
486
- /*
487
- ***************************************************************************
488
- * Print statistics average
489
- *
490
- * IN:
491
- * @curr Position in array where statistics for current sample are.
492
- * @dis TRUE if a header line must be printed.
493
- ***************************************************************************
494
- */
495
- /* void write_stats_avg(int curr, int dis) */
496
- /* { */
497
- /* char string[16]; */
498
-
499
- /* strncpy(string, _("Average:"), 16); */
500
- /* string[15] = '\0'; */
501
- /* write_stats_core(2, curr, dis, string, string); */
502
- /* } */
503
-
504
- /*
505
- ***************************************************************************
506
- * Print statistics
507
- *
508
- * IN:
509
- * @curr Position in array where statistics for current sample are.
510
- * @dis TRUE if a header line must be printed.
511
- ***************************************************************************
512
- */
513
- /* void write_stats(int curr, int dis) */
514
- /* { */
515
- /* char cur_time[2][16]; */
516
-
517
- /* /\* Get previous timestamp *\/ */
518
- /* strftime(cur_time[!curr], 16, "%X", &(mp_tstamp[!curr])); */
519
-
520
- /* /\* Get current timestamp *\/ */
521
- /* strftime(cur_time[curr], 16, "%X", &(mp_tstamp[curr])); */
522
-
523
- /* write_stats_core(!curr, curr, dis, cur_time[!curr], cur_time[curr]); */
524
- /* } */
525
-
526
- /*
527
- ***************************************************************************
528
- * Read stats from /proc/interrupts or /proc/softirqs.
529
- *
530
- * IN:
531
- * @file /proc file to read (interrupts or softirqs).
532
- * @ic_nr Number of interrupts (hard or soft) per CPU.
533
- * @curr Position in array where current statistics will be saved.
534
- *
535
- * OUT:
536
- * @st_ic Array for per-CPU statistics.
537
- ***************************************************************************
538
- */
539
- void read_interrupts_stat(char *file, struct stats_irqcpu *st_ic[], int ic_nr, int curr)
540
- {
541
- FILE *fp;
542
- struct stats_irq *st_irq_i;
543
- struct stats_irqcpu *p;
544
- char *line = NULL;
545
- unsigned long irq = 0;
546
- unsigned int cpu;
547
- int cpu_index[cpu_nr], index = 0, dgt, len;
548
- char *cp, *next;
549
-
550
- for (cpu = 0; cpu < cpu_nr; cpu++) {
551
- st_irq_i = st_irq[curr] + cpu + 1;
552
- st_irq_i->irq_nr = 0;
553
- }
554
-
555
- if ((fp = fopen(file, "r")) != NULL) {
556
-
557
- SREALLOC(line, char, INTERRUPTS_LINE + 11 * cpu_nr);
558
-
559
- /*
560
- * Parse header line to see which CPUs are online
561
- */
562
- while (fgets(line, INTERRUPTS_LINE + 11 * cpu_nr, fp) != NULL) {
563
- next = line;
564
- while (((cp = strstr(next, "CPU")) != NULL) && (index < cpu_nr)) {
565
- cpu = strtol(cp + 3, &next, 10);
566
- cpu_index[index++] = cpu;
567
- }
568
- if (index)
569
- /* Header line found */
570
- break;
571
- }
572
-
573
- while ((fgets(line, INTERRUPTS_LINE + 11 * cpu_nr, fp) != NULL) &&
574
- (irq < ic_nr)) {
575
-
576
- /* Skip over "<irq>:" */
577
- if ((cp = strchr(line, ':')) == NULL)
578
- continue;
579
- cp++;
580
-
581
- p = st_ic[curr] + irq;
582
- len = strcspn(line, ":");
583
- if (len >= MAX_IRQ_LEN) {
584
- len = MAX_IRQ_LEN - 1;
585
- }
586
- strncpy(p->irq_name, line, len);
587
- p->irq_name[len] = '\0';
588
- dgt = isdigit(line[len - 1]);
589
-
590
- for (cpu = 0; cpu < index; cpu++) {
591
- p = st_ic[curr] + cpu_index[cpu] * ic_nr + irq;
592
- st_irq_i = st_irq[curr] + cpu_index[cpu] + 1;
593
- /*
594
- * No need to set (st_irqcpu + cpu * irqcpu_nr)->irq:
595
- * This is the same as st_irqcpu->irq.
596
- */
597
- p->interrupt = strtoul(cp, &next, 10);
598
- if (dgt) {
599
- /* Sum only numerical irq (and not NMI, LOC, etc.) */
600
- st_irq_i->irq_nr += p->interrupt;
601
- }
602
- cp = next;
603
- }
604
- irq++;
605
- }
606
-
607
- fclose(fp);
608
-
609
- if (line) {
610
- free(line);
611
- }
612
- }
613
-
614
- while (irq < ic_nr) {
615
- /* Nb of interrupts per processor has changed */
616
- p = st_ic[curr] + irq;
617
- p->irq_name[0] = '\0'; /* This value means this is a dummy interrupt */
618
- irq++;
619
- }
620
- }
621
-
622
- /*
623
- ***************************************************************************
624
- * Main loop: Read stats from the relevant sources, and display them.
625
- *
626
- * IN:
627
- * @dis_hdr Set to TRUE if the header line must always be printed.
628
- * @rows Number of rows of screen.
629
- ***************************************************************************
630
- */
631
- void rw_mpstat_loop(int dis_hdr, int rows)
632
- {
633
- struct stats_cpu *scc;
634
- int cpu;
635
- int curr = 1, dis = 1;
636
- unsigned long lines = rows;
637
-
638
- /* Dont buffer data if redirected to a pipe */
639
- setbuf(stdout, NULL);
640
-
641
- /* Read stats */
642
- if (cpu_nr > 1) {
643
- /*
644
- * Init uptime0. So if /proc/uptime cannot fill it,
645
- * this will be done by /proc/stat.
646
- */
647
- uptime0[0] = 0;
648
- read_uptime(&(uptime0[0]));
649
- }
650
- read_stat_cpu(st_cpu[0], cpu_nr + 1, &(uptime[0]), &(uptime0[0]));
651
-
652
- if (DISPLAY_IRQ_SUM(actflags)) {
653
- read_stat_irq(st_irq[0], 1);
654
- }
655
-
656
- if (DISPLAY_IRQ_SUM(actflags) || DISPLAY_IRQ_CPU(actflags)) {
657
- /* Read this file to display int per CPU or total nr of int per CPU */
658
- read_interrupts_stat(INTERRUPTS, st_irqcpu, irqcpu_nr, 0);
659
- }
660
-
661
- if (DISPLAY_SOFTIRQS(actflags)) {
662
- read_interrupts_stat(SOFTIRQS, st_softirqcpu, softirqcpu_nr, 0);
663
- }
664
-
665
- if (!interval) {
666
- /* Display since boot time */
667
- mp_tstamp[1] = mp_tstamp[0];
668
- memset(st_cpu[1], 0, STATS_CPU_SIZE * (cpu_nr + 1));
669
- memset(st_irq[1], 0, STATS_IRQ_SIZE * (cpu_nr + 1));
670
- memset(st_irqcpu[1], 0, STATS_IRQCPU_SIZE * (cpu_nr + 1) * irqcpu_nr);
671
- if (DISPLAY_SOFTIRQS(actflags)) {
672
- memset(st_softirqcpu[1], 0, STATS_IRQCPU_SIZE * (cpu_nr + 1) * softirqcpu_nr);
673
- }
674
- /* write_stats(0, DISP_HDR); */
675
- exit(0);
676
- }
677
-
678
- /* Set a handler for SIGALRM */
679
- /* alarm_handler(0); */
680
-
681
- /* Save the first stats collected. Will be used to compute the average */
682
- mp_tstamp[2] = mp_tstamp[0];
683
- uptime[2] = uptime[0];
684
- uptime0[2] = uptime0[0];
685
- memcpy(st_cpu[2], st_cpu[0], STATS_CPU_SIZE * (cpu_nr + 1));
686
- memcpy(st_irq[2], st_irq[0], STATS_IRQ_SIZE * (cpu_nr + 1));
687
- memcpy(st_irqcpu[2], st_irqcpu[0], STATS_IRQCPU_SIZE * (cpu_nr + 1) * irqcpu_nr);
688
- if (DISPLAY_SOFTIRQS(actflags)) {
689
- memcpy(st_softirqcpu[2], st_softirqcpu[0],
690
- STATS_IRQCPU_SIZE * (cpu_nr + 1) * softirqcpu_nr);
691
- }
692
-
693
- pause();
694
-
695
- do {
696
- /*
697
- * Resetting the structure not needed since every fields will be set.
698
- * Exceptions are per-CPU structures: Some of them may not be filled
699
- * if corresponding processor is disabled (offline). We set them to zero
700
- * to be able to distinguish between offline and tickless CPUs.
701
- */
702
- for (cpu = 1; cpu <= cpu_nr; cpu++) {
703
- scc = st_cpu[curr] + cpu;
704
- memset(scc, 0, STATS_CPU_SIZE);
705
- }
706
-
707
- /* Get time */
708
- get_localtime(&(mp_tstamp[curr]));
709
-
710
- /* Read stats */
711
- if (cpu_nr > 1) {
712
- uptime0[curr] = 0;
713
- read_uptime(&(uptime0[curr]));
714
- }
715
- read_stat_cpu(st_cpu[curr], cpu_nr + 1, &(uptime[curr]), &(uptime0[curr]));
716
-
717
- if (DISPLAY_IRQ_SUM(actflags)) {
718
- read_stat_irq(st_irq[curr], 1);
719
- }
720
-
721
- if (DISPLAY_IRQ_SUM(actflags) || DISPLAY_IRQ_CPU(actflags)) {
722
- read_interrupts_stat(INTERRUPTS, st_irqcpu, irqcpu_nr, curr);
723
- }
724
-
725
- if (DISPLAY_SOFTIRQS(actflags)) {
726
- read_interrupts_stat(SOFTIRQS, st_softirqcpu, softirqcpu_nr, curr);
727
- }
728
-
729
- /* Write stats */
730
- if (!dis_hdr) {
731
- dis = lines / rows;
732
- if (dis) {
733
- lines %= rows;
734
- }
735
- lines++;
736
- }
737
- /* write_stats(curr, dis); */
738
-
739
- if (count > 0) {
740
- count--;
741
- }
742
- if (count) {
743
- curr ^= 1;
744
- pause();
745
- }
746
- }
747
- while (count);
748
-
749
- /* Write stats average */
750
- /* write_stats_avg(curr, dis_hdr); */
751
- }
752
-
753
- /*
754
- ***************************************************************************
755
- * Main entry to the program
756
- ***************************************************************************
757
- */
758
- /* int main(int argc, char **argv) */
759
- /* { */
760
- /* int opt = 0, i, actset = FALSE; */
761
- /* struct utsname header; */
762
- /* int dis_hdr = -1; */
763
- /* int rows = 23; */
764
- /* char *t; */
765
-
766
- /* #ifdef USE_NLS */
767
- /* /\* Init National Language Support *\/ */
768
- /* init_nls(); */
769
- /* #endif */
770
-
771
- /* /\* Get HZ *\/ */
772
- /* get_HZ(); */
773
-
774
- /* /\* How many processors on this machine ? *\/ */
775
- /* cpu_nr = get_cpu_nr(~0); */
776
-
777
- /* /\* Calculate number of interrupts per processor *\/ */
778
- /* irqcpu_nr = get_irqcpu_nr(INTERRUPTS, NR_IRQS, cpu_nr) + */
779
- /* NR_IRQCPU_PREALLOC; */
780
- /* /\* Calculate number of soft interrupts per processor *\/ */
781
- /* softirqcpu_nr = get_irqcpu_nr(SOFTIRQS, NR_IRQS, cpu_nr) + */
782
- /* NR_IRQCPU_PREALLOC; */
783
-
784
- /* /\* */
785
- /* * cpu_nr: a value of 2 means there are 2 processors (0 and 1). */
786
- /* * In this case, we have to allocate 3 structures: global, proc0 and proc1. */
787
- /* *\/ */
788
- /* salloc_mp_struct(cpu_nr + 1); */
789
-
790
- /* while (++opt < argc) { */
791
-
792
- /* if (!strcmp(argv[opt], "-I")) { */
793
- /* if (argv[++opt]) { */
794
- /* actset = TRUE; */
795
- /* if (!strcmp(argv[opt], K_SUM)) { */
796
- /* /\* Display total number of interrupts per CPU *\/ */
797
- /* actflags |= M_D_IRQ_SUM; */
798
- /* } */
799
- /* else if (!strcmp(argv[opt], K_CPU)) { */
800
- /* /\* Display interrupts per CPU *\/ */
801
- /* actflags |= M_D_IRQ_CPU; */
802
- /* } */
803
- /* else if (!strcmp(argv[opt], K_SCPU)) { */
804
- /* /\* Display soft interrupts per CPU *\/ */
805
- /* actflags |= M_D_SOFTIRQS; */
806
- /* } */
807
- /* else if (!strcmp(argv[opt], K_ALL)) { */
808
- /* actflags |= M_D_IRQ_SUM + M_D_IRQ_CPU + M_D_SOFTIRQS; */
809
- /* } */
810
- /* else { */
811
- /* usage(argv[0]); */
812
- /* } */
813
- /* } */
814
- /* else { */
815
- /* usage(argv[0]); */
816
- /* } */
817
- /* } */
818
-
819
- /* else if (!strcmp(argv[opt], "-P")) { */
820
- /* /\* '-P ALL' can be used on UP machines *\/ */
821
- /* if (argv[++opt]) { */
822
- /* flags |= F_P_OPTION; */
823
- /* dis_hdr++; */
824
-
825
- /* for (t = strtok(argv[opt], ","); t; t = strtok(NULL, ",")) { */
826
- /* if (!strcmp(t, K_ALL)) { */
827
- /* if (cpu_nr) { */
828
- /* dis_hdr = 9; */
829
- /* } */
830
- /* /\* */
831
- /* * Set bit for every processor. */
832
- /* * Also indicate to display stats for CPU 'all'. */
833
- /* *\/ */
834
- /* memset(cpu_bitmap, 0xff, ((cpu_nr + 1) >> 3) + 1); */
835
- /* } */
836
- /* else { */
837
- /* if (strspn(t, DIGITS) != strlen(t)) { */
838
- /* usage(argv[0]); */
839
- /* } */
840
- /* i = atoi(t); /\* Get cpu number *\/ */
841
- /* if (i >= cpu_nr) { */
842
- /* fprintf(stderr, _("Not that many processors!\n")); */
843
- /* exit(1); */
844
- /* } */
845
- /* i++; */
846
- /* *(cpu_bitmap + (i >> 3)) |= 1 << (i & 0x07); */
847
- /* } */
848
- /* } */
849
- /* } */
850
- /* else { */
851
- /* usage(argv[0]); */
852
- /* } */
853
- /* } */
854
-
855
- /* else if (!strncmp(argv[opt], "-", 1)) { */
856
- /* for (i = 1; *(argv[opt] + i); i++) { */
857
-
858
- /* switch (*(argv[opt] + i)) { */
859
-
860
- /* case 'A': */
861
- /* actflags |= M_D_CPU + M_D_IRQ_SUM + M_D_IRQ_CPU + M_D_SOFTIRQS; */
862
- /* actset = TRUE; */
863
- /* /\* Select all processors *\/ */
864
- /* flags |= F_P_OPTION; */
865
- /* memset(cpu_bitmap, 0xff, ((cpu_nr + 1) >> 3) + 1); */
866
- /* break; */
867
-
868
- /* case 'u': */
869
- /* /\* Display CPU *\/ */
870
- /* actflags |= M_D_CPU; */
871
- /* break; */
872
-
873
- /* case 'V': */
874
- /* /\* Print version number *\/ */
875
- /* print_version(); */
876
- /* break; */
877
-
878
- /* default: */
879
- /* usage(argv[0]); */
880
- /* } */
881
- /* } */
882
- /* } */
883
-
884
- /* else if (interval < 0) { */
885
- /* /\* Get interval *\/ */
886
- /* if (strspn(argv[opt], DIGITS) != strlen(argv[opt])) { */
887
- /* usage(argv[0]); */
888
- /* } */
889
- /* interval = atol(argv[opt]); */
890
- /* if (interval < 0) { */
891
- /* usage(argv[0]); */
892
- /* } */
893
- /* count = -1; */
894
- /* } */
895
-
896
- /* else if (count <= 0) { */
897
- /* /\* Get count value *\/ */
898
- /* if ((strspn(argv[opt], DIGITS) != strlen(argv[opt])) || */
899
- /* !interval) { */
900
- /* usage(argv[0]); */
901
- /* } */
902
- /* count = atol(argv[opt]); */
903
- /* if (count < 1) { */
904
- /* usage(argv[0]); */
905
- /* } */
906
- /* } */
907
-
908
- /* else { */
909
- /* usage(argv[0]); */
910
- /* } */
911
- /* } */
912
-
913
- /* /\* Default: Display CPU *\/ */
914
- /* if (!actset) { */
915
- /* actflags |= M_D_CPU; */
916
- /* } */
917
-
918
- /* if (count_bits(&actflags, sizeof(unsigned int)) > 1) { */
919
- /* dis_hdr = 9; */
920
- /* } */
921
-
922
- /* if (!USE_P_OPTION(flags)) { */
923
- /* /\* Option -P not used: Set bit 0 (global stats among all proc) *\/ */
924
- /* *cpu_bitmap = 1; */
925
- /* } */
926
- /* if (dis_hdr < 0) { */
927
- /* dis_hdr = 0; */
928
- /* } */
929
- /* if (!dis_hdr) { */
930
- /* /\* Get window size *\/ */
931
- /* rows = get_win_height(); */
932
- /* } */
933
- /* if (interval < 0) { */
934
- /* /\* Interval not set => display stats since boot time *\/ */
935
- /* interval = 0; */
936
- /* } */
937
-
938
- /* /\* Get time *\/ */
939
- /* get_localtime(&(mp_tstamp[0])); */
940
-
941
- /* /\* Get system name, release number and hostname *\/ */
942
- /* uname(&header); */
943
- /* print_gal_header(&(mp_tstamp[0]), header.sysname, header.release, */
944
- /* header.nodename, header.machine, cpu_nr); */
945
-
946
- /* /\* Main loop *\/ */
947
- /* rw_mpstat_loop(dis_hdr, rows); */
948
-
949
- /* /\* Free structures *\/ */
950
- /* sfree_mp_struct(); */
951
-
952
- /* return 0; */
953
- /* } */