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