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