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