]> granicus.if.org Git - sysstat/blob - pr_stats.c
sar/sadf: Check for possible division by zero
[sysstat] / pr_stats.c
1 /*
2  * pr_stats.c: Functions used by sar to display statistics
3  * (C) 1999-2018 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  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA              *
19  ***************************************************************************
20  */
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdarg.h>
25 #include <stdlib.h>
26
27 #include "sa.h"
28 #include "ioconf.h"
29 #include "pr_stats.h"
30
31 #ifdef USE_NLS
32 #include <locale.h>
33 #include <libintl.h>
34 #define _(string) gettext(string)
35 #else
36 #define _(string) (string)
37 #endif
38
39 extern unsigned int flags;
40 extern unsigned int dm_major;
41 extern int  dis;
42 extern char timestamp[][TIMESTAMP_LEN];
43 extern unsigned long avg_count;
44
45
46 /*
47  ***************************************************************************
48  * Display current activity header line.
49  *
50  * IN:
51  * @timestamp   Timestamp for previous stat sample.
52  * @a           Activity structure.
53  * @pos         Index in @.hdr_line string, 0 being the first one (header
54  *              are delimited by the '|' character).
55  * @iwidth      First column width (generally this is the item name). A
56  *              negative value means that the corresponding field shall be
57  *              displayed at the end of the line, with no indication of width.
58  * @vwidth      Column width for stats values.
59  ***************************************************************************
60  */
61 void print_hdr_line(char *timestamp, struct activity *a, int pos, int iwidth, int vwidth)
62 {
63         char hline[HEADER_LINE_LEN] = "";
64         char *hl, *tk, *it = NULL;
65         int i = -1, j;
66         int p = pos;
67
68         strncpy(hline, a->hdr_line, HEADER_LINE_LEN - 1);
69         hline[HEADER_LINE_LEN - 1] = '\0';
70         for (hl = strtok(hline, "|"); hl && (pos > 0); hl = strtok(NULL, "|"), pos--);
71         if (!hl)
72                 /* Bad @pos arg given to function */
73                 return;
74
75         printf("\n%-11s", timestamp);
76
77         if (strchr(hl, '&')) {
78                 j = strcspn(hl, "&");
79                 if ((a->opt_flags & 0xff00) & (1 << (8 + p))) {
80                         /* Display whole header line */
81                         *(hl + j) = ';';
82                 }
83                 else {
84                         /* Display only the first part of the header line */
85                         *(hl + j) = '\0';
86                 }
87         }
88         /* Display each field */
89         for (tk = strtok(hl, ";"); tk; tk = strtok(NULL, ";"), i--) {
90                 if (iwidth > 0) {
91                         printf(" %*s", iwidth, tk);
92                         iwidth = 0;
93                         continue;
94                 }
95                 if ((iwidth < 0) && (iwidth == i)) {
96                         it = tk;
97                         iwidth = 0;
98                 }
99                 else {
100                         printf(" %*s", vwidth, tk);
101                 }
102         }
103         if (it) {
104                 printf(" %s", it);
105         }
106         printf("\n");
107 }
108
109 /*
110  ***************************************************************************
111  * Display CPU statistics.
112  * NB: The stats are only calculated over the part of the time interval when
113  * the CPU was online. As a consequence, the sum (%user + %nice + ... + %idle)
114  * will always be 100% on the time interval even if the CPU has been offline
115  * most of the time.
116  *
117  * IN:
118  * @a           Activity structure with statistics.
119  * @prev        Index in array where stats used as reference are.
120  * @curr        Index in array for current sample statistics.
121  * @itv         Interval of time in 1/100th of a second (independent of the
122  *              number of processors). Unused here.
123  ***************************************************************************
124  */
125 __print_funct_t print_cpu_stats(struct activity *a, int prev, int curr,
126                                 unsigned long long itv)
127 {
128         int i;
129         unsigned long long deltot_jiffies = 1;
130         struct stats_cpu *scc, *scp;
131         unsigned char offline_cpu_bitmap[BITMAP_SIZE(NR_CPUS)] = {0};
132
133         if (dis) {
134                 print_hdr_line(timestamp[!curr], a, FIRST + DISPLAY_CPU_ALL(a->opt_flags), 7, 9);
135         }
136
137         /*
138          * @nr[curr] cannot normally be greater than @nr_ini
139          * (since @nr_ini counts up all CPU, even those offline).
140          * If this happens, it may be because the machine has been
141          * restarted with more CPU and no LINUX_RESTART has been
142          * inserted in file.
143          * No problem here with @nr_allocated. Having been able to
144          * read @nr[curr] structures shows that buffers are large enough.
145          */
146         if (a->nr[curr] > a->nr_ini) {
147                 a->nr_ini = a->nr[curr];
148         }
149
150         /*
151          * Compute CPU "all" as sum of all individual CPU (on SMP machines)
152          * and look for offline CPU.
153          */
154         if (a->nr_ini > 1) {
155                 deltot_jiffies = get_global_cpu_statistics(a, prev, curr,
156                                                            flags, offline_cpu_bitmap);
157         }
158
159         /*
160          * Now display CPU statistics (including CPU "all"),
161          * except for offline CPU or CPU that the user doesn't want to see.
162          */
163         for (i = 0; (i < a->nr_ini) && (i < a->bitmap->b_size + 1); i++) {
164
165                 /*
166                  * Should current CPU (including CPU "all") be displayed?
167                  * Note: @nr[curr] is in [1, NR_CPUS + 1].
168                  * Bitmap size is provided for (NR_CPUS + 1) CPUs.
169                  * Anyway, NR_CPUS may vary between the version of sysstat
170                  * used by sadc to create a file, and the version of sysstat
171                  * used by sar to read it...
172                  */
173                 if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))) ||
174                     offline_cpu_bitmap[i >> 3] & (1 << (i & 0x07)))
175                         /* Don't display CPU */
176                         continue;
177
178                 scc = (struct stats_cpu *) ((char *) a->buf[curr] + i * a->msize);
179                 scp = (struct stats_cpu *) ((char *) a->buf[prev] + i * a->msize);
180
181                 printf("%-11s", timestamp[curr]);
182
183                 if (i == 0) {
184                         /* This is CPU "all" */
185                         cprintf_in(IS_STR, " %s", "    all", 0);
186
187                         if (a->nr_ini == 1) {
188                                 /*
189                                  * This is a UP machine. In this case
190                                  * interval has still not been calculated.
191                                  */
192                                 deltot_jiffies = get_per_cpu_interval(scc, scp);
193                         }
194                         if (!deltot_jiffies) {
195                                 /* CPU "all" cannot be tickless */
196                                 deltot_jiffies = 1;
197                         }
198                 }
199                 else {
200                         cprintf_in(IS_INT, " %7d", "", i - 1);
201
202                         /* Recalculate interval for current proc */
203                         deltot_jiffies = get_per_cpu_interval(scc, scp);
204
205                         if (!deltot_jiffies) {
206                                 /*
207                                  * If the CPU is tickless then there is no change in CPU values
208                                  * but the sum of values is not zero.
209                                  * %user, %nice, %system, %iowait, %steal, ..., %idle
210                                  */
211                                 cprintf_pc(DISPLAY_UNIT(flags), 5, 9, 2,
212                                            0.0, 0.0, 0.0, 0.0, 0.0);
213
214                                 if (DISPLAY_CPU_DEF(a->opt_flags)) {
215                                         cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2, 100.0);
216                                         printf("\n");
217                                 }
218                                 /*
219                                  * Four additional fields to display:
220                                  * %irq, %soft, %guest, %gnice.
221                                  */
222                                 else if (DISPLAY_CPU_ALL(a->opt_flags)) {
223                                         cprintf_pc(DISPLAY_UNIT(flags), 4, 9, 2,
224                                                    0.0, 0.0, 0.0, 100.0);
225                                         printf("\n");
226                                 }
227                                 continue;
228                         }
229                 }
230
231                 if (DISPLAY_CPU_DEF(a->opt_flags)) {
232                         cprintf_pc(DISPLAY_UNIT(flags), 6, 9, 2,
233                                    ll_sp_value(scp->cpu_user, scc->cpu_user, deltot_jiffies),
234                                    ll_sp_value(scp->cpu_nice, scc->cpu_nice, deltot_jiffies),
235                                    ll_sp_value(scp->cpu_sys + scp->cpu_hardirq + scp->cpu_softirq,
236                                                scc->cpu_sys + scc->cpu_hardirq + scc->cpu_softirq,
237                                                deltot_jiffies),
238                                    ll_sp_value(scp->cpu_iowait, scc->cpu_iowait, deltot_jiffies),
239                                    ll_sp_value(scp->cpu_steal, scc->cpu_steal, deltot_jiffies),
240                                    scc->cpu_idle < scp->cpu_idle ?
241                                    0.0 :
242                                    ll_sp_value(scp->cpu_idle, scc->cpu_idle, deltot_jiffies));
243                         printf("\n");
244                 }
245                 else if (DISPLAY_CPU_ALL(a->opt_flags)) {
246                         cprintf_pc(DISPLAY_UNIT(flags), 10, 9, 2,
247                                    (scc->cpu_user - scc->cpu_guest) < (scp->cpu_user - scp->cpu_guest) ?
248                                    0.0 :
249                                    ll_sp_value(scp->cpu_user - scp->cpu_guest,
250                                                scc->cpu_user - scc->cpu_guest, deltot_jiffies),
251                                                (scc->cpu_nice - scc->cpu_guest_nice) < (scp->cpu_nice - scp->cpu_guest_nice) ?
252                                    0.0 :
253                                    ll_sp_value(scp->cpu_nice - scp->cpu_guest_nice,
254                                                scc->cpu_nice - scc->cpu_guest_nice, deltot_jiffies),
255                                    ll_sp_value(scp->cpu_sys, scc->cpu_sys, deltot_jiffies),
256                                    ll_sp_value(scp->cpu_iowait, scc->cpu_iowait, deltot_jiffies),
257                                    ll_sp_value(scp->cpu_steal, scc->cpu_steal, deltot_jiffies),
258                                    ll_sp_value(scp->cpu_hardirq, scc->cpu_hardirq, deltot_jiffies),
259                                    ll_sp_value(scp->cpu_softirq, scc->cpu_softirq, deltot_jiffies),
260                                    ll_sp_value(scp->cpu_guest, scc->cpu_guest, deltot_jiffies),
261                                    ll_sp_value(scp->cpu_guest_nice, scc->cpu_guest_nice, deltot_jiffies),
262                                    scc->cpu_idle < scp->cpu_idle ?
263                                    0.0 :
264                                    ll_sp_value(scp->cpu_idle, scc->cpu_idle, deltot_jiffies));
265                         printf("\n");
266                 }
267         }
268 }
269
270 /*
271  ***************************************************************************
272  * Display tasks creation and context switches statistics.
273  *
274  * IN:
275  * @a           Activity structure with statistics.
276  * @prev        Index in array where stats used as reference are.
277  * @curr        Index in array for current sample statistics.
278  * @itv         Interval of time in 1/100th of a second.
279  ***************************************************************************
280  */
281 __print_funct_t print_pcsw_stats(struct activity *a, int prev, int curr,
282                                  unsigned long long itv)
283 {
284         struct stats_pcsw
285                 *spc = (struct stats_pcsw *) a->buf[curr],
286                 *spp = (struct stats_pcsw *) a->buf[prev];
287
288         if (dis) {
289                 print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
290         }
291
292         printf("%-11s", timestamp[curr]);
293         cprintf_f(NO_UNIT, 2, 9, 2,
294                   S_VALUE(spp->processes,      spc->processes,      itv),
295                   S_VALUE(spp->context_switch, spc->context_switch, itv));
296         printf("\n");
297 }
298
299 /*
300  ***************************************************************************
301  * Display interrupts statistics.
302  *
303  * IN:
304  * @a           Activity structure with statistics.
305  * @prev        Index in array where stats used as reference are.
306  * @curr        Index in array for current sample statistics.
307  * @itv         Interval of time in 1/100th of a second.
308  ***************************************************************************
309  */
310 __print_funct_t print_irq_stats(struct activity *a, int prev, int curr,
311                                 unsigned long long itv)
312 {
313         int i;
314         struct stats_irq *sic, *sip;
315
316         if (dis || DISPLAY_ZERO_OMIT(flags)) {
317                 print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
318         }
319
320         for (i = 0; (i < a->nr[curr]) && (i < a->bitmap->b_size + 1); i++) {
321
322                 /*
323                  * If @nr[curr] > @nr[prev] then we consider that previous
324                  * interrupt value was 0.
325                  */
326                 sic = (struct stats_irq *) ((char *) a->buf[curr] + i * a->msize);
327                 sip = (struct stats_irq *) ((char *) a->buf[prev] + i * a->msize);
328
329                 /*
330                  * Note: @nr[curr] gives the number of interrupts read (1 .. NR_IRQS + 1).
331                  * Bitmap size is provided for (NR_IRQS + 1) interrupts.
332                  * Anyway, NR_IRQS may vary between the version of sysstat
333                  * used by sadc to create a file, and the version of sysstat
334                  * used by sar to read it...
335                  */
336
337                 /* Should current interrupt (including int "sum") be displayed? */
338                 if (a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))) {
339
340                         if (DISPLAY_ZERO_OMIT(flags) && !memcmp(sip, sic, STATS_IRQ_SIZE))
341                                 continue;
342
343                         /* Yes: Display it */
344                         printf("%-11s", timestamp[curr]);
345                         if (!i) {
346                                 /* This is interrupt "sum" */
347                                 cprintf_in(IS_STR, " %s", "      sum", 0);
348                         }
349                         else {
350                                 cprintf_in(IS_INT, " %9d", "", i -1);
351                         }
352
353                         cprintf_f(NO_UNIT, 1, 9, 2, S_VALUE(sip->irq_nr, sic->irq_nr, itv));
354                         printf("\n");
355                 }
356         }
357 }
358
359 /*
360  ***************************************************************************
361  * Display swapping statistics.
362  *
363  * IN:
364  * @a           Activity structure with statistics.
365  * @prev        Index in array where stats used as reference are.
366  * @curr        Index in array for current sample statistics.
367  * @itv         Interval of time in 1/100th of a second.
368  ***************************************************************************
369  */
370 __print_funct_t print_swap_stats(struct activity *a, int prev, int curr,
371                                  unsigned long long itv)
372 {
373         struct stats_swap
374                 *ssc = (struct stats_swap *) a->buf[curr],
375                 *ssp = (struct stats_swap *) a->buf[prev];
376
377         if (dis) {
378                 print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
379         }
380
381         printf("%-11s", timestamp[curr]);
382         cprintf_f(NO_UNIT, 2, 9, 2,
383                   S_VALUE(ssp->pswpin,  ssc->pswpin,  itv),
384                   S_VALUE(ssp->pswpout, ssc->pswpout, itv));
385         printf("\n");
386 }
387
388 /*
389  ***************************************************************************
390  * Display paging statistics.
391  *
392  * IN:
393  * @a           Activity structure with statistics.
394  * @prev        Index in array where stats used as reference are.
395  * @curr        Index in array for current sample statistics.
396  * @itv         Interval of time in 1/100th of a second.
397  ***************************************************************************
398  */
399 __print_funct_t print_paging_stats(struct activity *a, int prev, int curr,
400                                    unsigned long long itv)
401 {
402         struct stats_paging
403                 *spc = (struct stats_paging *) a->buf[curr],
404                 *spp = (struct stats_paging *) a->buf[prev];
405
406         if (dis) {
407                 print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
408         }
409
410         printf("%-11s", timestamp[curr]);
411         cprintf_f(NO_UNIT, 8, 9, 2,
412                   S_VALUE(spp->pgpgin,        spc->pgpgin,        itv),
413                   S_VALUE(spp->pgpgout,       spc->pgpgout,       itv),
414                   S_VALUE(spp->pgfault,       spc->pgfault,       itv),
415                   S_VALUE(spp->pgmajfault,    spc->pgmajfault,    itv),
416                   S_VALUE(spp->pgfree,        spc->pgfree,        itv),
417                   S_VALUE(spp->pgscan_kswapd, spc->pgscan_kswapd, itv),
418                   S_VALUE(spp->pgscan_direct, spc->pgscan_direct, itv),
419                   S_VALUE(spp->pgsteal,       spc->pgsteal,       itv));
420         cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2,
421                    (spc->pgscan_kswapd + spc->pgscan_direct -
422                    spp->pgscan_kswapd - spp->pgscan_direct) ?
423                    SP_VALUE(spp->pgsteal, spc->pgsteal,
424                             spc->pgscan_kswapd + spc->pgscan_direct -
425                             spp->pgscan_kswapd - spp->pgscan_direct)
426                    : 0.0);
427         printf("\n");
428 }
429
430 /*
431  ***************************************************************************
432  * Display I/O and transfer rate statistics.
433  *
434  * IN:
435  * @a           Activity structure with statistics.
436  * @prev        Index in array where stats used as reference are.
437  * @curr        Index in array for current sample statistics.
438  * @itv         Interval of time in 1/100th of a second.
439  ***************************************************************************
440  */
441 __print_funct_t print_io_stats(struct activity *a, int prev, int curr,
442                                unsigned long long itv)
443 {
444         struct stats_io
445                 *sic = (struct stats_io *) a->buf[curr],
446                 *sip = (struct stats_io *) a->buf[prev];
447
448         if (dis) {
449                 print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
450         }
451
452         printf("%-11s", timestamp[curr]);
453         /*
454          * If we get negative values, this is probably because
455          * one or more devices/filesystems have been unmounted.
456          * We display 0.0 in this case though we should rather tell
457          * the user that the value cannot be calculated here.
458          */
459         cprintf_f(NO_UNIT, 5, 9, 2,
460                   sic->dk_drive < sip->dk_drive ? 0.0 :
461                   S_VALUE(sip->dk_drive, sic->dk_drive, itv),
462                   sic->dk_drive_rio < sip->dk_drive_rio ? 0.0 :
463                   S_VALUE(sip->dk_drive_rio, sic->dk_drive_rio, itv),
464                   sic->dk_drive_wio < sip->dk_drive_wio ? 0.0 :
465                   S_VALUE(sip->dk_drive_wio, sic->dk_drive_wio, itv),
466                   sic->dk_drive_rblk < sip->dk_drive_rblk ? 0.0 :
467                   S_VALUE(sip->dk_drive_rblk, sic->dk_drive_rblk, itv),
468                   sic->dk_drive_wblk < sip->dk_drive_wblk ? 0.0 :
469                   S_VALUE(sip->dk_drive_wblk, sic->dk_drive_wblk, itv));
470         printf("\n");
471 }
472
473 /*
474  ***************************************************************************
475  * Display memory and swap statistics. This function is used to
476  * display instantaneous and average statistics.
477  *
478  * IN:
479  * @a           Activity structure with statistics.
480  * @prev        Index in array where stats used as reference are.
481  * @curr        Index in array for current sample statistics.
482  * @dispavg     TRUE if displaying average statistics.
483  ***************************************************************************
484  */
485 void stub_print_memory_stats(struct activity *a, int prev, int curr, int dispavg)
486 {
487         struct stats_memory
488                 *smc = (struct stats_memory *) a->buf[curr];
489         static unsigned long long
490                 avg_frmkb       = 0,
491                 avg_bufkb       = 0,
492                 avg_camkb       = 0,
493                 avg_comkb       = 0,
494                 avg_activekb    = 0,
495                 avg_inactkb     = 0,
496                 avg_dirtykb     = 0,
497                 avg_anonpgkb    = 0,
498                 avg_slabkb      = 0,
499                 avg_kstackkb    = 0,
500                 avg_pgtblkb     = 0,
501                 avg_vmusedkb    = 0,
502                 avg_availablekb = 0;
503         static unsigned long long
504                 avg_frskb = 0,
505                 avg_tlskb = 0,
506                 avg_caskb = 0;
507         int unit = NO_UNIT;
508
509         if (DISPLAY_UNIT(flags)) {
510                 /* Default values unit is kB */
511                 unit = UNIT_KILOBYTE;
512         }
513
514         if (DISPLAY_MEMORY(a->opt_flags)) {
515                 if (dis) {
516                         print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
517                 }
518
519                 if (!dispavg) {
520                         /* Display instantaneous values */
521                         printf("%-11s", timestamp[curr]);
522                         cprintf_u64(unit, 3, 9,
523                                     (unsigned long long) smc->frmkb,
524                                     (unsigned long long) smc->availablekb,
525                                     (unsigned long long) (smc->tlmkb - smc->frmkb));
526                         cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2,
527                                    smc->tlmkb ?
528                                    SP_VALUE(smc->frmkb, smc->tlmkb, smc->tlmkb)
529                                    : 0.0);
530                         cprintf_u64(unit, 3, 9,
531                                     (unsigned long long) smc->bufkb,
532                                     (unsigned long long) smc->camkb,
533                                     (unsigned long long) smc->comkb);
534                         cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2,
535                                    (smc->tlmkb + smc->tlskb) ?
536                                    SP_VALUE(0, smc->comkb, smc->tlmkb + smc->tlskb)
537                                    : 0.0);
538                         cprintf_u64(unit, 3, 9,
539                                     (unsigned long long) smc->activekb,
540                                     (unsigned long long) smc->inactkb,
541                                     (unsigned long long) smc->dirtykb);
542
543                         if (DISPLAY_MEM_ALL(a->opt_flags)) {
544                                 /* Display extended memory statistics */
545                                 cprintf_u64(unit, 5, 9,
546                                             (unsigned long long) smc->anonpgkb,
547                                             (unsigned long long) smc->slabkb,
548                                             (unsigned long long) smc->kstackkb,
549                                             (unsigned long long) smc->pgtblkb,
550                                             (unsigned long long) smc->vmusedkb);
551                         }
552
553                         printf("\n");
554
555                         /*
556                          * Will be used to compute the average.
557                          * We assume that the total amount of memory installed can not vary
558                          * during the interval given on the command line.
559                          */
560                         avg_frmkb       += smc->frmkb;
561                         avg_bufkb       += smc->bufkb;
562                         avg_camkb       += smc->camkb;
563                         avg_comkb       += smc->comkb;
564                         avg_activekb    += smc->activekb;
565                         avg_inactkb     += smc->inactkb;
566                         avg_dirtykb     += smc->dirtykb;
567                         avg_anonpgkb    += smc->anonpgkb;
568                         avg_slabkb      += smc->slabkb;
569                         avg_kstackkb    += smc->kstackkb;
570                         avg_pgtblkb     += smc->pgtblkb;
571                         avg_vmusedkb    += smc->vmusedkb;
572                         avg_availablekb += smc->availablekb;
573                 }
574                 else {
575                         /* Display average values */
576                         printf("%-11s", timestamp[curr]);
577                         cprintf_f(unit, 3, 9, 0,
578                                   (double) avg_frmkb / avg_count,
579                                   (double) avg_availablekb / avg_count,
580                                   (double) smc->tlmkb - ((double) avg_frmkb / avg_count));
581                         cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2,
582                                    smc->tlmkb ?
583                                    SP_VALUE((double) (avg_frmkb / avg_count), smc->tlmkb, smc->tlmkb)
584                                    : 0.0);
585                         cprintf_f(unit, 3, 9, 0,
586                                   (double) avg_bufkb / avg_count,
587                                   (double) avg_camkb / avg_count,
588                                   (double) avg_comkb / avg_count);
589                         cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2,
590                                    (smc->tlmkb + smc->tlskb) ?
591                                    SP_VALUE(0.0, (double) (avg_comkb / avg_count), smc->tlmkb + smc->tlskb)
592                                    : 0.0);
593                         cprintf_f(unit, 3, 9, 0,
594                                   (double) avg_activekb / avg_count,
595                                   (double) avg_inactkb / avg_count,
596                                   (double) avg_dirtykb / avg_count);
597
598                         if (DISPLAY_MEM_ALL(a->opt_flags)) {
599                                 cprintf_f(unit, 5, 9, 0,
600                                           (double) avg_anonpgkb / avg_count,
601                                           (double) avg_slabkb / avg_count,
602                                           (double) avg_kstackkb / avg_count,
603                                           (double) avg_pgtblkb / avg_count,
604                                           (double) avg_vmusedkb / avg_count);
605                         }
606
607                         printf("\n");
608
609                         /* Reset average counters */
610                         avg_frmkb = avg_bufkb = avg_camkb = avg_comkb = 0;
611                         avg_activekb = avg_inactkb = avg_dirtykb = 0;
612                         avg_anonpgkb = avg_slabkb = avg_kstackkb = 0;
613                         avg_pgtblkb = avg_vmusedkb = avg_availablekb = 0;
614                 }
615         }
616
617         if (DISPLAY_SWAP(a->opt_flags)) {
618                 if (dis) {
619                         print_hdr_line(timestamp[!curr], a, SECOND, 0, 9);
620                 }
621
622                 if (!dispavg) {
623                         /* Display instantaneous values */
624                         printf("%-11s", timestamp[curr]);
625                         cprintf_u64(unit, 2, 9,
626                                     (unsigned long long) smc->frskb,
627                                     (unsigned long long) (smc->tlskb - smc->frskb));
628                         cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2,
629                                    smc->tlskb ?
630                                    SP_VALUE(smc->frskb, smc->tlskb, smc->tlskb)
631                                    : 0.0);
632                         cprintf_u64(unit, 1, 9,
633                                     (unsigned long long) smc->caskb);
634                         cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2,
635                                    (smc->tlskb - smc->frskb) ?
636                                    SP_VALUE(0, smc->caskb, smc->tlskb - smc->frskb)
637                                    : 0.0);
638
639                         printf("\n");
640
641                         /*
642                          * Will be used to compute the average.
643                          * We assume that the total amount of swap space may vary.
644                          */
645                         avg_frskb += smc->frskb;
646                         avg_tlskb += smc->tlskb;
647                         avg_caskb += smc->caskb;
648                 }
649                 else {
650                         /* Display average values */
651                         printf("%-11s", timestamp[curr]);
652                         cprintf_f(unit, 2, 9, 0,
653                                   (double) avg_frskb / avg_count,
654                                   ((double) avg_tlskb / avg_count) -
655                                   ((double) avg_frskb / avg_count));
656                         cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2,
657                                    avg_tlskb ?
658                                    SP_VALUE((double) avg_frskb / avg_count,
659                                             (double) avg_tlskb / avg_count,
660                                             (double) avg_tlskb / avg_count)
661                                    : 0.0);
662                         cprintf_f(unit, 1, 9, 0,
663                                   (double) avg_caskb / avg_count);
664                         cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2,
665                                    (avg_tlskb != avg_frskb) ?
666                                    SP_VALUE(0.0, (double) avg_caskb / avg_count,
667                                             ((double) avg_tlskb / avg_count) -
668                                             ((double) avg_frskb / avg_count))
669                                    : 0.0);
670                         printf("\n");
671
672                         /* Reset average counters */
673                         avg_frskb = avg_tlskb = avg_caskb = 0;
674                 }
675         }
676 }
677
678 /*
679  ***************************************************************************
680  * Display memory and swap statistics.
681  *
682  * IN:
683  * @a           Activity structure with statistics.
684  * @prev        Index in array where stats used as reference are.
685  * @curr        Index in array for current sample statistics.
686  * @itv         Interval of time in 1/100th of a second.
687  ***************************************************************************
688  */
689 __print_funct_t print_memory_stats(struct activity *a, int prev, int curr,
690                                    unsigned long long itv)
691 {
692         stub_print_memory_stats(a, prev, curr, FALSE);
693 }
694
695 /*
696  ***************************************************************************
697  * Display average memory statistics.
698  *
699  * IN:
700  * @a           Activity structure with statistics.
701  * @prev        Index in array where stats used as reference are.
702  * @curr        Index in array for current sample statistics.
703  * @itv         Interval of time in 1/100th of a second.
704  ***************************************************************************
705  */
706 __print_funct_t print_avg_memory_stats(struct activity *a, int prev, int curr,
707                                        unsigned long long itv)
708 {
709         stub_print_memory_stats(a, prev, curr, TRUE);
710 }
711
712 /*
713  ***************************************************************************
714  * Display kernel tables statistics. This function is used to display
715  * instantaneous and average statistics.
716  *
717  * IN:
718  * @a           Activity structure with statistics.
719  * @curr        Index in array for current sample statistics.
720  * @dispavg     True if displaying average statistics.
721  ***************************************************************************
722  */
723 void stub_print_ktables_stats(struct activity *a, int curr, int dispavg)
724 {
725         struct stats_ktables
726                 *skc = (struct stats_ktables *) a->buf[curr];
727         static unsigned long long
728                 avg_dentry_stat = 0,
729                 avg_file_used   = 0,
730                 avg_inode_used  = 0,
731                 avg_pty_nr      = 0;
732
733
734         if (dis) {
735                 print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
736         }
737
738         if (!dispavg) {
739                 /* Display instantaneous values */
740                 printf("%-11s", timestamp[curr]);
741                 cprintf_u64(NO_UNIT, 4, 9,
742                             (unsigned long long) skc->dentry_stat,
743                             (unsigned long long) skc->file_used,
744                             (unsigned long long) skc->inode_used,
745                             (unsigned long long) skc->pty_nr);
746                 printf("\n");
747
748                 /*
749                  * Will be used to compute the average.
750                  * Note: Overflow unlikely to happen but not impossible...
751                  */
752                 avg_dentry_stat += skc->dentry_stat;
753                 avg_file_used   += skc->file_used;
754                 avg_inode_used  += skc->inode_used;
755                 avg_pty_nr      += skc->pty_nr;
756         }
757         else {
758                 /* Display average values */
759                 printf("%-11s", timestamp[curr]);
760                 cprintf_f(NO_UNIT, 4, 9, 0,
761                           (double) avg_dentry_stat / avg_count,
762                           (double) avg_file_used   / avg_count,
763                           (double) avg_inode_used  / avg_count,
764                           (double) avg_pty_nr      / avg_count);
765                 printf("\n");
766
767                 /* Reset average counters */
768                 avg_dentry_stat = avg_file_used = avg_inode_used = avg_pty_nr = 0;
769         }
770 }
771
772 /*
773  ***************************************************************************
774  * Display kernel tables statistics.
775  *
776  * IN:
777  * @a           Activity structure with statistics.
778  * @prev        Index in array where stats used as reference are.
779  * @curr        Index in array for current sample statistics.
780  * @itv         Interval of time in 1/100th of a second.
781  ***************************************************************************
782  */
783 __print_funct_t print_ktables_stats(struct activity *a, int prev, int curr,
784                                     unsigned long long itv)
785 {
786         stub_print_ktables_stats(a, curr, FALSE);
787 }
788
789 /*
790  ***************************************************************************
791  * Display average kernel tables statistics.
792  *
793  * IN:
794  * @a           Activity structure with statistics.
795  * @prev        Index in array where stats used as reference are.
796  * @curr        Index in array for current sample statistics.
797  * @itv         Interval of time in 1/100th of a second.
798  ***************************************************************************
799  */
800 __print_funct_t print_avg_ktables_stats(struct activity *a, int prev, int curr,
801                                         unsigned long long itv)
802 {
803         stub_print_ktables_stats(a, curr, TRUE);
804 }
805
806 /*
807  ***************************************************************************
808  * Display queue and load statistics. This function is used to display
809  * instantaneous and average statistics.
810  *
811  * IN:
812  * @a           Activity structure with statistics.
813  * @curr        Index in array for current sample statistics.
814  * @dispavg     TRUE if displaying average statistics.
815  ***************************************************************************
816  */
817 void stub_print_queue_stats(struct activity *a, int curr, int dispavg)
818 {
819         struct stats_queue
820                 *sqc = (struct stats_queue *) a->buf[curr];
821         static unsigned long long
822                 avg_nr_running    = 0,
823                 avg_nr_threads    = 0,
824                 avg_load_avg_1    = 0,
825                 avg_load_avg_5    = 0,
826                 avg_load_avg_15   = 0,
827                 avg_procs_blocked = 0;
828
829         if (dis) {
830                 print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
831         }
832
833         if (!dispavg) {
834                 /* Display instantaneous values */
835                 printf("%-11s", timestamp[curr]);
836                 cprintf_u64(NO_UNIT, 2, 9,
837                             (unsigned long long) sqc->nr_running,
838                             (unsigned long long) sqc->nr_threads);
839                 cprintf_f(NO_UNIT, 3, 9, 2,
840                           (double) sqc->load_avg_1  / 100,
841                           (double) sqc->load_avg_5  / 100,
842                           (double) sqc->load_avg_15 / 100);
843                 cprintf_u64(NO_UNIT, 1, 9,
844                             (unsigned long long) sqc->procs_blocked);
845                 printf("\n");
846
847                 /* Will be used to compute the average */
848                 avg_nr_running    += sqc->nr_running;
849                 avg_nr_threads    += sqc->nr_threads;
850                 avg_load_avg_1    += sqc->load_avg_1;
851                 avg_load_avg_5    += sqc->load_avg_5;
852                 avg_load_avg_15   += sqc->load_avg_15;
853                 avg_procs_blocked += sqc->procs_blocked;
854         }
855         else {
856                 /* Display average values */
857                 printf("%-11s", timestamp[curr]);
858                 cprintf_f(NO_UNIT, 2, 9, 0,
859                           (double) avg_nr_running / avg_count,
860                           (double) avg_nr_threads / avg_count);
861                 cprintf_f(NO_UNIT, 3, 9, 2,
862                           (double) avg_load_avg_1  / (avg_count * 100),
863                           (double) avg_load_avg_5  / (avg_count * 100),
864                           (double) avg_load_avg_15 / (avg_count * 100));
865                 cprintf_f(NO_UNIT, 1, 9, 0,
866                           (double) avg_procs_blocked / avg_count);
867                 printf("\n");
868
869                 /* Reset average counters */
870                 avg_nr_running = avg_nr_threads = 0;
871                 avg_load_avg_1 = avg_load_avg_5 = avg_load_avg_15 = 0;
872                 avg_procs_blocked = 0;
873         }
874 }
875
876 /*
877  ***************************************************************************
878  * Display queue and load statistics.
879  *
880  * IN:
881  * @a           Activity structure with statistics.
882  * @prev        Index in array where stats used as reference are.
883  * @curr        Index in array for current sample statistics.
884  * @itv         Interval of time in 1/100th of a second.
885  ***************************************************************************
886  */
887 __print_funct_t print_queue_stats(struct activity *a, int prev, int curr,
888                                   unsigned long long itv)
889 {
890         stub_print_queue_stats(a, curr, FALSE);
891 }
892
893 /*
894  ***************************************************************************
895  * Display average queue and load statistics.
896  *
897  * IN:
898  * @a           Activity structure with statistics.
899  * @prev        Index in array where stats used as reference are.
900  * @curr        Index in array for current sample statistics.
901  * @itv         Interval of time in 1/100th of a second.
902  ***************************************************************************
903  */
904 __print_funct_t print_avg_queue_stats(struct activity *a, int prev, int curr,
905                                       unsigned long long itv)
906 {
907         stub_print_queue_stats(a, curr, TRUE);
908 }
909
910 /*
911  ***************************************************************************
912  * Display serial lines statistics.
913  *
914  * IN:
915  * @a           Activity structure with statistics.
916  * @prev        Index in array where stats used as reference are.
917  * @curr        Index in array for current sample statistics.
918  * @itv         Interval of time in 1/100th of a second.
919  ***************************************************************************
920  */
921 __print_funct_t print_serial_stats(struct activity *a, int prev, int curr,
922                                    unsigned long long itv)
923 {
924         int i, j, j0, found;
925         struct stats_serial *ssc, *ssp;
926
927         if (dis || DISPLAY_ZERO_OMIT(flags)) {
928                 print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
929         }
930
931         for (i = 0; i < a->nr[curr]; i++) {
932                 ssc = (struct stats_serial *) ((char *) a->buf[curr] + i * a->msize);
933
934                 if (WANT_SINCE_BOOT(flags)) {
935                         /*
936                          * We want to display statistics since boot time.
937                          * Take the first structure from buf[prev]: This is a
938                          * structure that only contains 0 (it has been set to 0
939                          * when it has been allocated), and which exists since
940                          * there is the same number of allocated structures for
941                          * buf[prev] and bur[curr] (even if nothing has been read).
942                          */
943                         ssp = (struct stats_serial *) ((char *) a->buf[prev]);
944                         found = TRUE;
945                 }
946                 else {
947                         found = FALSE;
948
949                         if (a->nr[prev] > 0) {
950                                 /* Look for corresponding serial line in previous iteration */
951                                 j = i;
952
953                                 if (j >= a->nr[prev]) {
954                                         j = a->nr[prev] - 1;
955                                 }
956
957                                 j0 = j;
958
959                                 do {
960                                         ssp = (struct stats_serial *) ((char *) a->buf[prev] + j * a->msize);
961                                         if (ssc->line == ssp->line) {
962                                                 found = TRUE;
963                                                 break;
964                                         }
965                                         if (++j >= a->nr[prev]) {
966                                                 j = 0;
967                                         }
968                                 }
969                                 while (j != j0);
970                         }
971                 }
972
973                 if (!found)
974                         continue;
975
976                 if (DISPLAY_ZERO_OMIT(flags) && !memcmp(ssp, ssc, STATS_SERIAL_SIZE))
977                         continue;
978
979                 printf("%-11s", timestamp[curr]);
980                 cprintf_in(IS_INT, "       %3d", "", ssc->line);
981
982                 cprintf_f(NO_UNIT, 6, 9, 2,
983                           S_VALUE(ssp->rx,      ssc->rx,      itv),
984                           S_VALUE(ssp->tx,      ssc->tx,      itv),
985                           S_VALUE(ssp->frame,   ssc->frame,   itv),
986                           S_VALUE(ssp->parity,  ssc->parity,  itv),
987                           S_VALUE(ssp->brk,     ssc->brk,     itv),
988                           S_VALUE(ssp->overrun, ssc->overrun, itv));
989                 printf("\n");
990         }
991 }
992
993 /*
994  ***************************************************************************
995  * Display disks statistics.
996  *
997  * IN:
998  * @a           Activity structure with statistics.
999  * @prev        Index in array where stats used as reference are.
1000  * @curr        Index in array for current sample statistics.
1001  * @itv         Interval of time in 1/100th of a second.
1002  ***************************************************************************
1003  */
1004 __print_funct_t print_disk_stats(struct activity *a, int prev, int curr,
1005                                  unsigned long long itv)
1006 {
1007         int i, j;
1008         struct stats_disk *sdc, *sdp, sdpzero;
1009         struct ext_disk_stats xds;
1010         char *dev_name, *persist_dev_name;
1011         int unit = NO_UNIT;
1012
1013         memset(&sdpzero, 0, STATS_DISK_SIZE);
1014
1015         if (DISPLAY_UNIT(flags)) {
1016                 /* Default values unit is kB */
1017                 unit = UNIT_KILOBYTE;
1018         }
1019
1020         if (dis || DISPLAY_ZERO_OMIT(flags)) {
1021                 print_hdr_line(timestamp[!curr], a, FIRST, DISPLAY_HUMAN_READ(flags) ? -1 : 0, 9);
1022         }
1023
1024         for (i = 0; i < a->nr[curr]; i++) {
1025                 sdc = (struct stats_disk *) ((char *) a->buf[curr] + i * a->msize);
1026
1027                 if (!WANT_SINCE_BOOT(flags)) {
1028                         j = check_disk_reg(a, curr, prev, i);
1029                 }
1030                 else {
1031                         j = -1;
1032                 }
1033                 if (j < 0) {
1034                         /*
1035                          * This is a newly registered device or we want stats since boot time.
1036                          * Previous stats are zero.
1037                          */
1038                         sdp = &sdpzero;
1039                 }
1040                 else {
1041                         sdp = (struct stats_disk *) ((char *) a->buf[prev] + j * a->msize);
1042                 }
1043
1044                 if (DISPLAY_ZERO_OMIT(flags) && !memcmp(sdp, sdc, STATS_DISK_SIZE))
1045                         continue;
1046
1047                 /* Compute service time, etc. */
1048                 compute_ext_disk_stats(sdc, sdp, itv, &xds);
1049
1050                 dev_name = NULL;
1051                 persist_dev_name = NULL;
1052
1053                 if (DISPLAY_PERSIST_NAME_S(flags)) {
1054                         persist_dev_name = get_persistent_name_from_pretty(get_devname(sdc->major, sdc->minor, TRUE));
1055                 }
1056
1057                 if (persist_dev_name) {
1058                         dev_name = persist_dev_name;
1059                 }
1060                 else {
1061                         if ((USE_PRETTY_OPTION(flags)) && (sdc->major == dm_major)) {
1062                                 dev_name = transform_devmapname(sdc->major, sdc->minor);
1063                         }
1064
1065                         if (!dev_name) {
1066                                 dev_name = get_devname(sdc->major, sdc->minor,
1067                                                        USE_PRETTY_OPTION(flags));
1068                         }
1069                 }
1070
1071                 printf("%-11s", timestamp[curr]);
1072
1073                 if (!DISPLAY_HUMAN_READ(flags)) {
1074                         cprintf_in(IS_STR, " %9s", dev_name, 0);
1075                 }
1076                 cprintf_f(NO_UNIT, 1, 9, 2,
1077                           S_VALUE(sdp->nr_ios, sdc->nr_ios,  itv));
1078                 cprintf_f(unit, 2, 9, 2,
1079                           S_VALUE(sdp->rd_sect, sdc->rd_sect, itv) / 2,
1080                           S_VALUE(sdp->wr_sect, sdc->wr_sect, itv) / 2);
1081                 /* See iostat for explanations */
1082                 cprintf_f(unit, 1, 9, 2,
1083                           xds.arqsz / 2);
1084                 cprintf_f(NO_UNIT, 3, 9, 2,
1085                           S_VALUE(sdp->rq_ticks, sdc->rq_ticks, itv) / 1000.0,
1086                           xds.await,
1087                           xds.svctm);
1088                 cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2,
1089                            xds.util / 10.0);
1090                 if (DISPLAY_HUMAN_READ(flags)) {
1091                         cprintf_in(IS_STR, " %s", dev_name, 0);
1092                 }
1093                 printf("\n");
1094         }
1095 }
1096
1097 /*
1098  ***************************************************************************
1099  * Display network interfaces statistics.
1100  *
1101  * IN:
1102  * @a           Activity structure with statistics.
1103  * @prev        Index in array where stats used as reference are.
1104  * @curr        Index in array for current sample statistics.
1105  * @itv         Interval of time in 1/100th of a second.
1106  ***************************************************************************
1107  */
1108 __print_funct_t print_net_dev_stats(struct activity *a, int prev, int curr,
1109                                     unsigned long long itv)
1110 {
1111         int i, j;
1112         struct stats_net_dev *sndc, *sndp, sndzero;
1113         double rxkb, txkb, ifutil;
1114         int unit = NO_UNIT;
1115
1116         memset(&sndzero, 0, STATS_NET_DEV_SIZE);
1117
1118         if (DISPLAY_UNIT(flags)) {
1119                 /* Default values unit is bytes */
1120                 unit = UNIT_BYTE;
1121         }
1122
1123         if (dis || DISPLAY_ZERO_OMIT(flags)) {
1124                 print_hdr_line(timestamp[!curr], a, FIRST, DISPLAY_HUMAN_READ(flags) ? -1 : 0, 9);
1125         }
1126
1127         for (i = 0; i < a->nr[curr]; i++) {
1128                 sndc = (struct stats_net_dev *) ((char *) a->buf[curr] + i * a->msize);
1129
1130                 if (!WANT_SINCE_BOOT(flags)) {
1131                         j = check_net_dev_reg(a, curr, prev, i);
1132                 }
1133                 else {
1134                         j = -1;
1135                 }
1136                 if (j < 0) {
1137                         /*
1138                          * This is a newly registered interface or we want stats since boot time.
1139                          * Previous stats are zero.
1140                          */
1141                         sndp = &sndzero;
1142                 }
1143                 else {
1144                         sndp = (struct stats_net_dev *) ((char *) a->buf[prev] + j * a->msize);
1145                 }
1146
1147                 if (DISPLAY_ZERO_OMIT(flags) && !memcmp(sndp, sndc, STATS_NET_DEV_SIZE2CMP))
1148                         continue;
1149
1150                 printf("%-11s", timestamp[curr]);
1151
1152                 if (!DISPLAY_HUMAN_READ(flags)) {
1153                         cprintf_in(IS_STR, " %9s", sndc->interface, 0);
1154                 }
1155                 rxkb = S_VALUE(sndp->rx_bytes, sndc->rx_bytes, itv);
1156                 txkb = S_VALUE(sndp->tx_bytes, sndc->tx_bytes, itv);
1157
1158                 cprintf_f(NO_UNIT, 2, 9, 2,
1159                           S_VALUE(sndp->rx_packets, sndc->rx_packets, itv),
1160                           S_VALUE(sndp->tx_packets, sndc->tx_packets, itv));
1161                 cprintf_f(unit, 2, 9, 2,
1162                           unit < 0 ? rxkb / 1024 : rxkb,
1163                           unit < 0 ? txkb / 1024 : txkb);
1164                 cprintf_f(NO_UNIT, 3, 9, 2,
1165                           S_VALUE(sndp->rx_compressed, sndc->rx_compressed, itv),
1166                           S_VALUE(sndp->tx_compressed, sndc->tx_compressed, itv),
1167                           S_VALUE(sndp->multicast,     sndc->multicast,     itv));
1168                 ifutil = compute_ifutil(sndc, rxkb, txkb);
1169                 cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2, ifutil);
1170                 if (DISPLAY_HUMAN_READ(flags)) {
1171                         cprintf_in(IS_STR, " %s", sndc->interface, 0);
1172                 }
1173                 printf("\n");
1174         }
1175 }
1176
1177 /*
1178  ***************************************************************************
1179  * Display network interface errors statistics.
1180  *
1181  * IN:
1182  * @a           Activity structure with statistics.
1183  * @prev        Index in array where stats used as reference are.
1184  * @curr        Index in array for current sample statistics.
1185  * @itv         Interval of time in 1/100th of a second.
1186  ***************************************************************************
1187  */
1188 __print_funct_t print_net_edev_stats(struct activity *a, int prev, int curr,
1189                                      unsigned long long itv)
1190 {
1191         int i, j;
1192         struct stats_net_edev *snedc, *snedp, snedzero;
1193
1194         memset(&snedzero, 0, STATS_NET_EDEV_SIZE);
1195
1196         if (dis || DISPLAY_ZERO_OMIT(flags)) {
1197                 print_hdr_line(timestamp[!curr], a, FIRST, DISPLAY_HUMAN_READ(flags) ? -1 : 0, 9);
1198         }
1199
1200         for (i = 0; i < a->nr[curr]; i++) {
1201                 snedc = (struct stats_net_edev *) ((char *) a->buf[curr] + i * a->msize);
1202
1203                 if (!WANT_SINCE_BOOT(flags)) {
1204                         j = check_net_edev_reg(a, curr, prev, i);
1205                 }
1206                 else {
1207                         j = -1;
1208                 }
1209                 if (j < 0) {
1210                         /*
1211                          * This is a newly registered interface or we want stats since boot time.
1212                          * Previous stats are zero.
1213                          */
1214                         snedp = &snedzero;
1215                 }
1216                 else {
1217                         snedp = (struct stats_net_edev *) ((char *) a->buf[prev] + j * a->msize);
1218                 }
1219
1220                 if (DISPLAY_ZERO_OMIT(flags) && !memcmp(snedp, snedc, STATS_NET_EDEV_SIZE2CMP))
1221                         continue;
1222
1223                 printf("%-11s", timestamp[curr]);
1224
1225                 if (!DISPLAY_HUMAN_READ(flags)) {
1226                         cprintf_in(IS_STR, " %9s", snedc->interface, 0);
1227                 }
1228                 cprintf_f(NO_UNIT, 9, 9, 2,
1229                           S_VALUE(snedp->rx_errors,         snedc->rx_errors,         itv),
1230                           S_VALUE(snedp->tx_errors,         snedc->tx_errors,         itv),
1231                           S_VALUE(snedp->collisions,        snedc->collisions,        itv),
1232                           S_VALUE(snedp->rx_dropped,        snedc->rx_dropped,        itv),
1233                           S_VALUE(snedp->tx_dropped,        snedc->tx_dropped,        itv),
1234                           S_VALUE(snedp->tx_carrier_errors, snedc->tx_carrier_errors, itv),
1235                           S_VALUE(snedp->rx_frame_errors,   snedc->rx_frame_errors,   itv),
1236                           S_VALUE(snedp->rx_fifo_errors,    snedc->rx_fifo_errors,    itv),
1237                           S_VALUE(snedp->tx_fifo_errors,    snedc->tx_fifo_errors,    itv));
1238                 if (DISPLAY_HUMAN_READ(flags)) {
1239                         cprintf_in(IS_STR, " %s", snedc->interface, 0);
1240                 }
1241                 printf("\n");
1242         }
1243 }
1244
1245 /*
1246  ***************************************************************************
1247  * Display NFS client statistics.
1248  *
1249  * IN:
1250  * @a           Activity structure with statistics.
1251  * @prev        Index in array where stats used as reference are.
1252  * @curr        Index in array for current sample statistics.
1253  * @itv         Interval of time in 1/100th of a second.
1254  ***************************************************************************
1255  */
1256 __print_funct_t print_net_nfs_stats(struct activity *a, int prev, int curr,
1257                                     unsigned long long itv)
1258 {
1259         struct stats_net_nfs
1260                 *snnc = (struct stats_net_nfs *) a->buf[curr],
1261                 *snnp = (struct stats_net_nfs *) a->buf[prev];
1262
1263         if (dis) {
1264                 print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
1265         }
1266
1267         printf("%-11s", timestamp[curr]);
1268         cprintf_f(NO_UNIT, 6, 9, 2,
1269                   S_VALUE(snnp->nfs_rpccnt,     snnc->nfs_rpccnt,     itv),
1270                   S_VALUE(snnp->nfs_rpcretrans, snnc->nfs_rpcretrans, itv),
1271                   S_VALUE(snnp->nfs_readcnt,    snnc->nfs_readcnt,    itv),
1272                   S_VALUE(snnp->nfs_writecnt,   snnc->nfs_writecnt,   itv),
1273                   S_VALUE(snnp->nfs_accesscnt,  snnc->nfs_accesscnt,  itv),
1274                   S_VALUE(snnp->nfs_getattcnt,  snnc->nfs_getattcnt,  itv));
1275         printf("\n");
1276 }
1277
1278 /*
1279  ***************************************************************************
1280  * Display NFS server statistics.
1281  *
1282  * IN:
1283  * @a           Activity structure with statistics.
1284  * @prev        Index in array where stats used as reference are.
1285  * @curr        Index in array for current sample statistics.
1286  * @itv         Interval of time in 1/100th of a second.
1287  ***************************************************************************
1288  */
1289 __print_funct_t print_net_nfsd_stats(struct activity *a, int prev, int curr,
1290                                      unsigned long long itv)
1291 {
1292         struct stats_net_nfsd
1293                 *snndc = (struct stats_net_nfsd *) a->buf[curr],
1294                 *snndp = (struct stats_net_nfsd *) a->buf[prev];
1295
1296         if (dis) {
1297                 print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
1298         }
1299
1300         printf("%-11s", timestamp[curr]);
1301         cprintf_f(NO_UNIT, 11, 9, 2,
1302                   S_VALUE(snndp->nfsd_rpccnt,    snndc->nfsd_rpccnt,    itv),
1303                   S_VALUE(snndp->nfsd_rpcbad,    snndc->nfsd_rpcbad,    itv),
1304                   S_VALUE(snndp->nfsd_netcnt,    snndc->nfsd_netcnt,    itv),
1305                   S_VALUE(snndp->nfsd_netudpcnt, snndc->nfsd_netudpcnt, itv),
1306                   S_VALUE(snndp->nfsd_nettcpcnt, snndc->nfsd_nettcpcnt, itv),
1307                   S_VALUE(snndp->nfsd_rchits,    snndc->nfsd_rchits,    itv),
1308                   S_VALUE(snndp->nfsd_rcmisses,  snndc->nfsd_rcmisses,  itv),
1309                   S_VALUE(snndp->nfsd_readcnt,   snndc->nfsd_readcnt,   itv),
1310                   S_VALUE(snndp->nfsd_writecnt,  snndc->nfsd_writecnt,  itv),
1311                   S_VALUE(snndp->nfsd_accesscnt, snndc->nfsd_accesscnt, itv),
1312                   S_VALUE(snndp->nfsd_getattcnt, snndc->nfsd_getattcnt, itv));
1313         printf("\n");
1314 }
1315
1316 /*
1317  ***************************************************************************
1318  * Display network sockets statistics. This function is used to display
1319  * instantaneous and average statistics.
1320  *
1321  * IN:
1322  * @a           Activity structure with statistics.
1323  * @curr        Index in array for current sample statistics.
1324  * @dispavg     TRUE if displaying average statistics.
1325  ***************************************************************************
1326  */
1327 void stub_print_net_sock_stats(struct activity *a, int curr, int dispavg)
1328 {
1329         struct stats_net_sock
1330                 *snsc = (struct stats_net_sock *) a->buf[curr];
1331         static unsigned long long
1332                 avg_sock_inuse = 0,
1333                 avg_tcp_inuse  = 0,
1334                 avg_udp_inuse  = 0,
1335                 avg_raw_inuse  = 0,
1336                 avg_frag_inuse = 0,
1337                 avg_tcp_tw     = 0;
1338
1339         if (dis) {
1340                 print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
1341         }
1342
1343         if (!dispavg) {
1344                 /* Display instantaneous values */
1345                 printf("%-11s", timestamp[curr]);
1346                 cprintf_u64(NO_UNIT, 6, 9,
1347                             (unsigned long long) snsc->sock_inuse,
1348                             (unsigned long long) snsc->tcp_inuse,
1349                             (unsigned long long) snsc->udp_inuse,
1350                             (unsigned long long) snsc->raw_inuse,
1351                             (unsigned long long) snsc->frag_inuse,
1352                             (unsigned long long) snsc->tcp_tw);
1353                 printf("\n");
1354
1355                 /* Will be used to compute the average */
1356                 avg_sock_inuse += snsc->sock_inuse;
1357                 avg_tcp_inuse  += snsc->tcp_inuse;
1358                 avg_udp_inuse  += snsc->udp_inuse;
1359                 avg_raw_inuse  += snsc->raw_inuse;
1360                 avg_frag_inuse += snsc->frag_inuse;
1361                 avg_tcp_tw     += snsc->tcp_tw;
1362         }
1363         else {
1364                 /* Display average values */
1365                 printf("%-11s", timestamp[curr]);
1366                 cprintf_f(NO_UNIT, 6, 9, 0,
1367                           (double) avg_sock_inuse / avg_count,
1368                           (double) avg_tcp_inuse  / avg_count,
1369                           (double) avg_udp_inuse  / avg_count,
1370                           (double) avg_raw_inuse  / avg_count,
1371                           (double) avg_frag_inuse / avg_count,
1372                           (double) avg_tcp_tw     / avg_count);
1373                 printf("\n");
1374
1375                 /* Reset average counters */
1376                 avg_sock_inuse = avg_tcp_inuse = avg_udp_inuse = 0;
1377                 avg_raw_inuse = avg_frag_inuse = avg_tcp_tw = 0;
1378         }
1379 }
1380
1381 /*
1382  ***************************************************************************
1383  * Display network sockets statistics.
1384  *
1385  * IN:
1386  * @a           Activity structure with statistics.
1387  * @prev        Index in array where stats used as reference are.
1388  * @curr        Index in array for current sample statistics.
1389  * @itv         Interval of time in 1/100th of a second.
1390  ***************************************************************************
1391  */
1392 __print_funct_t print_net_sock_stats(struct activity *a, int prev, int curr,
1393                                      unsigned long long itv)
1394 {
1395         stub_print_net_sock_stats(a, curr, FALSE);
1396 }
1397
1398 /*
1399  ***************************************************************************
1400  * Display average network sockets statistics.
1401  *
1402  * IN:
1403  * @a           Activity structure with statistics.
1404  * @prev        Index in array where stats used as reference are.
1405  * @curr        Index in array for current sample statistics.
1406  * @itv         Interval of time in 1/100th of a second.
1407  ***************************************************************************
1408  */
1409 __print_funct_t print_avg_net_sock_stats(struct activity *a, int prev, int curr,
1410                                          unsigned long long itv)
1411 {
1412         stub_print_net_sock_stats(a, curr, TRUE);
1413 }
1414
1415 /*
1416  ***************************************************************************
1417  * Display IP network traffic statistics.
1418  *
1419  * IN:
1420  * @a           Activity structure with statistics.
1421  * @prev        Index in array where stats used as reference are.
1422  * @curr        Index in array for current sample statistics.
1423  * @itv         Interval of time in 1/100th of a second.
1424  ***************************************************************************
1425  */
1426 __print_funct_t print_net_ip_stats(struct activity *a, int prev, int curr,
1427                                    unsigned long long itv)
1428 {
1429         struct stats_net_ip
1430                 *snic = (struct stats_net_ip *) a->buf[curr],
1431                 *snip = (struct stats_net_ip *) a->buf[prev];
1432
1433         if (dis) {
1434                 print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
1435         }
1436
1437         printf("%-11s", timestamp[curr]);
1438         cprintf_f(NO_UNIT, 8, 9, 2,
1439                   S_VALUE(snip->InReceives,    snic->InReceives,    itv),
1440                   S_VALUE(snip->ForwDatagrams, snic->ForwDatagrams, itv),
1441                   S_VALUE(snip->InDelivers,    snic->InDelivers,    itv),
1442                   S_VALUE(snip->OutRequests,   snic->OutRequests,   itv),
1443                   S_VALUE(snip->ReasmReqds,    snic->ReasmReqds,    itv),
1444                   S_VALUE(snip->ReasmOKs,      snic->ReasmOKs,      itv),
1445                   S_VALUE(snip->FragOKs,       snic->FragOKs,       itv),
1446                   S_VALUE(snip->FragCreates,   snic->FragCreates,   itv));
1447         printf("\n");
1448 }
1449
1450 /*
1451  ***************************************************************************
1452  * Display IP network errors statistics.
1453  *
1454  * IN:
1455  * @a           Activity structure with statistics.
1456  * @prev        Index in array where stats used as reference are.
1457  * @curr        Index in array for current sample statistics.
1458  * @itv         Interval of time in 1/100th of a second.
1459  ***************************************************************************
1460  */
1461 __print_funct_t print_net_eip_stats(struct activity *a, int prev, int curr,
1462                                     unsigned long long itv)
1463 {
1464         struct stats_net_eip
1465                 *sneic = (struct stats_net_eip *) a->buf[curr],
1466                 *sneip = (struct stats_net_eip *) a->buf[prev];
1467
1468         if (dis) {
1469                 print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
1470         }
1471
1472         printf("%-11s", timestamp[curr]);
1473         cprintf_f(NO_UNIT, 8, 9, 2,
1474                   S_VALUE(sneip->InHdrErrors,     sneic->InHdrErrors,     itv),
1475                   S_VALUE(sneip->InAddrErrors,    sneic->InAddrErrors,    itv),
1476                   S_VALUE(sneip->InUnknownProtos, sneic->InUnknownProtos, itv),
1477                   S_VALUE(sneip->InDiscards,      sneic->InDiscards,      itv),
1478                   S_VALUE(sneip->OutDiscards,     sneic->OutDiscards,     itv),
1479                   S_VALUE(sneip->OutNoRoutes,     sneic->OutNoRoutes,     itv),
1480                   S_VALUE(sneip->ReasmFails,      sneic->ReasmFails,      itv),
1481                   S_VALUE(sneip->FragFails,       sneic->FragFails,       itv));
1482         printf("\n");
1483 }
1484
1485 /*
1486  ***************************************************************************
1487  * Display ICMP network traffic statistics.
1488  *
1489  * IN:
1490  * @a           Activity structure with statistics.
1491  * @prev        Index in array where stats used as reference are.
1492  * @curr        Index in array for current sample statistics.
1493  * @itv         Interval of time in 1/100th of a second.
1494  ***************************************************************************
1495  */
1496 __print_funct_t print_net_icmp_stats(struct activity *a, int prev, int curr,
1497                                      unsigned long long itv)
1498 {
1499         struct stats_net_icmp
1500                 *snic = (struct stats_net_icmp *) a->buf[curr],
1501                 *snip = (struct stats_net_icmp *) a->buf[prev];
1502
1503         if (dis) {
1504                 print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
1505         }
1506
1507         printf("%-11s", timestamp[curr]);
1508         cprintf_f(NO_UNIT, 14, 9, 2,
1509                   S_VALUE(snip->InMsgs,           snic->InMsgs,           itv),
1510                   S_VALUE(snip->OutMsgs,          snic->OutMsgs,          itv),
1511                   S_VALUE(snip->InEchos,          snic->InEchos,          itv),
1512                   S_VALUE(snip->InEchoReps,       snic->InEchoReps,       itv),
1513                   S_VALUE(snip->OutEchos,         snic->OutEchos,         itv),
1514                   S_VALUE(snip->OutEchoReps,      snic->OutEchoReps,      itv),
1515                   S_VALUE(snip->InTimestamps,     snic->InTimestamps,     itv),
1516                   S_VALUE(snip->InTimestampReps,  snic->InTimestampReps,  itv),
1517                   S_VALUE(snip->OutTimestamps,    snic->OutTimestamps,    itv),
1518                   S_VALUE(snip->OutTimestampReps, snic->OutTimestampReps, itv),
1519                   S_VALUE(snip->InAddrMasks,      snic->InAddrMasks,      itv),
1520                   S_VALUE(snip->InAddrMaskReps,   snic->InAddrMaskReps,   itv),
1521                   S_VALUE(snip->OutAddrMasks,     snic->OutAddrMasks,     itv),
1522                   S_VALUE(snip->OutAddrMaskReps,  snic->OutAddrMaskReps,  itv));
1523         printf("\n");
1524 }
1525
1526 /*
1527  ***************************************************************************
1528  * Display ICMP network errors statistics.
1529  *
1530  * IN:
1531  * @a           Activity structure with statistics.
1532  * @prev        Index in array where stats used as reference are.
1533  * @curr        Index in array for current sample statistics.
1534  * @itv         Interval of time in 1/100th of a second.
1535  ***************************************************************************
1536  */
1537 __print_funct_t print_net_eicmp_stats(struct activity *a, int prev, int curr,
1538                                       unsigned long long itv)
1539 {
1540         struct stats_net_eicmp
1541                 *sneic = (struct stats_net_eicmp *) a->buf[curr],
1542                 *sneip = (struct stats_net_eicmp *) a->buf[prev];
1543
1544         if (dis) {
1545                 print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
1546         }
1547
1548         printf("%-11s", timestamp[curr]);
1549         cprintf_f(NO_UNIT, 12, 9, 2,
1550                   S_VALUE(sneip->InErrors,        sneic->InErrors,        itv),
1551                   S_VALUE(sneip->OutErrors,       sneic->OutErrors,       itv),
1552                   S_VALUE(sneip->InDestUnreachs,  sneic->InDestUnreachs,  itv),
1553                   S_VALUE(sneip->OutDestUnreachs, sneic->OutDestUnreachs, itv),
1554                   S_VALUE(sneip->InTimeExcds,     sneic->InTimeExcds,     itv),
1555                   S_VALUE(sneip->OutTimeExcds,    sneic->OutTimeExcds,    itv),
1556                   S_VALUE(sneip->InParmProbs,     sneic->InParmProbs,     itv),
1557                   S_VALUE(sneip->OutParmProbs,    sneic->OutParmProbs,    itv),
1558                   S_VALUE(sneip->InSrcQuenchs,    sneic->InSrcQuenchs,    itv),
1559                   S_VALUE(sneip->OutSrcQuenchs,   sneic->OutSrcQuenchs,   itv),
1560                   S_VALUE(sneip->InRedirects,     sneic->InRedirects,     itv),
1561                   S_VALUE(sneip->OutRedirects,    sneic->OutRedirects,    itv));
1562         printf("\n");
1563 }
1564
1565 /*
1566  ***************************************************************************
1567  * Display TCP network traffic statistics.
1568  *
1569  * IN:
1570  * @a           Activity structure with statistics.
1571  * @prev        Index in array where stats used as reference are.
1572  * @curr        Index in array for current sample statistics.
1573  * @itv         Interval of time in 1/100th of a second.
1574  ***************************************************************************
1575  */
1576 __print_funct_t print_net_tcp_stats(struct activity *a, int prev, int curr,
1577                                     unsigned long long itv)
1578 {
1579         struct stats_net_tcp
1580                 *sntc = (struct stats_net_tcp *) a->buf[curr],
1581                 *sntp = (struct stats_net_tcp *) a->buf[prev];
1582
1583         if (dis) {
1584                 print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
1585         }
1586
1587         printf("%-11s", timestamp[curr]);
1588         cprintf_f(NO_UNIT, 4, 9, 2,
1589                   S_VALUE(sntp->ActiveOpens,  sntc->ActiveOpens,  itv),
1590                   S_VALUE(sntp->PassiveOpens, sntc->PassiveOpens, itv),
1591                   S_VALUE(sntp->InSegs,       sntc->InSegs,       itv),
1592                   S_VALUE(sntp->OutSegs,      sntc->OutSegs,      itv));
1593         printf("\n");
1594 }
1595
1596 /*
1597  ***************************************************************************
1598  * Display TCP network errors statistics.
1599  *
1600  * IN:
1601  * @a           Activity structure with statistics.
1602  * @prev        Index in array where stats used as reference are.
1603  * @curr        Index in array for current sample statistics.
1604  * @itv         Interval of time in 1/100th of a second.
1605  ***************************************************************************
1606  */
1607 __print_funct_t print_net_etcp_stats(struct activity *a, int prev, int curr,
1608                                      unsigned long long itv)
1609 {
1610         struct stats_net_etcp
1611                 *snetc = (struct stats_net_etcp *) a->buf[curr],
1612                 *snetp = (struct stats_net_etcp *) a->buf[prev];
1613
1614         if (dis) {
1615                 print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
1616         }
1617
1618         printf("%-11s", timestamp[curr]);
1619         cprintf_f(NO_UNIT, 5, 9, 2,
1620                   S_VALUE(snetp->AttemptFails, snetc->AttemptFails, itv),
1621                   S_VALUE(snetp->EstabResets,  snetc->EstabResets,  itv),
1622                   S_VALUE(snetp->RetransSegs,  snetc->RetransSegs,  itv),
1623                   S_VALUE(snetp->InErrs,       snetc->InErrs,       itv),
1624                   S_VALUE(snetp->OutRsts,      snetc->OutRsts,      itv));
1625         printf("\n");
1626 }
1627
1628 /*
1629  ***************************************************************************
1630  * Display UDP network traffic statistics.
1631  *
1632  * IN:
1633  * @a           Activity structure with statistics.
1634  * @prev        Index in array where stats used as reference are.
1635  * @curr        Index in array for current sample statistics.
1636  * @itv         Interval of time in 1/100th of a second.
1637  ***************************************************************************
1638  */
1639 __print_funct_t print_net_udp_stats(struct activity *a, int prev, int curr,
1640                                     unsigned long long itv)
1641 {
1642         struct stats_net_udp
1643                 *snuc = (struct stats_net_udp *) a->buf[curr],
1644                 *snup = (struct stats_net_udp *) a->buf[prev];
1645
1646         if (dis) {
1647                 print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
1648         }
1649
1650         printf("%-11s", timestamp[curr]);
1651         cprintf_f(NO_UNIT, 4, 9, 2,
1652                   S_VALUE(snup->InDatagrams,  snuc->InDatagrams,  itv),
1653                   S_VALUE(snup->OutDatagrams, snuc->OutDatagrams, itv),
1654                   S_VALUE(snup->NoPorts,      snuc->NoPorts,      itv),
1655                   S_VALUE(snup->InErrors,     snuc->InErrors,     itv));
1656         printf("\n");
1657 }
1658
1659 /*
1660  ***************************************************************************
1661  * Display IPv6 sockets statistics. This function is used to display
1662  * instantaneous and average statistics.
1663  *
1664  * IN:
1665  * @a           Activity structure with statistics.
1666  * @curr        Index in array for current sample statistics.
1667  * @dispavg     TRUE if displaying average statistics.
1668  ***************************************************************************
1669  */
1670 void stub_print_net_sock6_stats(struct activity *a, int curr, int dispavg)
1671 {
1672         struct stats_net_sock6
1673                 *snsc = (struct stats_net_sock6 *) a->buf[curr];
1674         static unsigned long long
1675                 avg_tcp6_inuse  = 0,
1676                 avg_udp6_inuse  = 0,
1677                 avg_raw6_inuse  = 0,
1678                 avg_frag6_inuse = 0;
1679
1680         if (dis) {
1681                 print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
1682         }
1683
1684         if (!dispavg) {
1685                 /* Display instantaneous values */
1686                 printf("%-11s", timestamp[curr]);
1687                 cprintf_u64(NO_UNIT, 4, 9,
1688                             (unsigned long long) snsc->tcp6_inuse,
1689                             (unsigned long long) snsc->udp6_inuse,
1690                             (unsigned long long) snsc->raw6_inuse,
1691                             (unsigned long long) snsc->frag6_inuse);
1692                 printf("\n");
1693
1694                 /* Will be used to compute the average */
1695                 avg_tcp6_inuse  += snsc->tcp6_inuse;
1696                 avg_udp6_inuse  += snsc->udp6_inuse;
1697                 avg_raw6_inuse  += snsc->raw6_inuse;
1698                 avg_frag6_inuse += snsc->frag6_inuse;
1699         }
1700         else {
1701                 /* Display average values */
1702                 printf("%-11s", timestamp[curr]);
1703                 cprintf_f(NO_UNIT, 4, 9, 0,
1704                           (double) avg_tcp6_inuse  / avg_count,
1705                           (double) avg_udp6_inuse  / avg_count,
1706                           (double) avg_raw6_inuse  / avg_count,
1707                           (double) avg_frag6_inuse / avg_count);
1708                 printf("\n");
1709
1710                 /* Reset average counters */
1711                 avg_tcp6_inuse = avg_udp6_inuse = avg_raw6_inuse = avg_frag6_inuse = 0;
1712         }
1713 }
1714
1715 /*
1716  ***************************************************************************
1717  * Display IPv6 sockets statistics.
1718  *
1719  * IN:
1720  * @a           Activity structure with statistics.
1721  * @prev        Index in array where stats used as reference are.
1722  * @curr        Index in array for current sample statistics.
1723  * @itv         Interval of time in 1/100th of a second.
1724  ***************************************************************************
1725  */
1726 __print_funct_t print_net_sock6_stats(struct activity *a, int prev, int curr,
1727                                       unsigned long long itv)
1728 {
1729         stub_print_net_sock6_stats(a, curr, FALSE);
1730 }
1731
1732 /*
1733  ***************************************************************************
1734  * Display average IPv6 sockets statistics.
1735  *
1736  * IN:
1737  * @a           Activity structure with statistics.
1738  * @prev        Index in array where stats used as reference are.
1739  * @curr        Index in array for current sample statistics.
1740  * @itv         Interval of time in 1/100th of a second.
1741  ***************************************************************************
1742  */
1743 __print_funct_t print_avg_net_sock6_stats(struct activity *a, int prev, int curr,
1744                                           unsigned long long itv)
1745 {
1746         stub_print_net_sock6_stats(a, curr, TRUE);
1747 }
1748
1749 /*
1750  ***************************************************************************
1751  * Display IPv6 network traffic statistics.
1752  *
1753  * IN:
1754  * @a           Activity structure with statistics.
1755  * @prev        Index in array where stats used as reference are.
1756  * @curr        Index in array for current sample statistics.
1757  * @itv         Interval of time in 1/100th of a second.
1758  ***************************************************************************
1759  */
1760 __print_funct_t print_net_ip6_stats(struct activity *a, int prev, int curr,
1761                                     unsigned long long itv)
1762 {
1763         struct stats_net_ip6
1764                 *snic = (struct stats_net_ip6 *) a->buf[curr],
1765                 *snip = (struct stats_net_ip6 *) a->buf[prev];
1766
1767         if (dis) {
1768                 print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
1769         }
1770
1771         printf("%-11s", timestamp[curr]);
1772         cprintf_f(NO_UNIT, 10, 9, 2,
1773                   S_VALUE(snip->InReceives6,       snic->InReceives6,       itv),
1774                   S_VALUE(snip->OutForwDatagrams6, snic->OutForwDatagrams6, itv),
1775                   S_VALUE(snip->InDelivers6,       snic->InDelivers6,       itv),
1776                   S_VALUE(snip->OutRequests6,      snic->OutRequests6,      itv),
1777                   S_VALUE(snip->ReasmReqds6,       snic->ReasmReqds6,       itv),
1778                   S_VALUE(snip->ReasmOKs6,         snic->ReasmOKs6,         itv),
1779                   S_VALUE(snip->InMcastPkts6,      snic->InMcastPkts6,      itv),
1780                   S_VALUE(snip->OutMcastPkts6,     snic->OutMcastPkts6,     itv),
1781                   S_VALUE(snip->FragOKs6,          snic->FragOKs6,          itv),
1782                   S_VALUE(snip->FragCreates6,      snic->FragCreates6,      itv));
1783         printf("\n");
1784 }
1785
1786 /*
1787  ***************************************************************************
1788  * Display IPv6 network errors statistics.
1789  *
1790  * IN:
1791  * @a           Activity structure with statistics.
1792  * @prev        Index in array where stats used as reference are.
1793  * @curr        Index in array for current sample statistics.
1794  * @itv         Interval of time in 1/100th of a second.
1795  ***************************************************************************
1796  */
1797 __print_funct_t print_net_eip6_stats(struct activity *a, int prev, int curr,
1798                                      unsigned long long itv)
1799 {
1800         struct stats_net_eip6
1801                 *sneic = (struct stats_net_eip6 *) a->buf[curr],
1802                 *sneip = (struct stats_net_eip6 *) a->buf[prev];
1803
1804         if (dis) {
1805                 print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
1806         }
1807
1808         printf("%-11s", timestamp[curr]);
1809         cprintf_f(NO_UNIT, 11, 9, 2,
1810                   S_VALUE(sneip->InHdrErrors6,     sneic->InHdrErrors6,     itv),
1811                   S_VALUE(sneip->InAddrErrors6,    sneic->InAddrErrors6,    itv),
1812                   S_VALUE(sneip->InUnknownProtos6, sneic->InUnknownProtos6, itv),
1813                   S_VALUE(sneip->InTooBigErrors6,  sneic->InTooBigErrors6,  itv),
1814                   S_VALUE(sneip->InDiscards6,      sneic->InDiscards6,      itv),
1815                   S_VALUE(sneip->OutDiscards6,     sneic->OutDiscards6,     itv),
1816                   S_VALUE(sneip->InNoRoutes6,      sneic->InNoRoutes6,      itv),
1817                   S_VALUE(sneip->OutNoRoutes6,     sneic->OutNoRoutes6,     itv),
1818                   S_VALUE(sneip->ReasmFails6,      sneic->ReasmFails6,      itv),
1819                   S_VALUE(sneip->FragFails6,       sneic->FragFails6,       itv),
1820                   S_VALUE(sneip->InTruncatedPkts6, sneic->InTruncatedPkts6, itv));
1821         printf("\n");
1822 }
1823
1824 /*
1825  ***************************************************************************
1826  * Display ICMPv6 network traffic statistics.
1827  *
1828  * IN:
1829  * @a           Activity structure with statistics.
1830  * @prev        Index in array where stats used as reference are.
1831  * @curr        Index in array for current sample statistics.
1832  * @itv         Interval of time in 1/100th of a second.
1833  ***************************************************************************
1834  */
1835 __print_funct_t print_net_icmp6_stats(struct activity *a, int prev, int curr,
1836                                       unsigned long long itv)
1837 {
1838         struct stats_net_icmp6
1839                 *snic = (struct stats_net_icmp6 *) a->buf[curr],
1840                 *snip = (struct stats_net_icmp6 *) a->buf[prev];
1841
1842         if (dis) {
1843                 print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
1844         }
1845
1846         printf("%-11s", timestamp[curr]);
1847         cprintf_f(NO_UNIT, 17, 9, 2,
1848                   S_VALUE(snip->InMsgs6,                    snic->InMsgs6,                    itv),
1849                   S_VALUE(snip->OutMsgs6,                   snic->OutMsgs6,                   itv),
1850                   S_VALUE(snip->InEchos6,                   snic->InEchos6,                   itv),
1851                   S_VALUE(snip->InEchoReplies6,             snic->InEchoReplies6,             itv),
1852                   S_VALUE(snip->OutEchoReplies6,            snic->OutEchoReplies6,            itv),
1853                   S_VALUE(snip->InGroupMembQueries6,        snic->InGroupMembQueries6,        itv),
1854                   S_VALUE(snip->InGroupMembResponses6,      snic->InGroupMembResponses6,      itv),
1855                   S_VALUE(snip->OutGroupMembResponses6,     snic->OutGroupMembResponses6,     itv),
1856                   S_VALUE(snip->InGroupMembReductions6,     snic->InGroupMembReductions6,     itv),
1857                   S_VALUE(snip->OutGroupMembReductions6,    snic->OutGroupMembReductions6,    itv),
1858                   S_VALUE(snip->InRouterSolicits6,          snic->InRouterSolicits6,          itv),
1859                   S_VALUE(snip->OutRouterSolicits6,         snic->OutRouterSolicits6,         itv),
1860                   S_VALUE(snip->InRouterAdvertisements6,    snic->InRouterAdvertisements6,    itv),
1861                   S_VALUE(snip->InNeighborSolicits6,        snic->InNeighborSolicits6,        itv),
1862                   S_VALUE(snip->OutNeighborSolicits6,       snic->OutNeighborSolicits6,       itv),
1863                   S_VALUE(snip->InNeighborAdvertisements6,  snic->InNeighborAdvertisements6,  itv),
1864                   S_VALUE(snip->OutNeighborAdvertisements6, snic->OutNeighborAdvertisements6, itv));
1865         printf("\n");
1866 }
1867
1868 /*
1869  ***************************************************************************
1870  * Display ICMPv6 network errors statistics.
1871  *
1872  * IN:
1873  * @a           Activity structure with statistics.
1874  * @prev        Index in array where stats used as reference are.
1875  * @curr        Index in array for current sample statistics.
1876  * @itv         Interval of time in 1/100th of a second.
1877  ***************************************************************************
1878  */
1879 __print_funct_t print_net_eicmp6_stats(struct activity *a, int prev, int curr,
1880                                        unsigned long long itv)
1881 {
1882         struct stats_net_eicmp6
1883                 *sneic = (struct stats_net_eicmp6 *) a->buf[curr],
1884                 *sneip = (struct stats_net_eicmp6 *) a->buf[prev];
1885
1886         if (dis) {
1887                 print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
1888         }
1889
1890         printf("%-11s", timestamp[curr]);
1891         cprintf_f(NO_UNIT, 11, 9, 2,
1892                   S_VALUE(sneip->InErrors6,        sneic->InErrors6,        itv),
1893                   S_VALUE(sneip->InDestUnreachs6,  sneic->InDestUnreachs6,  itv),
1894                   S_VALUE(sneip->OutDestUnreachs6, sneic->OutDestUnreachs6, itv),
1895                   S_VALUE(sneip->InTimeExcds6,     sneic->InTimeExcds6,     itv),
1896                   S_VALUE(sneip->OutTimeExcds6,    sneic->OutTimeExcds6,    itv),
1897                   S_VALUE(sneip->InParmProblems6,  sneic->InParmProblems6,  itv),
1898                   S_VALUE(sneip->OutParmProblems6, sneic->OutParmProblems6, itv),
1899                   S_VALUE(sneip->InRedirects6,     sneic->InRedirects6,     itv),
1900                   S_VALUE(sneip->OutRedirects6,    sneic->OutRedirects6,    itv),
1901                   S_VALUE(sneip->InPktTooBigs6,    sneic->InPktTooBigs6,    itv),
1902                   S_VALUE(sneip->OutPktTooBigs6,   sneic->OutPktTooBigs6,   itv));
1903         printf("\n");
1904 }
1905
1906 /*
1907  ***************************************************************************
1908  * Display UDPv6 network traffic statistics.
1909  *
1910  * IN:
1911  * @a           Activity structure with statistics.
1912  * @prev        Index in array where stats used as reference are.
1913  * @curr        Index in array for current sample statistics.
1914  * @itv         Interval of time in 1/100th of a second.
1915  ***************************************************************************
1916  */
1917 __print_funct_t print_net_udp6_stats(struct activity *a, int prev, int curr,
1918                                      unsigned long long itv)
1919 {
1920         struct stats_net_udp6
1921                 *snuc = (struct stats_net_udp6 *) a->buf[curr],
1922                 *snup = (struct stats_net_udp6 *) a->buf[prev];
1923
1924         if (dis) {
1925                 print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
1926         }
1927
1928         printf("%-11s", timestamp[curr]);
1929         cprintf_f(NO_UNIT, 4, 9, 2,
1930                   S_VALUE(snup->InDatagrams6,  snuc->InDatagrams6,  itv),
1931                   S_VALUE(snup->OutDatagrams6, snuc->OutDatagrams6, itv),
1932                   S_VALUE(snup->NoPorts6,      snuc->NoPorts6,      itv),
1933                   S_VALUE(snup->InErrors6,     snuc->InErrors6,     itv));
1934         printf("\n");
1935 }
1936
1937 /*
1938  ***************************************************************************
1939  * Display CPU frequency statistics. This function is used to display
1940  * instantaneous and average statistics.
1941  *
1942  * IN:
1943  * @a           Activity structure with statistics.
1944  * @curr        Index in array for current sample statistics.
1945  * @dispavg     True if displaying average statistics.
1946  ***************************************************************************
1947  */
1948 void stub_print_pwr_cpufreq_stats(struct activity *a, int curr, int dispavg)
1949 {
1950         int i;
1951         struct stats_pwr_cpufreq *spc;
1952         static __nr_t nr_alloc = 0;
1953         static unsigned long long
1954                 *avg_cpufreq = NULL;
1955
1956         if (!avg_cpufreq || (a->nr[curr] > nr_alloc)) {
1957                 /* Allocate array of CPU frequency */
1958                 SREALLOC(avg_cpufreq, unsigned long long, sizeof(unsigned long long) * a->nr[curr]);
1959                 if (a->nr[curr] > nr_alloc) {
1960                         /* Init additional space allocated */
1961                         memset(avg_cpufreq + nr_alloc, 0,
1962                                sizeof(unsigned long long) * (a->nr[curr] - nr_alloc));
1963                 }
1964                 nr_alloc = a->nr[curr];
1965         }
1966
1967         if (dis) {
1968                 print_hdr_line(timestamp[!curr], a, FIRST, 7, 9);
1969         }
1970
1971         for (i = 0; (i < a->nr[curr]) && (i < a->bitmap->b_size + 1); i++) {
1972
1973                 /*
1974                  * The size of a->buf[...] CPU structure may be different from the default
1975                  * sizeof(struct stats_pwr_cpufreq) value if data have been read from a file!
1976                  * That's why we don't use a syntax like:
1977                  * spc = (struct stats_pwr_cpufreq *) a->buf[...] + i;
1978                  */
1979                 spc = (struct stats_pwr_cpufreq *) ((char *) a->buf[curr] + i * a->msize);
1980
1981                 if (!spc->cpufreq)
1982                         /* This CPU is offline: Don't display it */
1983                         continue;
1984
1985                 /*
1986                  * Note: @nr[curr] is in [1, NR_CPUS + 1].
1987                  * Bitmap size is provided for (NR_CPUS + 1) CPUs.
1988                  * Anyway, NR_CPUS may vary between the version of sysstat
1989                  * used by sadc to create a file, and the version of sysstat
1990                  * used by sar to read it...
1991                  */
1992
1993                 /* Should current CPU (including CPU "all") be displayed? */
1994                 if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))))
1995                         /* No */
1996                         continue;
1997
1998                 printf("%-11s", timestamp[curr]);
1999
2000                 if (!i) {
2001                         /* This is CPU "all" */
2002                         cprintf_in(IS_STR, "%s", "     all", 0);
2003                 }
2004                 else {
2005                         cprintf_in(IS_INT, "     %3d", "", i - 1);
2006                 }
2007
2008                 if (!dispavg) {
2009                         /* Display instantaneous values */
2010                         cprintf_f(NO_UNIT, 1, 9, 2,
2011                                   ((double) spc->cpufreq) / 100);
2012                         printf("\n");
2013                         /*
2014                          * Will be used to compute the average.
2015                          * Note: Overflow unlikely to happen but not impossible...
2016                          */
2017                         avg_cpufreq[i] += spc->cpufreq;
2018                 }
2019                 else {
2020                         /* Display average values */
2021                         cprintf_f(NO_UNIT, 1, 9, 2,
2022                                   (double) avg_cpufreq[i] / (100 * avg_count));
2023                         printf("\n");
2024                 }
2025         }
2026
2027         if (dispavg && avg_cpufreq) {
2028                 /* Array of CPU frequency no longer needed: Free it! */
2029                 free(avg_cpufreq);
2030                 avg_cpufreq = NULL;
2031                 nr_alloc = 0;
2032         }
2033 }
2034
2035 /*
2036  ***************************************************************************
2037  * Display CPU frequency statistics.
2038  *
2039  * IN:
2040  * @a           Activity structure with statistics.
2041  * @prev        Index in array where stats used as reference are.
2042  * @curr        Index in array for current sample statistics.
2043  * @itv         Interval of time in 1/100th of a second.
2044  ***************************************************************************
2045  */
2046 __print_funct_t print_pwr_cpufreq_stats(struct activity *a, int prev, int curr,
2047                                         unsigned long long itv)
2048 {
2049         stub_print_pwr_cpufreq_stats(a, curr, FALSE);
2050 }
2051
2052 /*
2053  ***************************************************************************
2054  * Display average CPU frequency statistics.
2055  *
2056  * IN:
2057  * @a           Activity structure with statistics.
2058  * @prev        Index in array where stats used as reference are.
2059  * @curr        Index in array for current sample statistics.
2060  * @itv         Interval of time in 1/100th of a second.
2061  ***************************************************************************
2062  */
2063 __print_funct_t print_avg_pwr_cpufreq_stats(struct activity *a, int prev, int curr,
2064                                             unsigned long long itv)
2065 {
2066         stub_print_pwr_cpufreq_stats(a, curr, TRUE);
2067 }
2068
2069 /*
2070  ***************************************************************************
2071  * Display fan statistics. This function is used to display
2072  * instantaneous and average statistics.
2073  *
2074  * IN:
2075  * @a           Activity structure with statistics.
2076  * @curr        Index in array for current sample statistics.
2077  * @dispavg     True if displaying average statistics.
2078  ***************************************************************************
2079  */
2080 void stub_print_pwr_fan_stats(struct activity *a, int curr, int dispavg)
2081 {
2082         int i;
2083         struct stats_pwr_fan *spc;
2084         static __nr_t nr_alloc = 0;
2085         static double *avg_fan = NULL;
2086         static double *avg_fan_min = NULL;
2087
2088         /* Allocate arrays of fan RPMs */
2089         if (!avg_fan || (a->nr[curr] > nr_alloc)) {
2090                 SREALLOC(avg_fan, double, sizeof(double) * a->nr[curr]);
2091                 SREALLOC(avg_fan_min, double, sizeof(double) * a->nr[curr]);
2092
2093                 if (a->nr[curr] > nr_alloc) {
2094                         /* Init additional space allocated */
2095                         memset(avg_fan + nr_alloc, 0,
2096                                sizeof(double) * (a->nr[curr] - nr_alloc));
2097                         memset(avg_fan_min + nr_alloc, 0,
2098                                sizeof(double) * (a->nr[curr] - nr_alloc));
2099                 }
2100                 nr_alloc = a->nr[curr];
2101         }
2102
2103         if (dis) {
2104                 print_hdr_line(timestamp[!curr], a, FIRST, -2, 9);
2105         }
2106
2107         for (i = 0; i < a->nr[curr]; i++) {
2108                 spc = (struct stats_pwr_fan *) ((char *) a->buf[curr] + i * a->msize);
2109
2110                 printf("%-11s", timestamp[curr]);
2111                 cprintf_in(IS_INT, "     %5d", "", i + 1);
2112
2113                 if (dispavg) {
2114                         /* Display average values */
2115                         cprintf_f(NO_UNIT, 2, 9, 2,
2116                                   (double) avg_fan[i] / avg_count,
2117                                   (double) (avg_fan[i] - avg_fan_min[i]) / avg_count);
2118                 }
2119                 else {
2120                         /* Display instantaneous values */
2121                         cprintf_f(NO_UNIT, 2, 9, 2,
2122                                   spc->rpm,
2123                                   spc->rpm - spc->rpm_min);
2124                         avg_fan[i]     += spc->rpm;
2125                         avg_fan_min[i] += spc->rpm_min;
2126                 }
2127
2128                 cprintf_in(IS_STR, " %s\n", spc->device, 0);
2129         }
2130
2131         if (dispavg && avg_fan) {
2132                 free(avg_fan);
2133                 free(avg_fan_min);
2134                 avg_fan = NULL;
2135                 avg_fan_min = NULL;
2136                 nr_alloc = 0;
2137         }
2138 }
2139
2140 /*
2141  ***************************************************************************
2142  * Display fan statistics.
2143  *
2144  * IN:
2145  * @a           Activity structure with statistics.
2146  * @prev        Index in array where stats used as reference are.
2147  * @curr        Index in array for current sample statistics.
2148  * @itv         Interval of time in 1/100th of a second.
2149  ***************************************************************************
2150  */
2151 __print_funct_t print_pwr_fan_stats(struct activity *a, int prev, int curr,
2152                                     unsigned long long itv)
2153 {
2154         stub_print_pwr_fan_stats(a, curr, FALSE);
2155 }
2156
2157 /*
2158  ***************************************************************************
2159  * Display average fan statistics.
2160  *
2161  * IN:
2162  * @a           Activity structure with statistics.
2163  * @prev        Index in array where stats used as reference are.
2164  * @curr        Index in array for current sample statistics.
2165  * @itv         Interval of time in 1/100th of a second.
2166  ***************************************************************************
2167  */
2168 __print_funct_t print_avg_pwr_fan_stats(struct activity *a, int prev, int curr,
2169                                         unsigned long long itv)
2170 {
2171         stub_print_pwr_fan_stats(a, curr, TRUE);
2172 }
2173
2174 /*
2175  ***************************************************************************
2176  * Display device temperature statistics. This function is used to display
2177  * instantaneous and average statistics.
2178  *
2179  * IN:
2180  * @a           Activity structure with statistics.
2181  * @curr        Index in array for current sample statistics.
2182  * @dispavg     True if displaying average statistics.
2183  ***************************************************************************
2184  */
2185 void stub_print_pwr_temp_stats(struct activity *a, int curr, int dispavg)
2186 {
2187         int i;
2188         struct stats_pwr_temp *spc;
2189         static __nr_t nr_alloc = 0;
2190         static double *avg_temp = NULL;
2191         static double *avg_temp_min = NULL, *avg_temp_max = NULL;
2192
2193         /* Allocate arrays of temperatures */
2194         if (!avg_temp || (a->nr[curr] > nr_alloc)) {
2195                 SREALLOC(avg_temp, double, sizeof(double) * a->nr[curr]);
2196                 SREALLOC(avg_temp_min, double, sizeof(double) * a->nr[curr]);
2197                 SREALLOC(avg_temp_max, double, sizeof(double) * a->nr[curr]);
2198
2199                 if (a->nr[curr] > nr_alloc) {
2200                         /* Init additional space allocated */
2201                         memset(avg_temp + nr_alloc, 0,
2202                                sizeof(double) * (a->nr[curr] - nr_alloc));
2203                         memset(avg_temp_min + nr_alloc, 0,
2204                                sizeof(double) * (a->nr[curr] - nr_alloc));
2205                         memset(avg_temp_max + nr_alloc, 0,
2206                                sizeof(double) * (a->nr[curr] - nr_alloc));
2207                 }
2208                 nr_alloc = a->nr[curr];
2209         }
2210
2211         if (dis) {
2212                 print_hdr_line(timestamp[!curr], a, FIRST, -2, 9);
2213         }
2214
2215         for (i = 0; i < a->nr[curr]; i++) {
2216                 spc = (struct stats_pwr_temp *) ((char *) a->buf[curr] + i * a->msize);
2217
2218                 printf("%-11s", timestamp[curr]);
2219                 cprintf_in(IS_INT, "     %5d", "", i + 1);
2220
2221                 if (dispavg) {
2222                         /* Display average values */
2223                         cprintf_f(NO_UNIT, 1, 9, 2, (double) avg_temp[i] / avg_count);
2224                         cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2,
2225                                    (avg_temp_max[i] - avg_temp_min[i]) ?
2226                                    ((double) (avg_temp[i] / avg_count) - avg_temp_min[i]) / (avg_temp_max[i] - avg_temp_min[i]) * 100
2227                                    : 0.0);
2228                 }
2229                 else {
2230                         /* Display instantaneous values */
2231                         cprintf_f(NO_UNIT, 1, 9, 2, spc->temp);
2232                         cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2,
2233                                    (spc->temp_max - spc->temp_min) ?
2234                                    (spc->temp - spc->temp_min) / (spc->temp_max - spc->temp_min) * 100
2235                                    : 0.0);
2236                         avg_temp[i] += spc->temp;
2237                         /* Assume that min and max temperatures cannot vary */
2238                         avg_temp_min[i] = spc->temp_min;
2239                         avg_temp_max[i] = spc->temp_max;
2240                 }
2241
2242                 cprintf_in(IS_STR, " %s\n", spc->device, 0);
2243         }
2244
2245         if (dispavg && avg_temp) {
2246                 free(avg_temp);
2247                 free(avg_temp_min);
2248                 free(avg_temp_max);
2249                 avg_temp = NULL;
2250                 avg_temp_min = NULL;
2251                 avg_temp_max = NULL;
2252                 nr_alloc = 0;
2253         }
2254 }
2255
2256 /*
2257  ***************************************************************************
2258  * Display temperature statistics.
2259  *
2260  * IN:
2261  * @a           Activity structure with statistics.
2262  * @prev        Index in array where stats used as reference are.
2263  * @curr        Index in array for current sample statistics.
2264  * @itv         Interval of time in 1/100th of a second.
2265  ***************************************************************************
2266  */
2267 __print_funct_t print_pwr_temp_stats(struct activity *a, int prev, int curr,
2268                                      unsigned long long itv)
2269 {
2270         stub_print_pwr_temp_stats(a, curr, FALSE);
2271 }
2272
2273 /*
2274  ***************************************************************************
2275  * Display average temperature statistics.
2276  *
2277  * IN:
2278  * @a           Activity structure with statistics.
2279  * @prev        Index in array where stats used as reference are.
2280  * @curr        Index in array for current sample statistics.
2281  * @itv         Interval of time in 1/100th of a second.
2282  ***************************************************************************
2283  */
2284 __print_funct_t print_avg_pwr_temp_stats(struct activity *a, int prev, int curr,
2285                                          unsigned long long itv)
2286 {
2287         stub_print_pwr_temp_stats(a, curr, TRUE);
2288 }
2289
2290 /*
2291  ***************************************************************************
2292  * Display voltage inputs statistics. This function is used to display
2293  * instantaneous and average statistics.
2294  *
2295  * IN:
2296  * @a           Activity structure with statistics.
2297  * @curr        Index in array for current sample statistics.
2298  * @dispavg     True if displaying average statistics.
2299  ***************************************************************************
2300  */
2301 void stub_print_pwr_in_stats(struct activity *a, int curr, int dispavg)
2302 {
2303         int i;
2304         struct stats_pwr_in *spc;
2305         static __nr_t nr_alloc = 0;
2306         static double *avg_in = NULL;
2307         static double *avg_in_min = NULL, *avg_in_max = NULL;
2308
2309         /* Allocate arrays of voltage inputs */
2310         if (!avg_in || (a->nr[curr] > nr_alloc)) {
2311                 SREALLOC(avg_in, double, sizeof(double) * a->nr[curr]);
2312                 SREALLOC(avg_in_min, double, sizeof(double) * a->nr[curr]);
2313                 SREALLOC(avg_in_max, double, sizeof(double) * a->nr[curr]);
2314
2315                 if (a->nr[curr] > nr_alloc) {
2316                         /* Init additional space allocated */
2317                         memset(avg_in + nr_alloc, 0,
2318                                sizeof(double) * (a->nr[curr] - nr_alloc));
2319                         memset(avg_in_min + nr_alloc, 0,
2320                                sizeof(double) * (a->nr[curr] - nr_alloc));
2321                         memset(avg_in_max + nr_alloc, 0,
2322                                sizeof(double) * (a->nr[curr] - nr_alloc));
2323                 }
2324                 nr_alloc = a->nr[curr];
2325         }
2326
2327         if (dis) {
2328                 print_hdr_line(timestamp[!curr], a, FIRST, -2, 9);
2329         }
2330
2331         for (i = 0; i < a->nr[curr]; i++) {
2332                 spc = (struct stats_pwr_in *) ((char *) a->buf[curr] + i * a->msize);
2333
2334                 printf("%-11s", timestamp[curr]);
2335                 cprintf_in(IS_INT, "     %5d", "", i);
2336
2337                 if (dispavg) {
2338                         /* Display average values */
2339                         cprintf_f(NO_UNIT, 1, 9, 2, (double) avg_in[i] / avg_count);
2340                         cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2,
2341                                    (avg_in_max[i] - avg_in_min[i]) ?
2342                                    ((double) (avg_in[i] / avg_count) - avg_in_min[i]) / (avg_in_max[i] - avg_in_min[i]) * 100
2343                                    : 0.0);
2344                 }
2345                 else {
2346                         /* Display instantaneous values */
2347                         cprintf_f(NO_UNIT, 1, 9, 2, spc->in);
2348                         cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2,
2349                                    (spc->in_max - spc->in_min) ?
2350                                    (spc->in - spc->in_min) / (spc->in_max - spc->in_min) * 100
2351                                    : 0.0);
2352                         avg_in[i] += spc->in;
2353                         /* Assume that min and max voltage inputs cannot vary */
2354                         avg_in_min[i] = spc->in_min;
2355                         avg_in_max[i] = spc->in_max;
2356                 }
2357
2358                 cprintf_in(IS_STR, " %s\n", spc->device, 0);
2359         }
2360
2361         if (dispavg && avg_in) {
2362                 free(avg_in);
2363                 free(avg_in_min);
2364                 free(avg_in_max);
2365                 avg_in = NULL;
2366                 avg_in_min = NULL;
2367                 avg_in_max = NULL;
2368                 nr_alloc = 0;
2369         }
2370 }
2371
2372 /*
2373  ***************************************************************************
2374  * Display voltage inputs statistics.
2375  *
2376  * IN:
2377  * @a           Activity structure with statistics.
2378  * @prev        Index in array where stats used as reference are.
2379  * @curr        Index in array for current sample statistics.
2380  * @itv         Interval of time in 1/100th of a second.
2381  ***************************************************************************
2382  */
2383 __print_funct_t print_pwr_in_stats(struct activity *a, int prev, int curr,
2384                                    unsigned long long itv)
2385 {
2386         stub_print_pwr_in_stats(a, curr, FALSE);
2387 }
2388
2389 /*
2390  ***************************************************************************
2391  * Display average voltage inputs statistics.
2392  *
2393  * IN:
2394  * @a           Activity structure with statistics.
2395  * @prev        Index in array where stats used as reference are.
2396  * @curr        Index in array for current sample statistics.
2397  * @itv         Interval of time in 1/100th of a second.
2398  ***************************************************************************
2399  */
2400 __print_funct_t print_avg_pwr_in_stats(struct activity *a, int prev, int curr,
2401                                        unsigned long long itv)
2402 {
2403         stub_print_pwr_in_stats(a, curr, TRUE);
2404 }
2405
2406 /*
2407  ***************************************************************************
2408  * Display huge pages statistics. This function is used to
2409  * display instantaneous and average statistics.
2410  *
2411  * IN:
2412  * @a           Activity structure with statistics.
2413  * @curr        Index in array for current sample statistics.
2414  * @dispavg     TRUE if displaying average statistics.
2415  ***************************************************************************
2416  */
2417 void stub_print_huge_stats(struct activity *a, int curr, int dispavg)
2418 {
2419         struct stats_huge
2420                 *smc = (struct stats_huge *) a->buf[curr];
2421         static unsigned long long
2422                 avg_frhkb = 0,
2423                 avg_tlhkb = 0;
2424         int unit = NO_UNIT;
2425
2426         if (DISPLAY_UNIT(flags)) {
2427                 /* Default values unit is kB */
2428                 unit = UNIT_KILOBYTE;
2429         }
2430
2431         if (dis) {
2432                 print_hdr_line(timestamp[!curr], a, FIRST, 0, 9);
2433         }
2434
2435         if (!dispavg) {
2436                 /* Display instantaneous values */
2437                 printf("%-11s", timestamp[curr]);
2438                 cprintf_u64(unit, 2, 9,
2439                             (unsigned long long) smc->frhkb,
2440                             (unsigned long long) (smc->tlhkb - smc->frhkb));
2441                 cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2,
2442                            smc->tlhkb ?
2443                            SP_VALUE(smc->frhkb, smc->tlhkb, smc->tlhkb) : 0.0);
2444                 printf("\n");
2445
2446                 /* Will be used to compute the average */
2447                 avg_frhkb += smc->frhkb;
2448                 avg_tlhkb += smc->tlhkb;
2449         }
2450         else {
2451                 /* Display average values */
2452                 printf("%-11s", timestamp[curr]);
2453                 cprintf_f(unit, 2, 9, 0,
2454                           (double) avg_frhkb / avg_count,
2455                           ((double) avg_tlhkb / avg_count) -
2456                           ((double) avg_frhkb / avg_count));
2457                 cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2,
2458                            avg_tlhkb ?
2459                            SP_VALUE((double) avg_frhkb / avg_count,
2460                                     (double) avg_tlhkb / avg_count,
2461                                     (double) avg_tlhkb / avg_count) : 0.0);
2462                 printf("\n");
2463
2464                 /* Reset average counters */
2465                 avg_frhkb = avg_tlhkb = 0;
2466         }
2467 }
2468
2469 /*
2470  ***************************************************************************
2471  * Display huge pages statistics.
2472  *
2473  * IN:
2474  * @a           Activity structure with statistics.
2475  * @prev        Index in array where stats used as reference are.
2476  * @curr        Index in array for current sample statistics.
2477  * @itv         Interval of time in 1/100th of a second.
2478  ***************************************************************************
2479  */
2480 __print_funct_t print_huge_stats(struct activity *a, int prev, int curr,
2481                                  unsigned long long itv)
2482 {
2483         stub_print_huge_stats(a, curr, FALSE);
2484 }
2485
2486 /*
2487  ***************************************************************************
2488  * Display huge pages statistics.
2489  *
2490  * IN:
2491  * @a           Activity structure with statistics.
2492  * @prev        Index in array where stats used as reference are.
2493  * @curr        Index in array for current sample statistics.
2494  * @itv         Interval of time in 1/100th of a second.
2495  ***************************************************************************
2496  */
2497 __print_funct_t print_avg_huge_stats(struct activity *a, int prev, int curr,
2498                                      unsigned long long itv)
2499 {
2500         stub_print_huge_stats(a, curr, TRUE);
2501 }
2502
2503 /*
2504  ***************************************************************************
2505  * Display CPU weighted frequency statistics. This function is used to
2506  * display instantaneous and average statistics.
2507  *
2508  * IN:
2509  * @a           Activity structure with statistics.
2510  * @prev        Index in array where stats used as reference are.
2511  * @curr        Index in array for current sample statistics.
2512  * @itv         Interval of time in 1/100th of a second.
2513  ***************************************************************************
2514  */
2515 void print_pwr_wghfreq_stats(struct activity *a, int prev, int curr,
2516                              unsigned long long itv)
2517 {
2518         int i, k;
2519         struct stats_pwr_wghfreq *spc, *spp, *spc_k, *spp_k;
2520         unsigned long long tis, tisfreq;
2521
2522         if (dis) {
2523                 print_hdr_line(timestamp[!curr], a, FIRST, 7, 9);
2524         }
2525
2526         for (i = 0; (i < a->nr[curr]) && (i < a->bitmap->b_size + 1); i++) {
2527
2528                 /*
2529                  * The size of a->buf[...] CPU structure may be different from the default
2530                  * sizeof(struct stats_pwr_wghfreq) value if data have been read from a file!
2531                  * That's why we don't use a syntax like:
2532                  * spc = (struct stats_pwr_wghfreq *) a->buf[...] + i;
2533                  */
2534                 spc = (struct stats_pwr_wghfreq *) ((char *) a->buf[curr] + i * a->msize * a->nr2);
2535                 spp = (struct stats_pwr_wghfreq *) ((char *) a->buf[prev] + i * a->msize * a->nr2);
2536
2537                 /*
2538                  * Note: a->nr is in [1, NR_CPUS + 1].
2539                  * Bitmap size is provided for (NR_CPUS + 1) CPUs.
2540                  * Anyway, NR_CPUS may vary between the version of sysstat
2541                  * used by sadc to create a file, and the version of sysstat
2542                  * used by sar to read it...
2543                  */
2544
2545                 /* Should current CPU (including CPU "all") be displayed? */
2546                 if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))))
2547                         /* No */
2548                         continue;
2549
2550                 /* Yes: Display it */
2551                 printf("%-11s", timestamp[curr]);
2552
2553                 if (!i) {
2554                         /* This is CPU "all" */
2555                         cprintf_in(IS_STR, "%s", "     all", 0);
2556                 }
2557                 else {
2558                         cprintf_in(IS_INT, "     %3d", "", i - 1);
2559                 }
2560
2561                 tisfreq = 0;
2562                 tis = 0;
2563
2564                 for (k = 0; k < a->nr2; k++) {
2565
2566                         spc_k = (struct stats_pwr_wghfreq *) ((char *) spc + k * a->msize);
2567                         if (!spc_k->freq)
2568                                 break;
2569                         spp_k = (struct stats_pwr_wghfreq *) ((char *) spp + k * a->msize);
2570
2571                         tisfreq += (spc_k->freq / 1000) *
2572                                    (spc_k->time_in_state - spp_k->time_in_state);
2573                         tis     += (spc_k->time_in_state - spp_k->time_in_state);
2574                 }
2575
2576                 /* Display weighted frequency for current CPU */
2577                 cprintf_f(NO_UNIT, 1, 9, 2,
2578                           tis ? ((double) tisfreq) / tis : 0.0);
2579                 printf("\n");
2580         }
2581 }
2582
2583 /*
2584  ***************************************************************************
2585  * Display USB devices statistics. This function is used to
2586  * display instantaneous and summary statistics.
2587  *
2588  * IN:
2589  * @a           Activity structure with statistics.
2590  * @curr        Index in array for current sample statistics.
2591  * @dispavg     TRUE if displaying average statistics.
2592  ***************************************************************************
2593  */
2594 void stub_print_pwr_usb_stats(struct activity *a, int curr, int dispavg)
2595 {
2596         int i, j;
2597         char fmt[16];
2598         struct stats_pwr_usb *suc, *sum;
2599
2600         if (dis) {
2601                 printf("\n%-11s     BUS  idvendor    idprod  maxpower",
2602                        (dispavg ? _("Summary:") : timestamp[!curr]));
2603                 printf(" %-*s product\n", MAX_MANUF_LEN - 1, "manufact");
2604         }
2605
2606         for (i = 0; i < a->nr[curr]; i++) {
2607                 suc = (struct stats_pwr_usb *) ((char *) a->buf[curr] + i * a->msize);
2608
2609                 printf("%-11s", (dispavg ? _("Summary:") : timestamp[curr]));
2610                 cprintf_in(IS_INT, "  %6d", "", suc->bus_nr);
2611                 cprintf_x(2, 9,
2612                           suc->vendor_id,
2613                           suc->product_id);
2614                 cprintf_u64(NO_UNIT, 1, 9,
2615                             /* bMaxPower is expressed in 2 mA units */
2616                             (unsigned long long) (suc->bmaxpower << 1));
2617
2618                 snprintf(fmt, 16, " %%-%ds", MAX_MANUF_LEN - 1);
2619                 cprintf_s(IS_STR, fmt, suc->manufacturer);
2620                 cprintf_s(IS_STR, " %s\n", suc->product);
2621
2622                 if (!dispavg) {
2623                         /* Save current USB device in summary list */
2624                         for (j = 0; j < a->nr_allocated; j++) {
2625                                 sum = (struct stats_pwr_usb *) ((char *) a->buf[2] + j * a->msize);
2626
2627                                 if ((sum->bus_nr     == suc->bus_nr) &&
2628                                     (sum->vendor_id  == suc->vendor_id) &&
2629                                     (sum->product_id == suc->product_id))
2630                                         /* USB device found in summary list */
2631                                         break;
2632                                 if (!sum->bus_nr) {
2633                                         /*
2634                                          * Current slot is free:
2635                                          * Save USB device in summary list.
2636                                          */
2637                                         *sum = *suc;
2638                                         a->nr[2] = j + 1;
2639                                         break;
2640                                 }
2641                         }
2642                         if (j == a->nr_allocated) {
2643                                 /*
2644                                  * No free slot has been found for current device.
2645                                  * So enlarge buffers then save device in list.
2646                                  */
2647                                 reallocate_all_buffers(a, j);
2648                                 sum = (struct stats_pwr_usb *) ((char *) a->buf[2] + j * a->msize);
2649                                 *sum = *suc;
2650                                 a->nr[2] = j + 1;
2651                         }
2652                 }
2653         }
2654 }
2655
2656 /*
2657  ***************************************************************************
2658  * Display USB devices statistics.
2659  *
2660  * IN:
2661  * @a           Activity structure with statistics.
2662  * @prev        Index in array where stats used as reference are.
2663  * @curr        Index in array for current sample statistics.
2664  * @itv         Interval of time in 1/100th of a second.
2665  ***************************************************************************
2666  */
2667 __print_funct_t print_pwr_usb_stats(struct activity *a, int prev, int curr,
2668                                    unsigned long long itv)
2669 {
2670         stub_print_pwr_usb_stats(a, curr, FALSE);
2671 }
2672
2673 /*
2674  ***************************************************************************
2675  * Display average USB devices statistics.
2676  *
2677  * IN:
2678  * @a           Activity structure with statistics.
2679  * @prev        Index in array where stats used as reference are.
2680  * @curr        Index in array for current sample statistics.
2681  * @itv         Interval of time in 1/100th of a second.
2682  ***************************************************************************
2683  */
2684 __print_funct_t print_avg_pwr_usb_stats(struct activity *a, int prev, int curr,
2685                                         unsigned long long itv)
2686 {
2687         stub_print_pwr_usb_stats(a, 2, TRUE);
2688 }
2689
2690 /*
2691  ***************************************************************************
2692  * Display filesystems statistics. This function is used to
2693  * display instantaneous and average statistics.
2694  *
2695  * IN:
2696  * @a           Activity structure with statistics.
2697  * @prev        Index in array where stats used as reference are.
2698  * @curr        Index in array for current sample statistics.
2699  * @dispavg     TRUE if displaying average statistics.
2700  ***************************************************************************
2701  */
2702 __print_funct_t stub_print_filesystem_stats(struct activity *a, int prev, int curr, int dispavg)
2703 {
2704         int i, j, j0, found;
2705         struct stats_filesystem *sfc, *sfp, *sfm;
2706         int unit = NO_UNIT;
2707
2708         if (DISPLAY_UNIT(flags)) {
2709                 /* Default values unit is B */
2710                 unit = UNIT_BYTE;
2711         }
2712
2713         if (dis || DISPLAY_ZERO_OMIT(flags)) {
2714                 print_hdr_line((dispavg ? _("Summary:") : timestamp[!curr]),
2715                                a, FIRST + DISPLAY_MOUNT(a->opt_flags), -1, 9);
2716         }
2717
2718         for (i = 0; i < a->nr[curr]; i++) {
2719                 sfc = (struct stats_filesystem *) ((char *) a->buf[curr] + i * a->msize);
2720
2721                 found = FALSE;
2722                 if (DISPLAY_ZERO_OMIT(flags) && !dispavg) {
2723
2724                         if (a->nr[prev] > 0) {
2725                                 /* Look for corresponding fs in previous iteration */
2726                                 j = i;
2727
2728                                 if (j >= a->nr[prev]) {
2729                                         j = a->nr[prev] - 1;
2730                                 }
2731
2732                                 j0 = j;
2733
2734                                 do {
2735                                         sfp = (struct stats_filesystem *) ((char *) a->buf[prev] + j * a->msize);
2736                                         if (!strcmp(sfp->fs_name, sfc->fs_name)) {
2737                                                 found = TRUE;
2738                                                 break;
2739                                         }
2740                                         if (++j >= a->nr[prev]) {
2741                                                 j = 0;
2742                                         }
2743                                 }
2744                                 while (j != j0);
2745                         }
2746                 }
2747
2748                 if (!DISPLAY_ZERO_OMIT(flags) || dispavg || WANT_SINCE_BOOT(flags) || !found ||
2749                     (found && memcmp(sfp, sfc, STATS_FILESYSTEM_SIZE2CMP))) {
2750
2751                         printf("%-11s", (dispavg ? _("Summary:") : timestamp[curr]));
2752                         cprintf_f(unit, 2, 9, 0,
2753                                   unit < 0 ? (double) sfc->f_bfree / 1024 / 1024 : (double) sfc->f_bfree,
2754                                   unit < 0 ? (double) (sfc->f_blocks - sfc->f_bfree) / 1024 / 1024 :
2755                                              (double) (sfc->f_blocks - sfc->f_bfree));
2756                         cprintf_pc(DISPLAY_UNIT(flags), 2, 9, 2,
2757                                    /* f_blocks is not zero. But test it anyway ;-) */
2758                                    sfc->f_blocks ? SP_VALUE(sfc->f_bfree, sfc->f_blocks, sfc->f_blocks)
2759                                    : 0.0,
2760                                    sfc->f_blocks ? SP_VALUE(sfc->f_bavail, sfc->f_blocks, sfc->f_blocks)
2761                                    : 0.0);
2762                         cprintf_u64(NO_UNIT, 2, 9,
2763                                     (unsigned long long) sfc->f_ffree,
2764                                     (unsigned long long) (sfc->f_files - sfc->f_ffree));
2765                         cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2,
2766                                    sfc->f_files ? SP_VALUE(sfc->f_ffree, sfc->f_files, sfc->f_files)
2767                                    : 0.0);
2768                         cprintf_in(IS_STR, " %s\n",
2769                                    DISPLAY_MOUNT(a->opt_flags) ? sfc->mountp : sfc->fs_name, 0);
2770                 }
2771
2772                 if (!dispavg) {
2773                         /* Save current filesystem in summary list */
2774                         for (j = 0; j < a->nr_allocated; j++) {
2775                                 sfm = (struct stats_filesystem *) ((char *) a->buf[2] + j * a->msize);
2776
2777                                 if (!strcmp(sfm->fs_name, sfc->fs_name) ||
2778                                     !sfm->f_blocks) {
2779                                         /*
2780                                          * Filesystem found in list (then save again its stats)
2781                                          * or free slot (end of list).
2782                                          */
2783                                         *sfm = *sfc;
2784                                         if (j >= a->nr[2]) {
2785                                                 a->nr[2] = j + 1;
2786                                         }
2787                                         break;
2788                                 }
2789                         }
2790                         if (j == a->nr_allocated) {
2791                                 /*
2792                                  * No free slot has been found for current filesystem.
2793                                  * So enlarge buffers then save filesystem in list.
2794                                  */
2795                                 reallocate_all_buffers(a, j);
2796                                 sfm = (struct stats_filesystem *) ((char *) a->buf[2] + j * a->msize);
2797                                 *sfm = *sfc;
2798                                 a->nr[2] = j + 1;
2799                         }
2800                 }
2801         }
2802 }
2803
2804 /*
2805  ***************************************************************************
2806  * Display filesystems statistics.
2807  *
2808  * IN:
2809  * @a           Activity structure with statistics.
2810  * @prev        Index in array where stats used as reference are.
2811  * @curr        Index in array for current sample statistics.
2812  * @itv         Interval of time in 1/100th of a second.
2813  ***************************************************************************
2814  */
2815 __print_funct_t print_filesystem_stats(struct activity *a, int prev, int curr,
2816                                        unsigned long long itv)
2817 {
2818         stub_print_filesystem_stats(a, prev, curr, FALSE);
2819 }
2820
2821 /*
2822  ***************************************************************************
2823  * Display average filesystems statistics.
2824  *
2825  * IN:
2826  * @a           Activity structure with statistics.
2827  * @prev        Index in array where stats used as reference are.
2828  * @curr        Index in array for current sample statistics.
2829  * @itv         Interval of time in 1/100th of a second.
2830  ***************************************************************************
2831  */
2832 __print_funct_t print_avg_filesystem_stats(struct activity *a, int prev, int curr,
2833                                            unsigned long long itv)
2834 {
2835         stub_print_filesystem_stats(a, prev, 2, TRUE);
2836 }
2837
2838 /*
2839  ***************************************************************************
2840  * Display Fibre Channel HBA statistics.
2841  *
2842  * IN:
2843  * @a           Activity structure with statistics.
2844  * @prev        Index in array where stats used as reference are.
2845  * @curr        Index in array for current sample statistics.
2846  * @itv         Interval of time in 1/100th of a second.
2847  ***************************************************************************
2848  */
2849 __print_funct_t print_fchost_stats(struct activity *a, int prev, int curr,
2850                                    unsigned long long itv)
2851 {
2852         int i, j, j0, found;
2853         struct stats_fchost *sfcc,*sfcp;
2854
2855         if (dis) {
2856                 print_hdr_line(timestamp[!curr], a, FIRST, -1, 9);
2857         }
2858
2859         for (i = 0; i < a->nr[curr]; i++) {
2860                 sfcc = (struct stats_fchost *) ((char *) a->buf[curr] + i * a->msize);
2861
2862                 if (WANT_SINCE_BOOT(flags)) {
2863                         sfcp = (struct stats_fchost *) ((char *) a->buf[prev]);
2864                         found = TRUE;
2865                 }
2866                 else {
2867                         found = FALSE;
2868
2869                         if (a->nr[prev] > 0) {
2870                                 /* Look for corresponding structure in previous iteration */
2871                                 j = i;
2872
2873                                 if (j >= a->nr[prev]) {
2874                                         j = a->nr[prev] - 1;
2875                                 }
2876
2877                                 j0 = j;
2878
2879                                 do {
2880                                         sfcp = (struct stats_fchost *) ((char *) a->buf[prev] + j * a->msize);
2881                                         if (!strcmp(sfcc->fchost_name, sfcp->fchost_name)) {
2882                                                 found = TRUE;
2883                                                 break;
2884                                         }
2885
2886                                         if (++j >= a->nr[prev]) {
2887                                                 j = 0;
2888                                         }
2889                                 }
2890                                 while (j != j0);
2891                         }
2892                 }
2893
2894                 if (!found)
2895                         continue;
2896
2897                 printf("%-11s", timestamp[curr]);
2898                 cprintf_f(NO_UNIT, 4, 9, 2,
2899                           S_VALUE(sfcp->f_rxframes, sfcc->f_rxframes, itv),
2900                           S_VALUE(sfcp->f_txframes, sfcc->f_txframes, itv),
2901                           S_VALUE(sfcp->f_rxwords,  sfcc->f_rxwords,  itv),
2902                           S_VALUE(sfcp->f_txwords,  sfcc->f_txwords,  itv));
2903                 cprintf_in(IS_STR, " %s\n", sfcc->fchost_name, 0);
2904         }
2905 }
2906
2907 /*
2908  ***************************************************************************
2909  * Display softnet statistics.
2910  *
2911  * IN:
2912  * @a           Activity structure with statistics.
2913  * @prev        Index in array where stats used as reference are.
2914  * @curr        Index in array for current sample statistics.
2915  * @itv         Interval of time in 1/100th of a second.
2916  ***************************************************************************
2917  */
2918 __print_funct_t print_softnet_stats(struct activity *a, int prev, int curr,
2919                                     unsigned long long itv)
2920 {
2921         int i;
2922         struct stats_softnet
2923                 *ssnc = (struct stats_softnet *) a->buf[curr],
2924                 *ssnp = (struct stats_softnet *) a->buf[prev];
2925         unsigned char offline_cpu_bitmap[BITMAP_SIZE(NR_CPUS)] = {0};
2926
2927         if (dis || DISPLAY_ZERO_OMIT(flags)) {
2928                 print_hdr_line(timestamp[!curr], a, FIRST, 7, 9);
2929         }
2930
2931         /*
2932          * @nr[curr] cannot normally be greater than @nr_ini
2933          * (since @nr_ini counts up all CPU, even those offline).
2934          * If this happens, it may be because the machine has been
2935          * restarted with more CPU and no LINUX_RESTART has been
2936          * inserted in file.
2937          */
2938         if (a->nr[curr] > a->nr_ini) {
2939                 a->nr_ini = a->nr[curr];
2940         }
2941
2942         /* Compute statistics for CPU "all" */
2943         get_global_soft_statistics(a, prev, curr, flags, offline_cpu_bitmap);
2944
2945         for (i = 0; (i < a->nr_ini) && (i < a->bitmap->b_size + 1); i++) {
2946
2947                 /*
2948                  * Should current CPU (including CPU "all") be displayed?
2949                  * Note: a->nr is in [1, NR_CPUS + 1].
2950                  * Bitmap size is provided for (NR_CPUS + 1) CPUs.
2951                  * Anyway, NR_CPUS may vary between the version of sysstat
2952                  * used by sadc to create a file, and the version of sysstat
2953                  * used by sar to read it...
2954                  */
2955                 if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))) ||
2956                     offline_cpu_bitmap[i >> 3] & (1 << (i & 0x07)))
2957                         /* No */
2958                         continue;
2959                 /*
2960                  * The size of a->buf[...] CPU structure may be different from the default
2961                  * sizeof(struct stats_pwr_cpufreq) value if data have been read from a file!
2962                  * That's why we don't use a syntax like:
2963                  * ssnc = (struct stats_softnet *) a->buf[...] + i;
2964                  */
2965                 ssnc = (struct stats_softnet *) ((char *) a->buf[curr] + i * a->msize);
2966                 ssnp = (struct stats_softnet *) ((char *) a->buf[prev] + i * a->msize);
2967
2968                 if (DISPLAY_ZERO_OMIT(flags) && !memcmp(ssnp, ssnc, STATS_SOFTNET_SIZE))
2969                         continue;
2970
2971                 printf("%-11s", timestamp[curr]);
2972
2973                 if (!i) {
2974                         /* This is CPU "all" */
2975                         cprintf_in(IS_STR, " %s", "    all", 0);
2976                 }
2977                 else {
2978                         cprintf_in(IS_INT, " %7d", "", i - 1);
2979                 }
2980
2981                 cprintf_f(NO_UNIT, 5, 9, 2,
2982                           S_VALUE(ssnp->processed,    ssnc->processed,    itv),
2983                           S_VALUE(ssnp->dropped,      ssnc->dropped,      itv),
2984                           S_VALUE(ssnp->time_squeeze, ssnc->time_squeeze, itv),
2985                           S_VALUE(ssnp->received_rps, ssnc->received_rps, itv),
2986                           S_VALUE(ssnp->flow_limit,   ssnc->flow_limit,   itv));
2987                 printf("\n");
2988         }
2989 }