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