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