2 * svg_stats.c: Funtions used by sadf to display statistics in SVG format.
3 * (C) 2016-2018 by Sebastien GODARD (sysstat <at> orange.fr)
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. *
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 *
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 ***************************************************************************
30 #include "svg_stats.h"
35 #define _(string) gettext(string)
37 #define _(string) (string)
40 extern unsigned int flags;
41 extern struct sa_dlist *st_iface_list;
42 extern struct sa_dlist *st_dev_list;
43 extern struct sa_dlist *st_fs_list;
44 extern int dlst_iface_idx;
45 extern int dlst_dev_idx;
46 extern int dlst_fs_idx;
48 unsigned int svg_colors[] = {0x00cc00, 0xff00bf, 0x00ffff, 0xff0000,
49 0xe85f00, 0x0000ff, 0x006020, 0x7030a0,
50 0xffff00, 0x666635, 0xd60093, 0x00bfbf,
51 0xcc3300, 0x50040f, 0xffffbf, 0x193d55};
52 #define SVG_COLORS_IDX_MASK 0x0f
55 ***************************************************************************
56 * Compare the values of a statistics sample with the max and min values
57 * already found in previous samples for this same activity. If some new
58 * min or max values are found, then save them.
59 * Assume values cannot be negative.
60 * The structure containing the statistics sample is composed of @llu_nr
61 * unsigned long long fields, followed by @lu_nr unsigned long fields, then
62 * followed by @u_nr unsigned int fields.
65 * @types_nr Number of fields whose type is "long long", "long" and "int"
66 * composing the structure.
67 * @cs Pointer on current sample statistics structure.
68 * @ps Pointer on previous sample statistics structure (may be NULL).
69 * @itv Interval of time in 1/100th of a second.
70 * @spmin Array containing min values already found for this activity.
71 * @spmax Array containing max values already found for this activity.
72 * @g_fields Index in spmin/spmax arrays where extrema values for each
73 * activity metric will be saved. As a consequence spmin/spmax
74 * arrays may contain values in a different order than that of
75 * the fields in the statistics structure.
78 * @spmin Array containg the possible new min values for current activity.
79 * @spmax Array containg the possible new max values for current activity.
80 ***************************************************************************
82 void save_extrema(unsigned int types_nr[], void *cs, void *ps, unsigned long long itv,
83 double *spmin, double *spmax, int g_fields[])
85 unsigned long long *lluc, *llup;
86 unsigned long *luc, *lup;
87 unsigned int *uc, *up;
91 /* Compare unsigned long long fields */
92 lluc = (unsigned long long *) cs;
93 llup = (unsigned long long *) ps;
94 for (i = 0; i < types_nr[0]; i++, m++) {
96 val = *lluc < *llup ? 0.0 : S_VALUE(*llup, *lluc, itv);
100 * If no pointer on previous sample has been given
101 * then the value is not a per-second one.
103 val = (double) *lluc;
105 if (val < *(spmin + g_fields[m])) {
106 *(spmin + g_fields[m]) = val;
108 if (val > *(spmax + g_fields[m])) {
109 *(spmax + g_fields[m]) = val;
111 lluc = (unsigned long long *) ((char *) lluc + ULL_ALIGNMENT_WIDTH);
113 llup = (unsigned long long *) ((char *) llup + ULL_ALIGNMENT_WIDTH);
117 /* Compare unsigned long fields */
118 luc = (unsigned long *) lluc;
119 lup = (unsigned long *) llup;
120 for (i = 0; i < types_nr[1]; i++, m++) {
122 val = *luc < *lup ? 0.0 : S_VALUE(*lup, *luc, itv);
127 if (val < *(spmin + g_fields[m])) {
128 *(spmin + g_fields[m]) = val;
130 if (val > *(spmax + g_fields[m])) {
131 *(spmax + g_fields[m]) = val;
133 luc = (unsigned long *) ((char *) luc + UL_ALIGNMENT_WIDTH);
135 lup = (unsigned long *) ((char *) lup + UL_ALIGNMENT_WIDTH);
139 /* Compare unsigned int fields */
140 uc = (unsigned int *) luc;
141 up = (unsigned int *) lup;
142 for (i = 0; i < types_nr[2]; i++, m++) {
144 val = *uc < *up ? 0.0 : S_VALUE(*up, *uc, itv);
149 if (val < *(spmin + g_fields[m])) {
150 *(spmin + g_fields[m]) = val;
152 if (val > *(spmax + g_fields[m])) {
153 *(spmax + g_fields[m]) = val;
155 uc = (unsigned int *) ((char *) uc + U_ALIGNMENT_WIDTH);
157 up = (unsigned int *) ((char *) up + U_ALIGNMENT_WIDTH);
163 ***************************************************************************
164 * Find the min and max values of all the graphs that will be drawn in the
165 * same view. The graphs have their own min and max values in
166 * spmin[pos...pos+n-1] and spmax[pos...pos+n-1].
169 * @pos Position in array for the first graph extrema value.
170 * @n Number of graphs to scan.
171 * @spmin Array containing min values for graphs.
172 * @spmax Array containing max values for graphs.
175 * @gmin Global min value found.
176 * @gmax Global max value found.
177 ***************************************************************************
179 void get_global_extrema(int pos, int n, double *spmin, double *spmax,
180 double *gmin, double *gmax)
184 *gmin = *(spmin + pos);
185 *gmax = *(spmax + pos);
187 for (i = 1; i < n; i++) {
188 if (*(spmin + pos + i) < *gmin) {
189 *gmin = *(spmin + pos + i);
191 if (*(spmax + pos + i) > *gmax) {
192 *gmax = *(spmax + pos + i);
198 ***************************************************************************
199 * Allocate arrays used to save graphs data, min and max values.
200 * @n arrays of chars are allocated for @n graphs to draw. A pointer on this
201 * array is returned. This is equivalent to "char data[][n]" where each
202 * element is of indeterminate size and will contain the graph data (eg.
203 * << path d="M12,14 L13,16..." ... >>.
204 * The size of element data[i] is given by outsize[i].
205 * Also allocate an array to save min values (equivalent to "double spmin[n]")
206 * and an array for max values (equivalent to "double spmax[n]").
209 * @n Number of graphs to draw for current activity.
212 * @outsize Array that will contain the sizes of each element in array
213 * of chars. Equivalent to "int outsize[n]" with
214 * outsize[n] = sizeof(data[][n]).
215 * @spmin Array that will contain min values for current activity.
216 * @spmax Array that will contain max values for current activity.
219 * Pointer on array of arrays of chars that will contain the graphs data.
221 * NB: @min and @max arrays contain values in the same order as the fields
222 * in the statistics structure.
223 ***************************************************************************
225 char **allocate_graph_lines(int n, int **outsize, double **spmin, double **spmax)
232 * Allocate an array of pointers. Each of these pointers will
233 * be an array of chars.
235 if ((out = (char **) malloc(n * sizeof(char *))) == NULL) {
239 /* Allocate array that will contain the size of each array of chars */
240 if ((*outsize = (int *) malloc(n * sizeof(int))) == NULL) {
244 /* Allocate array that will contain the min value of each graph */
245 if ((*spmin = (double *) malloc(n * sizeof(double))) == NULL) {
249 /* Allocate array that will contain the max value of each graph */
250 if ((*spmax = (double *) malloc(n * sizeof(double))) == NULL) {
254 /* Allocate arrays of chars that will contain graphs data */
255 for (i = 0; i < n; i++) {
256 if ((out_p = (char *) malloc(CHUNKSIZE * sizeof(char))) == NULL) {
261 *out_p = '\0'; /* Reset string so that it can be safely strncat()'d later */
262 *(*outsize + i) = CHUNKSIZE; /* Each array of chars has a default size of CHUNKSIZE */
263 *(*spmin + i) = DBL_MAX; /* Init min and max values */
264 *(*spmax + i) = -DBL_MAX;
271 ***************************************************************************
272 * Reallocate all the arrays used to save graphs data, min and max values.
273 * The new size is the double of the original one.
276 * @n Number of slots currently allocated.
277 * @out Current pointer on arrays containing the graphs data.
278 * @outsize Current pointer on array containing the size of each element
280 * @spmin Current pointer on array containing min values.
281 * @spmax Current pointer on array containing max values.
284 * @out New pointer on arrays containing the graphs data.
285 * @outsize New pointer on array containing the size of each element
287 * @spmin New pointer on array containing min values.
288 * @spmax New pointer on array containing max values.
289 ***************************************************************************
291 void reallocate_all_graph_lines(int n, char ***out, int **outsize,
292 double **spmin, double **spmax)
297 /* Reallocate all the arrays */
298 SREALLOC(*out, char *, n * sizeof(char *) * 2);
299 SREALLOC(*outsize, int, n * sizeof(int) * 2);
300 SREALLOC(*spmin, double, n * sizeof(double) * 2);
301 SREALLOC(*spmax, double, n * sizeof(double) * 2);
303 /* Allocate arrays of chars that will contain graphs data for the newly allocated slots */
304 for (i = 0; i < n; i++) {
305 if ((out_p = (char *) malloc(CHUNKSIZE * sizeof(char))) == NULL) {
309 *(*out + n + i) = out_p;
311 *(*outsize + n + i) = CHUNKSIZE;
312 *(*spmin + n + i) = DBL_MAX;
313 *(*spmax + n + i) = -DBL_MAX;
318 ***************************************************************************
319 * Save SVG code for current graph.
322 * @data SVG code to append to current graph definition.
323 * @out Pointer on array of chars for current graph definition.
324 * @outsize Size of array of chars for current graph definition.
327 * @out Pointer on array of chars for current graph definition that
328 * has been updated with the addition of current sample data.
329 * @outsize Array that containing the (possibly new) sizes of each
330 * element in array of chars.
331 ***************************************************************************
333 void save_svg_data(char *data, char **out, int *outsize)
339 /* Determine space left in array */
340 len = *outsize - strlen(out_p) - 1;
341 if (strlen(data) >= len) {
343 * If current array of chars doesn't have enough space left
344 * then reallocate it with CHUNKSIZE more bytes.
346 SREALLOC(out_p, char, *outsize + CHUNKSIZE);
348 *outsize += CHUNKSIZE;
351 strncat(out_p, data, len);
355 ***************************************************************************
356 * Update line graph definition by appending current X,Y coordinates.
359 * @timetag Timestamp in seconds since the epoch for current sample
360 * stats. Will be used as X coordinate.
361 * @value Value of current sample metric. Will be used as Y coordinate.
362 * @out Pointer on array of chars for current graph definition.
363 * @outsize Size of array of chars for current graph definition.
364 * @restart Set to TRUE if a RESTART record has been read since the last
368 * @out Pointer on array of chars for current graph definition that
369 * has been updated with the addition of current sample data.
370 * @outsize Array that containing the (possibly new) sizes of each
371 * element in array of chars.
372 ***************************************************************************
374 void lnappend(unsigned long long timetag, double value, char **out, int *outsize,
379 /* Prepare additional graph definition data */
380 snprintf(data, 128, " %c%llu,%.2f", restart ? 'M' : 'L', timetag, value);
383 save_svg_data(data, out, outsize);
387 ***************************************************************************
388 * Update line graph definition by appending current X,Y coordinates. Use
389 * (unsigned long) integer values here.
392 * @timetag Timestamp in seconds since the epoch for current sample
393 * stats. Will be used as X coordinate.
394 * @value Value of current sample metric. Will be used as Y coordinate.
395 * @out Pointer on array of chars for current graph definition.
396 * @outsize Size of array of chars for current graph definition.
397 * @restart Set to TRUE if a RESTART record has been read since the last
401 * @out Pointer on array of chars for current graph definition that
402 * has been updated with the addition of current sample data.
403 * @outsize Array that containing the (possibly new) sizes of each
404 * element in array of chars.
405 ***************************************************************************
407 void lniappend(unsigned long long timetag, unsigned long long value, char **out,
408 int *outsize, int restart)
412 /* Prepare additional graph definition data */
413 snprintf(data, 128, " %c%llu,%llu", restart ? 'M' : 'L', timetag, value);
416 save_svg_data(data, out, outsize);
420 ***************************************************************************
421 * Update bar graph definition by adding a new rectangle.
424 * @timetag Timestamp in seconds since the epoch for current sample
425 * stats. Will be used as X coordinate.
426 * @value Value of current sample metric. Will be used as rectangle
428 * @offset Offset for Y coordinate.
429 * @out Pointer on array of chars for current graph definition.
430 * @outsize Size of array of chars for current graph definition.
431 * @dt Interval of time in seconds between current and previous
435 * @out Pointer on array of chars for current graph definition that
436 * has been updated with the addition of current sample data.
437 * @outsize Array that containing the (possibly new) sizes of each
438 * element in array of chars.
439 ***************************************************************************
441 void brappend(unsigned long long timetag, double offset, double value, char **out,
442 int *outsize, unsigned long long dt)
446 /* Prepare additional graph definition data */
447 if ((value == 0.0) || (dt == 0))
448 /* Don't draw a flat rectangle! */
451 snprintf(data, 128, "<rect x=\"%llu\" y=\"%.2f\" height=\"%.2f\" width=\"%llu\"/>",
452 timetag - dt, MINIMUM(offset, 100.0), MINIMUM(value, (100.0 - offset)), dt);
455 save_svg_data(data, out, outsize);
460 ***************************************************************************
461 * Update CPU graph and min/max values for each metric.
464 * @timetag Timestamp in seconds since the epoch for current sample
465 * stats. Will be used as X coordinate.
466 * @offset Offset for Y coordinate.
467 * @value Value of current CPU metric. Will be used as rectangle
469 * @out Pointer on array of chars for current graph definition.
470 * @outsize Size of array of chars for current graph definition.
471 * @dt Interval of time in seconds between current and previous
473 * @spmin Min value already found for this CPU metric.
474 * @spmax Max value already found for this CPU metric.
477 * @offset New offset value, to use to draw next rectangle
478 * @out Pointer on array of chars for current graph definition that
479 * has been updated with the addition of current sample data.
480 * @outsize Array that containing the (possibly new) sizes of each
481 * element in array of chars.
482 ***************************************************************************
484 void cpuappend(unsigned long long timetag, double *offset, double value, char **out,
485 int *outsize, unsigned long long dt, double *spmin, double *spmax)
487 /* Save min and max values */
488 if (value < *spmin) {
491 if (value > *spmax) {
494 /* Prepare additional graph definition data */
495 brappend(timetag, *offset, value, out, outsize, dt);
501 ***************************************************************************
502 * Update rectangular graph and min/max values.
505 * @timetag Timestamp in seconds since the epoch for current sample
506 * stats. Will be used as X coordinate.
507 * @p_value Metric value for previous sample
508 * @value Metric value for current sample.
509 * @out Pointer on array of chars for current graph definition.
510 * @outsize Size of array of chars for current graph definition.
511 * @restart Set to TRUE if a RESTART record has been read since the last
513 * @dt Interval of time in seconds between current and previous
515 * @spmin Min value already found for this metric.
516 * @spmax Max value already found for this metric.
519 * @out Pointer on array of chars for current graph definition that
520 * has been updated with the addition of current sample data.
521 * @outsize Array that containing the (possibly new) sizes of each
522 * element in array of chars.
523 * @spmin Min value for this metric.
524 * @spmax Max value for this metric.
525 ***************************************************************************
527 void recappend(unsigned long long timetag, double p_value, double value, char **out,
528 int *outsize, int restart, unsigned long long dt,
529 double *spmin, double *spmax)
531 char data[128], data1[128], data2[128];
533 /* Save min and max values */
534 if (value < *spmin) {
537 if (value > *spmax) {
540 /* Prepare additional graph definition data */
542 snprintf(data1, 128, " M%llu,%.2f", timetag - dt, p_value);
545 if (p_value != value) {
546 snprintf(data2, 128, " L%llu,%.2f", timetag, value);
549 snprintf(data, 128, "%s L%llu,%.2f%s", restart ? data1 : "", timetag, p_value,
550 p_value != value ? data2 : "");
553 save_svg_data(data, out, outsize);
557 ***************************************************************************
558 * Calculate 10 raised to the power of n.
561 * @n Power number to use.
564 * 10 raised to the power of n.
565 ***************************************************************************
567 unsigned int pwr10(int n)
572 for (i = 0; i < n; i++) {
580 ***************************************************************************
581 * Autoscale graphs of a given view.
584 * @asf_nr (Maximum) number of autoscale factors.
585 * @group Number of graphs in current view.
586 * @g_type Type of graph (SVG_LINE_GRAPH, SVG_BAR_GRAPH).
587 * @pos Position in array for the first graph in view.
588 * @gmax Global max value for all graphs in view.
589 * @spmax Array containing max values for graphs.
592 * @asfactor Autoscale factors (one for each graph).
593 ***************************************************************************
595 void gr_autoscaling(unsigned int asfactor[], int asf_nr, int group, int g_type, int pos,
596 double gmax, double *spmax)
601 for (j = 0; j < asf_nr; j++) {
602 /* Init autoscale factors */
606 if (AUTOSCALE_ON(flags) && (group > 1) && gmax && (g_type == SVG_LINE_GRAPH)) {
608 for (j = 0; (j < group) && (j < asf_nr); j++) {
609 if (!*(spmax + pos + j) || (*(spmax + pos + j) == gmax))
612 snprintf(val, 32, "%u", (unsigned int) (gmax / *(spmax + pos + j)));
613 if (strlen(val) > 0) {
614 asfactor[j] = pwr10(strlen(val) - 1);
621 ***************************************************************************
622 * Display background grid (horizontal lines) and corresponding graduations.
625 * @ypos Gap between two horizontal lines.
626 * @yfactor Scaling factor on Y axis.
627 * @lmax Max value for current view.
628 * @dp Number of decimal places for graduations.
629 ***************************************************************************
631 void display_hgrid(double ypos, double yfactor, double lmax, int dp)
637 /* Display horizontal lines (except on X axis) */
639 printf("<polyline points=\"0,%.2f %d,%.2f\" style=\"vector-effect: non-scaling-stroke; "
640 "stroke: #202020\" transform=\"scale(1,%f)\"/>\n",
641 ypos * j, SVG_G_XSIZE, ypos * j, yfactor);
645 * Display graduations.
646 * Use same rounded value for graduation numbers as for grid lines
647 * to make sure they are properly aligned.
649 sprintf(stmp, "%.2f", ypos * j);
650 printf("<text x=\"0\" y=\"%ld\" style=\"fill: white; stroke: none; font-size: 12px; "
651 "text-anchor: end\">%.*f.</text>\n",
652 (long) (atof(stmp) * yfactor), dp, ypos * j);
655 while ((ypos * j <= lmax) && (j < MAX_HLINES_NR));
659 ***************************************************************************
660 * Display background grid (vertical lines) and corresponding graduations.
663 * @xpos Gap between two vertical lines.
664 * @xfactor Scaling factor on X axis.
665 * @v_gridnr Default number of vertical lines to display. The actual
666 * number may vary between this value and 2 times this value.
667 * @svg_p SVG specific parameters (see draw_activity_graphs() function).
668 ***************************************************************************
670 void display_vgrid(long int xpos, double xfactor, int v_gridnr, struct svg_parm *svg_p)
672 struct record_header stamp;
674 char cur_time[TIMESTAMP_LEN];
677 stamp.ust_time = svg_p->ust_time_ref; /* Only ust_time field needs to be set. TRUE_TIME not allowed */
680 * What really matters to know when we should stop drawing vertical lines
681 * is the time end. v_gridnr is only informative and used to calculate
682 * the gap between two lines.
684 for (j = 0; (j <= (2 * v_gridnr)) && (stamp.ust_time <= svg_p->ust_time_end); j++) {
686 /* Display vertical lines */
687 sa_get_record_timestamp_struct(flags, &stamp, &rectime, NULL);
688 set_record_timestamp_string(flags, &stamp, NULL, cur_time, TIMESTAMP_LEN, &rectime);
689 printf("<polyline points=\"%ld,0 %ld,%d\" style=\"vector-effect: non-scaling-stroke; "
690 "stroke: #202020\" transform=\"scale(%f,1)\"/>\n",
691 xpos * j, xpos * j, -SVG_G_YSIZE, xfactor);
693 * Display graduations.
694 * NB: We may have tm_min != 0 if we have more than 24H worth of data in one datafile.
695 * In this case, we should rather display the exact time instead of only the hour.
697 if (DISPLAY_ONE_DAY(flags) && (rectime.tm_min == 0)) {
698 printf("<text x=\"%ld\" y=\"15\" style=\"fill: white; stroke: none; font-size: 14px; "
699 "text-anchor: start\">%2d:00</text>\n",
700 (long) (xpos * j * xfactor) - 15, rectime.tm_hour);
703 printf("<text x=\"%ld\" y=\"10\" style=\"fill: white; stroke: none; font-size: 12px; "
704 "text-anchor: start\" transform=\"rotate(45,%ld,0)\">%s</text>\n",
705 (long) (xpos * j * xfactor), (long) (xpos * j * xfactor), cur_time);
707 stamp.ust_time += xpos;
710 if (!PRINT_LOCAL_TIME(flags)) {
711 printf("<text x=\"-10\" y=\"30\" style=\"fill: yellow; stroke: none; font-size: 12px; "
712 "text-anchor: end\">UTC</text>\n");
717 ***************************************************************************
718 * Calculate the value on the Y axis between two horizontal lines that will
719 * make the graph background grid.
722 * @lmax Max value reached for this graph.
725 * @dp Number of decimal places for Y graduations.
728 * Value between two horizontal lines.
729 ***************************************************************************
731 double ygrid(double lmax, int *dp)
742 n = (long) (lmax / SVG_H_GRIDNR);
745 return (lmax / SVG_H_GRIDNR);
747 snprintf(val, 32, "%ld", n);
754 return ((double) (((long) (n / e)) * e));
758 ***************************************************************************
759 * Calculate the value on the X axis between two vertical lines that will
760 * make the graph background grid.
763 * @timestart First data timestamp (X coordinate of the first data point).
764 * @timeend Last data timestamp (X coordinate of the last data point).
765 * @v_gridnr Number of vertical lines to display. Its value is normally
766 * SVG_V_GRIDNR, except when option "oneday" is used, in which
767 * case it is set to 12.
770 * Value between two vertical lines.
771 ***************************************************************************
773 long int xgrid(unsigned long timestart, unsigned long timeend, int v_gridnr)
775 if ((timeend - timestart) <= v_gridnr)
778 return ((timeend - timestart) / v_gridnr);
782 ***************************************************************************
783 * Free global graphs structures.
786 * @out Pointer on array of chars for each graph definition.
787 * @outsize Size of array of chars for each graph definition.
788 * @spmin Array containing min values for graphs.
789 * @spmax Array containing max values for graphs.
790 ***************************************************************************
792 void free_graphs(char **out, int *outsize, double *spmin, double *spmax)
809 ***************************************************************************
810 * Skip current view where all graphs have only zero values. This function
811 * is called when option "skipempty" has been used, or when "No data" have
812 * been found for current view.
815 * @out Pointer on array of chars for each graph definition.
816 * @pos Position of current view in the array of graphs definitions.
817 * @group Number of graphs in current view.
820 * @pos Position of next view in the array of graphs definitions.
821 ***************************************************************************
823 void skip_current_view(char **out, int *pos, int group)
828 for (j = 0; j < group; j++) {
829 out_p = *(out + *pos + j);
831 /* Even if not displayed, current graph data have to be freed */
839 ***************************************************************************
840 * Display all graphs for current activity.
843 * @g_nr Number of views to display.
844 * @g_type Type of graph (SVG_LINE_GRAPH, SVG_BAR_GRAPH) for each view.
845 * @title Titles for each set of graphs.
846 * @g_title Titles for each graph.
847 * @item_name Item (network interface, etc.) name.
848 * @group Indicate how graphs are grouped together to make sets.
849 * @spmin Array containing min values for graphs.
850 * @spmax Array containing max values for graphs.
851 * @out Pointer on array of chars for each graph definition.
852 * @outsize Size of array of chars for each graph definition.
853 * @svg_p SVG specific parameters: Current views row number (.@graph_no),
854 * time for the first sample of stats (.@ust_time_first), and
855 * times used as start and end values on the X axis
856 * (.@ust_time_ref and .@ust_time_end).
857 * @record_hdr Pointer on record header of current stats sample.
858 * @skip_void Set to <> 0 if graphs with no data should be skipped.
859 * This is typicallly used to not display CPU offline on the
861 * @id Current activity id.
862 * @xid Current activity extra id number.
863 ***************************************************************************
865 void draw_activity_graphs(int g_nr, int g_type[], char *title[], char *g_title[], char *item_name,
866 int group[], double *spmin, double *spmax, char **out, int *outsize,
867 struct svg_parm *svg_p, struct record_header *record_hdr, int skip_void,
868 unsigned int id, unsigned int xid)
871 int i, j, dp, pos = 0, views_nr = 0, displayed = FALSE;
872 int v_gridnr, xv, yv;
873 unsigned int asfactor[16];
875 double lmax, xfactor, yfactor, ypos, gmin, gmax;
876 char val[32], cur_date[TIMESTAMP_LEN];
878 /* For each view which is part of current activity */
879 for (i = 0; i < g_nr; i++) {
881 /* Get global min and max value for current view */
882 get_global_extrema(pos, group[i], spmin, spmax, &gmin, &gmax);
884 /* Don't display empty views if requested */
885 if (SKIP_EMPTY_VIEWS(flags) && (gmax < 0.005)) {
886 skip_current_view(out, &pos, group[i]);
889 /* Skip void graphs */
890 if (skip_void && ((*(spmin + pos) == DBL_MAX) || (*(spmax + pos) == -DBL_MIN)))
894 /* Translate to proper position for current activity */
895 printf("<g id=\"g%d-%d\" transform=\"translate(0,%d)\">\n",
898 SVG_C_YSIZE * (DISPLAY_TOC(flags) ? svg_p->nr_act_dispd : 0) +
899 SVG_T_YSIZE * svg_p->graph_no);
903 /* Increment number of views actually displayed */
906 /* Compute top left position of view */
907 if (PACK_VIEWS(flags)) {
908 xv = (views_nr - 1) * SVG_T_XSIZE;
913 yv = (views_nr - 1) * SVG_T_YSIZE;
916 /* Graph background */
917 printf("<rect x=\"%d\" y=\"%d\" height=\"%d\" width=\"%d\"/>\n",
918 xv, yv, SVG_V_YSIZE, SVG_V_XSIZE);
921 printf("<text x=\"%d\" y=\"%d\" style=\"fill: yellow; stroke: none\">%s",
922 xv, 20 + yv, title[i]);
924 printf(" [%s]", item_name);
927 printf("<tspan x=\"%d\" y=\"%d\" style=\"fill: yellow; stroke: none; font-size: 12px\">"
928 "(Min, Max values)</tspan>\n</text>\n",
929 xv + 5 + SVG_M_XSIZE + SVG_G_XSIZE, yv + 25);
932 * At least two samples are needed.
933 * And a min and max value should have been found.
935 if ((record_hdr->ust_time == svg_p->ust_time_first) ||
936 (*(spmin + pos) == DBL_MAX) || (*(spmax + pos) == -DBL_MIN)) {
938 printf("<text x=\"%d\" y=\"%d\" style=\"fill: red; stroke: none\">No data</text>\n",
939 xv, yv + SVG_M_YSIZE);
940 skip_current_view(out, &pos, group[i]);
945 printf("<polyline points=\"%d,%d %d,%d %d,%d\" stroke=\"white\" stroke-width=\"2\"/>\n",
946 xv + SVG_M_XSIZE, yv + SVG_M_YSIZE,
947 xv + SVG_M_XSIZE, yv + SVG_M_YSIZE + SVG_G_YSIZE,
948 xv + SVG_M_XSIZE + SVG_G_XSIZE, yv + SVG_M_YSIZE + SVG_G_YSIZE);
950 /* Autoscaling graphs if needed */
951 gr_autoscaling(asfactor, 16, group[i], g_type[i], pos, gmax, spmax);
954 for (j = 0; j < group[i]; j++) {
955 /* Set dp to TRUE (1) if current metric is based on integer values */
956 dp = (g_title[pos + j][0] == '~');
957 snprintf(val, 32, "x%u ", asfactor[j]);
958 printf("<text x=\"%d\" y=\"%d\" style=\"fill: #%06x; stroke: none; font-size: 12px\">"
959 "%s %s(%.*f, %.*f)</text>\n",
960 xv + 5 + SVG_M_XSIZE + SVG_G_XSIZE, yv + SVG_M_YSIZE + j * 15,
961 svg_colors[(pos + j) & SVG_COLORS_IDX_MASK], g_title[pos + j] + dp,
962 asfactor[j] == 1 ? "" : val,
963 !dp * 2, *(spmin + pos + j) * asfactor[j],
964 !dp * 2, *(spmax + pos + j) * asfactor[j]);
967 if (DISPLAY_INFO(flags)) {
968 /* Display additional info (hostname, date) */
969 printf("<text x=\"%d\" y=\"%d\" "
970 "style=\"fill: yellow; text-anchor: end; stroke: none; font-size: 14px\">"
972 xv + SVG_V_XSIZE - 5, yv + SVG_M_YSIZE + SVG_G_YSIZE,
973 svg_p->file_hdr->sa_nodename);
975 /* Get report date */
976 set_report_date(localtime((const time_t *) &(svg_p->file_hdr->sa_ust_time)),
977 cur_date, sizeof(cur_date));
978 printf("<tspan x=\"%d\" y=\"%d\" "
979 "style=\"fill: yellow; text-anchor: end; stroke: none; font-size: 14px\">"
980 "%s</tspan>\n</text>\n",
981 xv + SVG_V_XSIZE - 5, yv + SVG_M_YSIZE + SVG_G_YSIZE + 14,
985 /* Translate to proper position for current graph within current activity */
986 printf("<g transform=\"translate(%d,%d)\">\n",
987 xv + SVG_M_XSIZE, yv + SVG_M_YSIZE + SVG_G_YSIZE);
990 if (g_type[i] == SVG_LINE_GRAPH) {
991 /* For line graphs */
993 /* If all values are zero then set current max value to 1 */
999 /* Max value cannot be too small, else Y graduations will be meaningless */
1000 if (lmax < SVG_H_GRIDNR * 0.01) {
1001 lmax = SVG_H_GRIDNR * 0.01;
1003 ypos = ygrid(lmax, &dp);
1006 /* For bar graphs (used for %values) */
1007 ypos = 25.0; /* Draw lines at 25%, 50%, 75% and 100% */
1008 dp = 0; /* No decimals */
1010 /* Max should be always 100% except for percentage values greater than 100% */
1018 yfactor = (double) -SVG_G_YSIZE / lmax;
1020 /* Display horizontal lines and graduations */
1021 display_hgrid(ypos, yfactor, lmax, dp);
1023 /* Set number of vertical lines to 12 when option "oneday" is used */
1024 v_gridnr = DISPLAY_ONE_DAY(flags) ? 12 : SVG_V_GRIDNR;
1026 xpos = xgrid(svg_p->ust_time_ref, svg_p->ust_time_end, v_gridnr);
1027 xfactor = (double) SVG_G_XSIZE / (svg_p->ust_time_end - svg_p->ust_time_ref);
1029 /* Display vertical lines and graduations */
1030 display_vgrid(xpos, xfactor, v_gridnr, svg_p);
1032 /* Draw current graphs set */
1033 for (j = 0; j < group[i]; j++) {
1034 out_p = *(out + pos + j);
1035 if (g_type[i] == SVG_LINE_GRAPH) {
1037 printf("<path d=\"%s\" "
1038 "style=\"vector-effect: non-scaling-stroke; "
1039 "stroke: #%06x; stroke-width: 1; fill-opacity: 0\" "
1040 "transform=\"scale(%f,%f)\"/>\n",
1042 svg_colors[(pos + j) & SVG_COLORS_IDX_MASK],
1044 yfactor * asfactor[j]);
1046 else if (*out_p) { /* Ignore flat bars */
1048 printf("<g style=\"fill: #%06x; stroke: none\" transform=\"scale(%f,%f)\">\n",
1049 svg_colors[(pos + j) & SVG_COLORS_IDX_MASK], xfactor, yfactor);
1050 printf("%s\n", out_p);
1062 /* For next row of views */
1063 (svg_p->graph_no) += PACK_VIEWS(flags) ? 1 : views_nr;
1067 ***************************************************************************
1068 * Display CPU statistics in SVG.
1071 * @a Activity structure with statistics.
1072 * @curr Index in array for current sample statistics.
1073 * @action Action expected from current function.
1074 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
1075 * flag indicating that a restart record has been previously
1076 * found (.@restart), and time used for the X axis origin
1078 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
1080 * @record_hdr Pointer on record header of current stats sample.
1081 ***************************************************************************
1083 __print_funct_t svg_print_cpu_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
1084 unsigned long long itv, struct record_header *record_hdr)
1086 struct stats_cpu *scc, *scp;
1087 unsigned long long deltot_jiffies = 1;
1088 unsigned char offline_cpu_bitmap[BITMAP_SIZE(NR_CPUS)] = {0};
1091 int g_type[] = {SVG_BAR_GRAPH};
1092 char *title[] = {"CPU utilization"};
1093 char *g_title1[] = {"%user", "%nice", "%system", "%iowait", "%steal", "%idle"};
1094 char *g_title2[] = {"%usr", "%nice", "%sys", "%iowait", "%steal", "%irq", "%soft", "%guest", "%gnice", "%idle"};
1095 static double *spmin, *spmax;
1097 static int *outsize;
1102 if (action & F_BEGIN) {
1104 * Allocate arrays that will contain the graphs data
1105 * and the min/max values.
1107 out = allocate_graph_lines(10 * svg_p->nr_max, &outsize, &spmin, &spmax);
1110 if (action & F_MAIN) {
1112 /* @nr[curr] cannot normally be greater than @nr_ini */
1113 if (a->nr[curr] > a->nr_ini) {
1114 a->nr_ini = a->nr[curr];
1118 * Compute CPU "all" as sum of all individual CPU (on SMP machines)
1119 * and look for offline CPU.
1121 if (a->nr_ini > 1) {
1122 deltot_jiffies = get_global_cpu_statistics(a, !curr, curr,
1123 flags, offline_cpu_bitmap);
1127 for (i = 0; (i < a->nr_ini) && (i < a->bitmap->b_size + 1); i++) {
1129 /* Should current CPU (including CPU "all") be displayed? */
1130 if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))) ||
1131 offline_cpu_bitmap[i >> 3] & (1 << (i & 0x07)))
1132 /* Don't display CPU */
1135 scc = (struct stats_cpu *) ((char *) a->buf[curr] + i * a->msize);
1136 scp = (struct stats_cpu *) ((char *) a->buf[!curr] + i * a->msize);
1142 /* This is CPU "all" */
1143 if (a->nr_ini == 1) {
1145 * This is a UP machine. In this case
1146 * interval has still not been calculated.
1148 deltot_jiffies = get_per_cpu_interval(scc, scp);
1150 if (!deltot_jiffies) {
1151 /* CPU "all" cannot be tickless */
1157 * Recalculate interval for current proc.
1158 * If result is 0 then current CPU is a tickless one.
1160 deltot_jiffies = get_per_cpu_interval(scc, scp);
1162 if (!deltot_jiffies) { /* Current CPU is tickless */
1164 val = 100.0; /* Tickless CPU: %idle = 100% */
1166 if (DISPLAY_CPU_DEF(a->opt_flags)) {
1169 else { /* DISPLAY_CPU_ALL(a->opt_flags) */
1173 /* Check min/max values for %user, etc. */
1174 for (k = 0; k < j; k++) {
1175 if (0.0 < *(spmin + pos + k)) {
1176 *(spmin + pos + k) = 0.0;
1178 if (0.0 > *(spmax + pos + k)) {
1179 *(spmax + pos + k) = 0.0;
1184 cpuappend(record_hdr->ust_time - svg_p->ust_time_ref,
1186 out + pos + j, outsize + pos + j, svg_p->dt,
1187 spmin + pos + j, spmax + pos + j);
1192 if (DISPLAY_CPU_DEF(a->opt_flags)) {
1194 cpuappend(record_hdr->ust_time - svg_p->ust_time_ref,
1195 &offset, ll_sp_value(scp->cpu_user, scc->cpu_user, deltot_jiffies),
1196 out + pos, outsize + pos, svg_p->dt,
1197 spmin + pos, spmax + pos);
1201 cpuappend(record_hdr->ust_time - svg_p->ust_time_ref,
1203 (scc->cpu_user - scc->cpu_guest) < (scp->cpu_user - scp->cpu_guest) ?
1205 ll_sp_value(scp->cpu_user - scp->cpu_guest,
1206 scc->cpu_user - scc->cpu_guest, deltot_jiffies),
1207 out + pos, outsize + pos, svg_p->dt,
1208 spmin + pos, spmax + pos);
1211 if (DISPLAY_CPU_DEF(a->opt_flags)) {
1213 cpuappend(record_hdr->ust_time - svg_p->ust_time_ref,
1214 &offset, ll_sp_value(scp->cpu_nice, scc->cpu_nice, deltot_jiffies),
1215 out + pos + 1, outsize + pos + 1, svg_p->dt,
1216 spmin + pos + 1, spmax + pos + 1);
1220 cpuappend(record_hdr->ust_time - svg_p->ust_time_ref,
1222 (scc->cpu_nice - scc->cpu_guest_nice) < (scp->cpu_nice - scp->cpu_guest_nice) ?
1224 ll_sp_value(scp->cpu_nice - scp->cpu_guest_nice,
1225 scc->cpu_nice - scc->cpu_guest_nice, deltot_jiffies),
1226 out + pos + 1, outsize + pos + 1, svg_p->dt,
1227 spmin + pos + 1, spmax + pos + 1);
1230 if (DISPLAY_CPU_DEF(a->opt_flags)) {
1232 cpuappend(record_hdr->ust_time - svg_p->ust_time_ref,
1234 ll_sp_value(scp->cpu_sys + scp->cpu_hardirq + scp->cpu_softirq,
1235 scc->cpu_sys + scc->cpu_hardirq + scc->cpu_softirq,
1237 out + pos + 2, outsize + pos + 2, svg_p->dt,
1238 spmin + pos + 2, spmax + pos + 2);
1242 cpuappend(record_hdr->ust_time - svg_p->ust_time_ref,
1243 &offset, ll_sp_value(scp->cpu_sys, scc->cpu_sys, deltot_jiffies),
1244 out + pos + 2, outsize + pos + 2, svg_p->dt,
1245 spmin + pos + 2, spmax + pos + 2);
1249 cpuappend(record_hdr->ust_time - svg_p->ust_time_ref,
1250 &offset, ll_sp_value(scp->cpu_iowait, scc->cpu_iowait, deltot_jiffies),
1251 out + pos + 3, outsize + pos + 3, svg_p->dt,
1252 spmin + pos + 3, spmax + pos + 3);
1254 cpuappend(record_hdr->ust_time - svg_p->ust_time_ref,
1255 &offset, ll_sp_value(scp->cpu_steal, scc->cpu_steal, deltot_jiffies),
1256 out + pos + 4, outsize + pos + 4, svg_p->dt,
1257 spmin + pos + 4, spmax + pos + 4);
1259 if (DISPLAY_CPU_ALL(a->opt_flags)) {
1261 cpuappend(record_hdr->ust_time - svg_p->ust_time_ref,
1262 &offset, ll_sp_value(scp->cpu_hardirq, scc->cpu_hardirq, deltot_jiffies),
1263 out + pos + 5, outsize + pos + 5, svg_p->dt,
1264 spmin + pos + 5, spmax + pos + 5);
1266 cpuappend(record_hdr->ust_time - svg_p->ust_time_ref,
1267 &offset, ll_sp_value(scp->cpu_softirq, scc->cpu_softirq, deltot_jiffies),
1268 out + pos + 6, outsize + pos + 6, svg_p->dt,
1269 spmin + pos + 6, spmax + pos + 6);
1271 cpuappend(record_hdr->ust_time - svg_p->ust_time_ref,
1272 &offset, ll_sp_value(scp->cpu_guest, scc->cpu_guest, deltot_jiffies),
1273 out + pos + 7, outsize + pos + 7, svg_p->dt,
1274 spmin + pos + 7, spmax + pos + 7);
1276 cpuappend(record_hdr->ust_time - svg_p->ust_time_ref,
1277 &offset, ll_sp_value(scp->cpu_guest_nice, scc->cpu_guest_nice, deltot_jiffies),
1278 out + pos + 8, outsize + pos + 8, svg_p->dt,
1279 spmin + pos + 8, spmax + pos + 8);
1288 cpuappend(record_hdr->ust_time - svg_p->ust_time_ref,
1290 (scc->cpu_idle < scp->cpu_idle ? 0.0 :
1291 ll_sp_value(scp->cpu_idle, scc->cpu_idle, deltot_jiffies)),
1292 out + pos + j, outsize + pos + j, svg_p->dt,
1293 spmin + pos + j, spmax + pos + j);
1297 if (action & F_END) {
1298 if (DISPLAY_IDLE(flags)) {
1299 /* Include additional %idle field */
1304 for (i = 0; (i < svg_p->nr_max) && (i < a->bitmap->b_size + 1); i++) {
1306 /* Should current CPU (including CPU "all") be displayed? */
1307 if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))))
1313 /* This is CPU "all" */
1314 strcpy(item_name, "all");
1317 sprintf(item_name, "%d", i - 1);
1320 if (DISPLAY_CPU_DEF(a->opt_flags)) {
1321 draw_activity_graphs(a->g_nr, g_type,
1322 title, g_title1, item_name, group1,
1323 spmin + pos, spmax + pos, out + pos, outsize + pos,
1324 svg_p, record_hdr, i, a->id, i);
1327 draw_activity_graphs(a->g_nr, g_type,
1328 title, g_title2, item_name, group2,
1329 spmin + pos, spmax + pos, out + pos, outsize + pos,
1330 svg_p, record_hdr, i, a->id, i);
1334 /* Free remaining structures */
1335 free_graphs(out, outsize, spmin, spmax);
1340 ***************************************************************************
1341 * Display task creation and context switch statistics in SVG.
1344 * @a Activity structure with statistics.
1345 * @curr Index in array for current sample statistics.
1346 * @action Action expected from current function.
1347 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
1348 * flag indicating that a restart record has been previously
1349 * found (.@restart) and time used for the X axis origin
1351 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
1352 * @record_hdr Pointer on record header of current stats sample.
1353 ***************************************************************************
1355 __print_funct_t svg_print_pcsw_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
1356 unsigned long long itv, struct record_header *record_hdr)
1359 *spc = (struct stats_pcsw *) a->buf[curr],
1360 *spp = (struct stats_pcsw *) a->buf[!curr];
1361 int group[] = {1, 1};
1362 int g_fields[] = {1, 0};
1363 int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH};
1364 char *title[] = {"Task creation", "Switching activity"};
1365 char *g_title[] = {"proc/s",
1367 static double *spmin, *spmax;
1369 static int *outsize;
1371 if (action & F_BEGIN) {
1373 * Allocate arrays that will contain the graphs data
1374 * and the min/max values.
1376 out = allocate_graph_lines(2, &outsize, &spmin, &spmax);
1379 if (action & F_MAIN) {
1380 /* Check for min/max values */
1381 save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
1382 itv, spmin, spmax, g_fields);
1384 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1385 S_VALUE(spp->processes, spc->processes, itv),
1386 out, outsize, svg_p->restart);
1388 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1389 S_VALUE(spp->context_switch, spc->context_switch, itv),
1390 out + 1, outsize + 1, svg_p->restart);
1393 if (action & F_END) {
1394 draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
1395 spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
1397 /* Free remaining structures */
1398 free_graphs(out, outsize, spmin, spmax);
1403 ***************************************************************************
1404 * Display swap statistics in SVG.
1407 * @a Activity structure with statistics.
1408 * @curr Index in array for current sample statistics.
1409 * @action Action expected from current function.
1410 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
1411 * flag indicating that a restart record has been previously
1412 * found (.@restart) and time used for the X axis origin
1414 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
1415 * @record_hdr Pointer on record header of current stats sample.
1416 ***************************************************************************
1418 __print_funct_t svg_print_swap_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
1419 unsigned long long itv, struct record_header *record_hdr)
1422 *ssc = (struct stats_swap *) a->buf[curr],
1423 *ssp = (struct stats_swap *) a->buf[!curr];
1425 int g_type[] = {SVG_LINE_GRAPH};
1426 char *title[] = {"Swap activity"};
1427 char *g_title[] = {"pswpin/s", "pswpout/s" };
1428 int g_fields[] = {0, 1};
1429 static double *spmin, *spmax;
1431 static int *outsize;
1433 if (action & F_BEGIN) {
1435 * Allocate arrays that will contain the graphs data
1436 * and the min/max values.
1438 out = allocate_graph_lines(2, &outsize, &spmin, &spmax);
1441 if (action & F_MAIN) {
1442 /* Check for min/max values */
1443 save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
1444 itv, spmin, spmax, g_fields);
1446 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1447 S_VALUE(ssp->pswpin, ssc->pswpin, itv),
1448 out, outsize, svg_p->restart);
1450 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1451 S_VALUE(ssp->pswpout, ssc->pswpout, itv),
1452 out + 1, outsize + 1, svg_p->restart);
1455 if (action & F_END) {
1456 draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
1457 spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
1459 /* Free remaining structures */
1460 free_graphs(out, outsize, spmin, spmax);
1465 ***************************************************************************
1466 * Display paging statistics in SVG.
1469 * @a Activity structure with statistics.
1470 * @curr Index in array for current sample statistics.
1471 * @action Action expected from current function.
1472 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
1473 * flag indicating that a restart record has been previously
1474 * found (.@restart) and time used for the X axis origin
1476 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
1477 * @record_hdr Pointer on record header of current stats sample.
1478 ***************************************************************************
1480 __print_funct_t svg_print_paging_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
1481 unsigned long long itv, struct record_header *record_hdr)
1484 *spc = (struct stats_paging *) a->buf[curr],
1485 *spp = (struct stats_paging *) a->buf[!curr];
1486 int group[] = {2, 2, 4};
1487 int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH};
1488 char *title[] = {"Paging activity (1)", "Paging activity (2)", "Paging activity (3)"};
1489 char *g_title[] = {"pgpgin/s", "pgpgout/s",
1490 "fault/s", "majflt/s",
1491 "pgfree/s", "pgscank/s", "pgscand/s", "pgsteal/s"};
1492 int g_fields[] = {0, 1, 2, 3, 4, 5, 6, 7};
1493 static double *spmin, *spmax;
1495 static int *outsize;
1497 if (action & F_BEGIN) {
1499 * Allocate arrays that will contain the graphs data
1500 * and the min/max values.
1502 out = allocate_graph_lines(8, &outsize, &spmin, &spmax);
1505 if (action & F_MAIN) {
1506 /* Check for min/max values */
1507 save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
1508 itv, spmin, spmax, g_fields);
1510 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1511 S_VALUE(spp->pgpgin, spc->pgpgin, itv),
1512 out, outsize, svg_p->restart);
1514 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1515 S_VALUE(spp->pgpgout, spc->pgpgout, itv),
1516 out + 1, outsize + 1, svg_p->restart);
1518 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1519 S_VALUE(spp->pgfault, spc->pgfault, itv),
1520 out + 2, outsize + 2, svg_p->restart);
1522 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1523 S_VALUE(spp->pgmajfault, spc->pgmajfault, itv),
1524 out + 3, outsize + 3, svg_p->restart);
1526 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1527 S_VALUE(spp->pgfree, spc->pgfree, itv),
1528 out + 4, outsize + 4, svg_p->restart);
1530 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1531 S_VALUE(spp->pgscan_kswapd, spc->pgscan_kswapd, itv),
1532 out + 5, outsize + 5, svg_p->restart);
1534 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1535 S_VALUE(spp->pgscan_direct, spc->pgscan_direct, itv),
1536 out + 6, outsize + 6, svg_p->restart);
1538 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1539 S_VALUE(spp->pgsteal, spc->pgsteal, itv),
1540 out + 7, outsize + 7, svg_p->restart);
1543 if (action & F_END) {
1544 draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
1545 spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
1547 /* Free remaining structures */
1548 free_graphs(out, outsize, spmin, spmax);
1553 ***************************************************************************
1554 * Display I/O and transfer rate statistics in SVG.
1557 * @a Activity structure with statistics.
1558 * @curr Index in array for current sample statistics.
1559 * @action Action expected from current function.
1560 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
1561 * flag indicating that a restart record has been previously
1562 * found (.@restart) and time used for the X axis origin
1564 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
1565 * @record_hdr Pointer on record header of current stats sample.
1566 ***************************************************************************
1568 __print_funct_t svg_print_io_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
1569 unsigned long long itv, struct record_header *record_hdr)
1572 *sic = (struct stats_io *) a->buf[curr],
1573 *sip = (struct stats_io *) a->buf[!curr];
1574 int group[] = {3, 2};
1575 int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH};
1576 char *title[] = {"I/O and transfer rate statistics (1)", "I/O and transfer rate statistics (2)"};
1577 char *g_title[] = {"tps", "rtps", "wtps",
1578 "bread/s", "bwrtn/s"};
1579 int g_fields[] = {0, 1, 2, 3, 4};
1580 static double *spmin, *spmax;
1582 static int *outsize;
1584 if (action & F_BEGIN) {
1586 * Allocate arrays that will contain the graphs data
1587 * and the min/max values.
1589 out = allocate_graph_lines(5, &outsize, &spmin, &spmax);
1592 if (action & F_MAIN) {
1593 /* Check for min/max values */
1594 save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
1595 itv, spmin, spmax, g_fields);
1598 * If we get negative values, this is probably because
1599 * one or more devices/filesystems have been unmounted.
1600 * We display 0.0 in this case though we should rather tell
1601 * the user that the value cannot be calculated here.
1604 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1605 sic->dk_drive < sip->dk_drive ? 0.0 :
1606 S_VALUE(sip->dk_drive, sic->dk_drive, itv),
1607 out, outsize, svg_p->restart);
1609 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1610 sic->dk_drive_rio < sip->dk_drive_rio ? 0.0 :
1611 S_VALUE(sip->dk_drive_rio, sic->dk_drive_rio, itv),
1612 out + 1, outsize + 1, svg_p->restart);
1614 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1615 sic->dk_drive_wio < sip->dk_drive_wio ? 0.0 :
1616 S_VALUE(sip->dk_drive_wio, sic->dk_drive_wio, itv),
1617 out + 2, outsize + 2, svg_p->restart);
1619 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1620 sic->dk_drive_rblk < sip->dk_drive_rblk ? 0.0 :
1621 S_VALUE(sip->dk_drive_rblk, sic->dk_drive_rblk, itv),
1622 out + 3, outsize + 3, svg_p->restart);
1624 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1625 sic->dk_drive_wblk < sip->dk_drive_wblk ? 0.0 :
1626 S_VALUE(sip->dk_drive_wblk, sic->dk_drive_wblk, itv),
1627 out + 4, outsize + 4, svg_p->restart);
1630 if (action & F_END) {
1631 draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
1632 spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
1634 /* Free remaining structures */
1635 free_graphs(out, outsize, spmin, spmax);
1640 ***************************************************************************
1641 * Display memory statistics in SVG.
1644 * @a Activity structure with statistics.
1645 * @curr Index in array for current sample statistics.
1646 * @action Action expected from current function.
1647 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
1648 * flag indicating that a restart record has been previously
1649 * found (.@restart) and time used for the X axis origin
1651 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
1652 * @record_hdr Pointer on record header of current stats sample.
1653 ***************************************************************************
1655 __print_funct_t svg_print_memory_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
1656 unsigned long long itv, struct record_header *record_hdr)
1659 *smc = (struct stats_memory *) a->buf[curr];
1660 int group1[] = {3, 1, 3, 1, 3, 5};
1661 int g_type1[] = {SVG_LINE_GRAPH, SVG_BAR_GRAPH, SVG_LINE_GRAPH,
1662 SVG_BAR_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH};
1663 int group2[] = {3, 1, 1};
1664 int g_type2[] = {SVG_LINE_GRAPH, SVG_BAR_GRAPH, SVG_BAR_GRAPH};
1665 char *title1[] = {"Memory utilization (1)", "Memory utilization (2)",
1666 "Memory utilization (3)", "Memory utilization (4)",
1667 "Memory utilization (5)", "Memory utilization (6)"};
1668 char *title2[] = {"Swap utilization (1)", "Swap utilization (2)",
1669 "Swap utilization (3)"};
1670 char *g_title1[] = {"MBmemfree", "MBavail", "MBmemused", "%memused", "MBbuffers",
1671 "MBcached", "MBcommit", "%commit", "MBactive", "MBinact",
1672 "MBdirty", "MBanonpg", "MBslab", "MBkstack", "MBpgtbl",
1674 char *g_title2[] = {"MBswpfree", "MBswpused", "MBswpcad", "%swpused",
1676 int g_fields[] = {0, 4, 5, 21, 16, 22, 18, 6, 8, 9, 10, 11, 12, 13, 14, 15, 1};
1677 static double *spmin, *spmax;
1679 static int *outsize;
1682 unsigned long long nousedmem;
1684 if (action & F_BEGIN) {
1686 * Allocate arrays that will contain the graphs data
1687 * and the min/max values.
1689 out = allocate_graph_lines(23, &outsize, &spmin, &spmax);
1692 if (action & F_MAIN) {
1693 /* Check for min/max values */
1694 save_extrema(a->gtypes_nr, (void *) a->buf[curr], NULL,
1695 itv, spmin, spmax, g_fields);
1696 /* Compute %memused min/max values */
1697 nousedmem = smc->frmkb + smc->bufkb + smc->camkb + smc->slabkb;
1698 if (nousedmem > smc->tlmkb) {
1699 nousedmem = smc->tlmkb;
1701 tval = smc->tlmkb ? SP_VALUE(nousedmem, smc->tlmkb, smc->tlmkb) : 0.0;
1702 if (tval > *(spmax + 3)) {
1703 *(spmax + 3) = tval;
1705 if (tval < *(spmin + 3)) {
1706 *(spmin + 3) = tval;
1708 /* Compute %commit min/max values */
1709 tval = (smc->tlmkb + smc->tlskb) ?
1710 SP_VALUE(0, smc->comkb, smc->tlmkb + smc->tlskb) : 0.0;
1711 if (tval > *(spmax + 7)) {
1712 *(spmax + 7) = tval;
1714 if (tval < *(spmin + 7)) {
1715 *(spmin + 7) = tval;
1717 /* Compute %swpused min/max values */
1719 SP_VALUE(smc->frskb, smc->tlskb, smc->tlskb) : 0.0;
1720 if (tval > *(spmax + 19)) {
1721 *(spmax + 19) = tval;
1723 if (tval < *(spmin + 19)) {
1724 *(spmin + 19) = tval;
1726 /* Compute %swpcad min/max values */
1727 tval = (smc->tlskb - smc->frskb) ?
1728 SP_VALUE(0, smc->caskb, smc->tlskb - smc->frskb) : 0.0;
1729 if (tval > *(spmax + 20)) {
1730 *(spmax + 20) = tval;
1732 if (tval < *(spmin + 20)) {
1733 *(spmin + 20) = tval;
1735 /* Compute memused min/max values in MB */
1736 tval = ((double) (smc->tlmkb - nousedmem)) / 1024;
1737 if (tval > *(spmax + 2)) {
1738 *(spmax + 2) = tval;
1740 if (tval < *(spmin + 2)) {
1741 *(spmin + 2) = tval;
1743 /* Compute swpused min/max values in MB */
1744 tval = ((double) (smc->tlskb - smc->frskb)) / 1024;
1745 if (tval > *(spmax + 17)) {
1746 *(spmax + 17) = tval;
1748 if (tval < *(spmin + 17)) {
1749 *(spmin + 17) = tval;
1753 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1754 ((double) smc->frmkb) / 1024,
1755 out, outsize, svg_p->restart);
1757 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1758 ((double) (smc->tlmkb - nousedmem)) / 1024,
1759 out + 2, outsize + 2, svg_p->restart);
1761 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1762 ((double) smc->availablekb) / 1024,
1763 out + 1, outsize + 1, svg_p->restart);
1765 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1766 ((double) smc->bufkb) / 1024,
1767 out + 4, outsize + 4, svg_p->restart);
1769 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1770 ((double) smc->camkb) / 1024,
1771 out + 5, outsize + 5, svg_p->restart);
1773 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1774 ((double) smc->frskb) / 1024,
1775 out + 16, outsize + 16, svg_p->restart);
1777 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1778 ((double) (smc->tlskb - smc->frskb)) / 1024,
1779 out + 17, outsize + 17, svg_p->restart);
1781 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1782 ((double) smc->caskb) / 1024,
1783 out + 18, outsize + 18, svg_p->restart);
1785 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1786 ((double) smc->comkb) / 1024,
1787 out + 6, outsize + 6, svg_p->restart);
1789 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1790 ((double) smc->activekb) / 1024,
1791 out + 8, outsize + 8, svg_p->restart);
1793 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1794 ((double) smc->inactkb) / 1024,
1795 out + 9, outsize + 9, svg_p->restart);
1797 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1798 ((double) smc->dirtykb) / 1024,
1799 out + 10, outsize + 10, svg_p->restart);
1801 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1802 ((double) smc->anonpgkb) / 1024,
1803 out + 11, outsize + 11, svg_p->restart);
1805 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1806 ((double) smc->slabkb) / 1024,
1807 out + 12, outsize + 12, svg_p->restart);
1809 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1810 ((double) smc->kstackkb) / 1024,
1811 out + 13, outsize + 13, svg_p->restart);
1813 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1814 ((double) smc->pgtblkb) / 1024,
1815 out + 14, outsize + 14, svg_p->restart);
1817 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1818 ((double) smc->vmusedkb) / 1024,
1819 out + 15, outsize + 15, svg_p->restart);
1821 brappend(record_hdr->ust_time - svg_p->ust_time_ref,
1824 SP_VALUE(nousedmem, smc->tlmkb, smc->tlmkb) : 0.0,
1825 out + 3, outsize + 3, svg_p->dt);
1827 brappend(record_hdr->ust_time - svg_p->ust_time_ref,
1829 (smc->tlmkb + smc->tlskb) ?
1830 SP_VALUE(0, smc->comkb, smc->tlmkb + smc->tlskb) : 0.0,
1831 out + 7, outsize + 7, svg_p->dt);
1833 brappend(record_hdr->ust_time - svg_p->ust_time_ref,
1836 SP_VALUE(smc->frskb, smc->tlskb, smc->tlskb) : 0.0,
1837 out + 19, outsize + 19, svg_p->dt);
1839 brappend(record_hdr->ust_time - svg_p->ust_time_ref,
1841 (smc->tlskb - smc->frskb) ?
1842 SP_VALUE(0, smc->caskb, smc->tlskb - smc->frskb) : 0.0,
1843 out + 20, outsize + 20, svg_p->dt);
1846 if (action & F_END) {
1848 /* Conversion kB -> MB */
1849 for (i = 0; i < 17; i++) {
1850 *(spmin + g_fields[i]) /= 1024;
1851 *(spmax + g_fields[i]) /= 1024;
1854 if (DISPLAY_MEMORY(a->opt_flags)) {
1855 draw_activity_graphs(DISPLAY_MEM_ALL(a->opt_flags) ? 6 : 5,
1856 g_type1, title1, g_title1, NULL, group1,
1857 spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
1860 if (DISPLAY_SWAP(a->opt_flags)) {
1861 draw_activity_graphs(3, g_type2, title2, g_title2, NULL, group2,
1862 spmin + 16, spmax + 16, out + 16, outsize + 16,
1863 svg_p, record_hdr, FALSE, a->id, 1);
1866 /* Free remaining structures */
1867 free_graphs(out, outsize, spmin, spmax);
1872 ***************************************************************************
1873 * Display kernel tables statistics in SVG.
1876 * @a Activity structure with statistics.
1877 * @curr Index in array for current sample statistics.
1878 * @action Action expected from current function.
1879 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
1880 * flag indicating that a restart record has been previously
1881 * found (.@restart) and time used for the X axis origin
1883 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
1884 * @record_hdr Pointer on record header of current stats sample.
1885 ***************************************************************************
1887 __print_funct_t svg_print_ktables_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
1888 unsigned long long itv, struct record_header *record_hdr)
1890 struct stats_ktables
1891 *skc = (struct stats_ktables *) a->buf[curr];
1892 int group[] = {3, 1};
1893 int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH};
1894 char *title[] = {"Kernel tables statistics (1)", "Kernel tables statistics (2)"};
1895 char *g_title[] = {"~dentunusd", "~file-nr", "~inode-nr",
1897 int g_fields[] = {1, 2, 0, 3};
1898 static double *spmin, *spmax;
1900 static int *outsize;
1902 if (action & F_BEGIN) {
1904 * Allocate arrays that will contain the graphs data
1905 * and the min/max values.
1907 out = allocate_graph_lines(4, &outsize, &spmin, &spmax);
1910 if (action & F_MAIN) {
1911 /* Check for min/max values */
1912 save_extrema(a->gtypes_nr, (void *) a->buf[curr], NULL,
1913 itv, spmin, spmax, g_fields);
1915 lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
1916 (unsigned long long) skc->dentry_stat,
1917 out, outsize, svg_p->restart);
1919 lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
1920 (unsigned long long) skc->file_used,
1921 out + 1, outsize + 1, svg_p->restart);
1923 lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
1924 (unsigned long long) skc->inode_used,
1925 out + 2, outsize + 2, svg_p->restart);
1927 lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
1928 (unsigned long long) skc->pty_nr,
1929 out + 3, outsize + 3, svg_p->restart);
1932 if (action & F_END) {
1933 draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
1934 spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
1936 /* Free remaining structures */
1937 free_graphs(out, outsize, spmin, spmax);
1942 ***************************************************************************
1943 * Display queue and load statistics in SVG.
1946 * @a Activity structure with statistics.
1947 * @curr Index in array for current sample statistics.
1948 * @action Action expected from current function.
1949 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
1950 * flag indicating that a restart record has been previously
1951 * found (.@restart) and time used for the X axis origin
1953 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
1954 * @record_hdr Pointer on record header of current stats sample.
1955 ***************************************************************************
1957 __print_funct_t svg_print_queue_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
1958 unsigned long long itv, struct record_header *record_hdr)
1961 *sqc = (struct stats_queue *) a->buf[curr];
1962 int group[] = {2, 1, 3};
1963 int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH};
1964 char *title[] = {"Queue length", "Task list statistics", "Load average statistics"};
1965 char *g_title[] = {"~runq-sz", "~blocked",
1967 "ldavg-1", "ldavg-5", "ldavg-15"};
1968 int g_fields[] = {0, 1, 2, 3, 4, 5};
1969 static double *spmin, *spmax;
1971 static int *outsize;
1973 if (action & F_BEGIN) {
1975 * Allocate arrays that will contain the graphs data
1976 * and the min/max values.
1978 out = allocate_graph_lines(6, &outsize, &spmin, &spmax);
1981 if (action & F_MAIN) {
1982 /* Check for min/max values */
1983 save_extrema(a->gtypes_nr, (void *) a->buf[curr], NULL,
1984 itv, spmin, spmax, g_fields);
1986 lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
1987 (unsigned long long) sqc->nr_running,
1988 out, outsize, svg_p->restart);
1990 lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
1991 (unsigned long long) sqc->procs_blocked,
1992 out + 1, outsize + 1, svg_p->restart);
1994 lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
1995 (unsigned long long) sqc->nr_threads,
1996 out + 2, outsize + 2, svg_p->restart);
1998 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
1999 (double) sqc->load_avg_1 / 100,
2000 out + 3, outsize + 3, svg_p->restart);
2002 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2003 (double) sqc->load_avg_5 / 100,
2004 out + 4, outsize + 4, svg_p->restart);
2006 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2007 (double) sqc->load_avg_15 / 100,
2008 out + 5, outsize + 5, svg_p->restart);
2011 if (action & F_END) {
2012 /* Fix min/max values for load average */
2013 *(spmin + 3) /= 100; *(spmax + 3) /= 100;
2014 *(spmin + 4) /= 100; *(spmax + 4) /= 100;
2015 *(spmin + 5) /= 100; *(spmax + 5) /= 100;
2017 draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
2018 spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
2020 /* Free remaining structures */
2021 free_graphs(out, outsize, spmin, spmax);
2026 ***************************************************************************
2027 * Display disk statistics in SVG.
2030 * @a Activity structure with statistics.
2031 * @curr Index in array for current sample statistics.
2032 * @action Action expected from current function.
2033 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
2034 * flag indicating that a restart record has been previously
2035 * found (.@restart) and time used for the X axis origin
2037 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
2038 * @record_hdr Pointer on record header of current stats sample.
2039 ***************************************************************************
2041 __print_funct_t svg_print_disk_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
2042 unsigned long long itv, struct record_header *record_hdr)
2044 struct stats_disk *sdc, *sdp, sdpzero;
2045 struct ext_disk_stats xds;
2046 int group[] = {1, 2, 2, 2, 1};
2047 int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH,
2048 SVG_LINE_GRAPH, SVG_BAR_GRAPH};
2049 char *title[] = {"Block devices statistics (1)", "Block devices statistics (2)",
2050 "Block devices statistics (3)", "Block devices statistics (4)",
2051 "Block devices statistics (5)"};
2052 char *g_title[] = {"tps",
2054 "areq-sz", "aqu-sz",
2057 int g_fields[] = {0, 1, 2};
2058 unsigned int local_types_nr[] = {1, 0, 0};
2059 static double *spmin, *spmax;
2061 static int *outsize;
2063 double rkB, wkB, aqusz;
2064 int i, j, k, pos, restart, *unregistered;
2066 if (action & F_BEGIN) {
2068 * Allocate arrays (#0..7) that will contain the graphs data
2069 * and the min/max values.
2070 * Also allocate one additional array (#8) for each disk device:
2071 * spmax + 8 will contain the device major number,
2072 * spmin + 8 will contain the device minor number,
2073 * outsize + 8 will contain a positive value (TRUE) if the device
2074 * has either still not been registered, or has been unregistered.
2076 out = allocate_graph_lines(9 * svg_p->nr_max, &outsize, &spmin, &spmax);
2079 if (action & F_MAIN) {
2080 memset(&sdpzero, 0, STATS_DISK_SIZE);
2081 restart = svg_p->restart;
2083 * Mark previously registered devices as now
2084 * possibly unregistered for all graphs.
2086 for (k = 0; k < svg_p->nr_max; k++) {
2087 unregistered = outsize + k * 9 + 8;
2088 if (*unregistered == FALSE) {
2089 *unregistered = MAYBE;
2093 /* For each device structure */
2094 for (i = 0; i < a->nr[curr]; i++) {
2095 sdc = (struct stats_disk *) ((char *) a->buf[curr] + i * a->msize);
2097 /* Get device name */
2098 item_name = get_sa_devname(sdc->major, sdc->minor, flags);
2101 /* A list of devices has been entered on the command line */
2102 if (!search_sa_dlist(st_dev_list, dlst_dev_idx, item_name))
2103 /* Device not found */
2107 /* Look for corresponding graph */
2108 for (k = 0; k < svg_p->nr_max; k++) {
2109 if ((sdc->major == *(spmax + k * 9 + 8)) &&
2110 (sdc->minor == *(spmin + k * 9 + 8)))
2114 if (k == svg_p->nr_max) {
2115 /* Graph not found: Look for first free entry */
2116 for (k = 0; k < svg_p->nr_max; k++) {
2117 if (*(spmax + k * 9 + 8) == -DBL_MAX)
2120 if (k == svg_p->nr_max) {
2121 /* No free graph entry: Extend all buffers */
2122 reallocate_all_graph_lines(svg_p->nr_max,
2123 &out, &outsize, &spmin, &spmax);
2128 unregistered = outsize + pos + 8;
2131 * If current device was marked as previously unregistered,
2132 * then set restart variable to TRUE so that the graph will be
2133 * discontinuous, and mark it as now registered.
2135 if (*unregistered == TRUE) {
2138 *unregistered = FALSE;
2140 if (*(spmax + pos + 8) == -DBL_MAX) {
2141 /* Save device major and minor numbers (if not already done) */
2142 *(spmax + pos + 8) = sdc->major;
2143 *(spmin + pos + 8) = sdc->minor;
2146 j = check_disk_reg(a, curr, !curr, i);
2148 /* This is a newly registered interface. Previous stats are zero */
2152 sdp = (struct stats_disk *) ((char *) a->buf[!curr] + j * a->msize);
2155 /* Check for min/max values */
2156 save_extrema(local_types_nr, (void *) sdc, (void *) sdp,
2157 itv, spmin + pos, spmax + pos, g_fields);
2159 rkB = S_VALUE(sdp->rd_sect, sdc->rd_sect, itv) / 2;
2160 wkB = S_VALUE(sdp->wr_sect, sdc->wr_sect, itv) / 2;
2161 if (rkB < *(spmin + pos + 1)) {
2162 *(spmin + pos + 1) = rkB;
2164 if (rkB > *(spmax + pos + 1)) {
2165 *(spmax + pos + 1) = rkB;
2167 if (wkB < *(spmin + pos + 2)) {
2168 *(spmin + pos + 2) = wkB;
2170 if (wkB > *(spmax + pos + 2)) {
2171 *(spmax + pos + 2) = wkB;
2174 compute_ext_disk_stats(sdc, sdp, itv, &xds);
2175 if ((xds.arqsz / 2) < *(spmin + pos + 3)) {
2176 *(spmin + pos + 3) = xds.arqsz / 2;
2178 if ((xds.arqsz / 2) > *(spmax + pos + 3)) {
2179 *(spmax + pos + 3) = xds.arqsz / 2;
2181 aqusz = S_VALUE(sdp->rq_ticks, sdc->rq_ticks, itv) / 1000.0;
2182 if (aqusz < *(spmin + pos + 4)) {
2183 *(spmin + pos + 4) = aqusz;
2185 if (aqusz > *(spmax + pos + 4)) {
2186 *(spmax + pos + 4) = aqusz;
2188 if (xds.await < *(spmin + pos + 5)) {
2189 *(spmin + pos + 5) = xds.await;
2191 if (xds.await > *(spmax + pos + 5)) {
2192 *(spmax + pos + 5) = xds.await;
2194 if (xds.svctm < *(spmin + pos + 6)) {
2195 *(spmin + pos + 6) = xds.svctm;
2197 if (xds.svctm > *(spmax + pos + 6)) {
2198 *(spmax + pos + 6) = xds.svctm;
2200 if ((xds.util / 10.0) < *(spmin + pos + 7)) {
2201 *(spmin + pos + 7) = xds.util / 10.0;
2203 if ((xds.util / 10.0) > *(spmax + pos + 7)) {
2204 *(spmax + pos + 7) = xds.util / 10.0;
2208 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2209 S_VALUE(sdp->nr_ios, sdc->nr_ios, itv),
2210 out + pos, outsize + pos, restart);
2212 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2213 S_VALUE(sdp->rd_sect, sdc->rd_sect, itv) / 2,
2214 out + pos + 1, outsize + pos + 1, restart);
2216 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2217 S_VALUE(sdp->wr_sect, sdc->wr_sect, itv) / 2,
2218 out + pos + 2, outsize + pos + 2, restart);
2220 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2222 out + pos + 3, outsize + pos + 3, restart);
2224 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2226 out + pos + 4, outsize + pos + 4, restart);
2228 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2230 out + pos + 5, outsize + pos + 5, restart);
2232 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2234 out + pos + 6, outsize + pos + 6, restart);
2236 brappend(record_hdr->ust_time - svg_p->ust_time_ref,
2237 0.0, xds.util / 10.0,
2238 out + pos + 7, outsize + pos + 7, svg_p->dt);
2241 /* Mark devices not seen here as now unregistered */
2242 for (k = 0; k < svg_p->nr_max; k++) {
2243 unregistered = outsize + k * 9 + 8;
2244 if (*unregistered != FALSE) {
2245 *unregistered = TRUE;
2250 if (action & F_END) {
2251 for (i = 0; i < svg_p->nr_max; i++) {
2252 /* Check if there is something to display */
2257 /* Get device name */
2258 item_name = get_sa_devname(*(spmax + pos + 8), *(spmin + pos + 8), flags);
2260 draw_activity_graphs(a->g_nr, g_type,
2261 title, g_title, item_name, group,
2262 spmin + pos, spmax + pos, out + pos, outsize + pos,
2263 svg_p, record_hdr, FALSE, a->id, i);
2266 /* Free remaining structures */
2267 free_graphs(out, outsize, spmin, spmax);
2272 ***************************************************************************
2273 * Display network interfaces statistics in SVG.
2276 * @a Activity structure with statistics.
2277 * @curr Index in array for current sample statistics.
2278 * @action Action expected from current function.
2279 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
2280 * flag indicating that a restart record has been previously
2281 * found (.@restart) and time used for the X axis origin
2283 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
2284 * @record_hdr Pointer on record header of current stats sample.
2285 ***************************************************************************
2287 __print_funct_t svg_print_net_dev_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
2288 unsigned long long itv, struct record_header *record_hdr)
2290 struct stats_net_dev *sndc, *sndp, sndzero;
2291 int group[] = {2, 2, 3, 1};
2292 int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH,
2294 char *title[] = {"Network interfaces statistics (1)", "Network interfaces statistics (2)",
2295 "Network interfaces statistics (3)", "Network interfaces statistics (4)"};
2296 char *g_title[] = {"rxpck/s", "txpck/s",
2298 "rxcmp/s", "txcmp/s", "rxmcst/s",
2300 int g_fields[] = {0, 1, 2, 3, 4, 5, 6};
2301 unsigned int local_types_nr[] = {7, 0, 0};
2302 static double *spmin, *spmax;
2304 static int *outsize;
2306 double rxkb, txkb, ifutil;
2307 int i, j, k, pos, restart, *unregistered;
2309 if (action & F_BEGIN) {
2311 * Allocate arrays (#0..7) that will contain the graphs data
2312 * and the min/max values.
2313 * Also allocate one additional array (#8) for each interface:
2314 * out + 8 will contain the interface name,
2315 * outsize + 8 will contain a positive value (TRUE) if the interface
2316 * has either still not been registered, or has been unregistered.
2318 out = allocate_graph_lines(9 * svg_p->nr_max, &outsize, &spmin, &spmax);
2321 if (action & F_MAIN) {
2322 memset(&sndzero, 0, STATS_NET_DEV_SIZE);
2323 restart = svg_p->restart;
2325 * Mark previously registered interfaces as now
2326 * possibly unregistered for all graphs.
2328 for (k = 0; k < svg_p->nr_max; k++) {
2329 unregistered = outsize + k * 9 + 8;
2330 if (*unregistered == FALSE) {
2331 *unregistered = MAYBE;
2335 /* For each network interfaces structure */
2336 for (i = 0; i < a->nr[curr]; i++) {
2337 sndc = (struct stats_net_dev *) ((char *) a->buf[curr] + i * a->msize);
2339 if (dlst_iface_idx) {
2340 /* A list of devices has been entered on the command line */
2341 if (!search_sa_dlist(st_iface_list, dlst_iface_idx, sndc->interface))
2342 /* Device not found */
2346 /* Look for corresponding graph */
2347 for (k = 0; k < svg_p->nr_max; k++) {
2348 item_name = *(out + k * 9 + 8);
2349 if (!strcmp(sndc->interface, item_name))
2353 if (k == svg_p->nr_max) {
2354 /* Graph not found: Look for first free entry */
2355 for (k = 0; k < svg_p->nr_max; k++) {
2356 item_name = *(out + k * 9 + 8);
2357 if (!strcmp(item_name, ""))
2360 if (k == svg_p->nr_max) {
2361 /* No free graph entry: Extend all buffers */
2362 reallocate_all_graph_lines(svg_p->nr_max,
2363 &out, &outsize, &spmin, &spmax);
2369 unregistered = outsize + pos + 8;
2371 j = check_net_dev_reg(a, curr, !curr, i);
2373 /* This is a newly registered interface. Previous stats are zero */
2377 sndp = (struct stats_net_dev *) ((char *) a->buf[!curr] + j * a->msize);
2381 * If current interface was marked as previously unregistered,
2382 * then set restart variable to TRUE so that the graph will be
2383 * discontinuous, and mark it as now registered.
2385 if (*unregistered == TRUE) {
2388 *unregistered = FALSE;
2390 if (!item_name[0]) {
2391 /* Save network interface name (if not already done) */
2392 strncpy(item_name, sndc->interface, CHUNKSIZE);
2393 item_name[CHUNKSIZE - 1] = '\0';
2396 /* Check for min/max values */
2397 save_extrema(local_types_nr, (void *) sndc, (void *) sndp,
2398 itv, spmin + pos, spmax + pos, g_fields);
2400 rxkb = S_VALUE(sndp->rx_bytes, sndc->rx_bytes, itv);
2401 txkb = S_VALUE(sndp->tx_bytes, sndc->tx_bytes, itv);
2402 ifutil = compute_ifutil(sndc, rxkb, txkb);
2403 if (ifutil < *(spmin + pos + 7)) {
2404 *(spmin + pos + 7) = ifutil;
2406 if (ifutil > *(spmax + pos + 7)) {
2407 *(spmax + pos + 7) = ifutil;
2411 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2412 S_VALUE(sndp->rx_packets, sndc->rx_packets, itv),
2413 out + pos, outsize + pos, restart);
2415 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2416 S_VALUE(sndp->tx_packets, sndc->tx_packets, itv),
2417 out + pos + 1, outsize + pos + 1, restart);
2419 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2421 out + pos + 2, outsize + pos + 2, restart);
2423 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2425 out + pos + 3, outsize + pos + 3, restart);
2427 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2428 S_VALUE(sndp->rx_compressed, sndc->rx_compressed, itv),
2429 out + pos + 4, outsize + pos + 4, restart);
2431 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2432 S_VALUE(sndp->tx_compressed, sndc->tx_compressed, itv),
2433 out + pos + 5, outsize + pos + 5, restart);
2435 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2436 S_VALUE(sndp->multicast, sndc->multicast, itv),
2437 out + pos + 6, outsize + pos + 6, restart);
2439 brappend(record_hdr->ust_time - svg_p->ust_time_ref,
2441 out + pos + 7, outsize + pos + 7, svg_p->dt);
2444 /* Mark interfaces not seen here as now unregistered */
2445 for (k = 0; k < svg_p->nr_max; k++) {
2446 unregistered = outsize + k * 9 + 8;
2447 if (*unregistered != FALSE) {
2448 *unregistered = TRUE;
2453 if (action & F_END) {
2454 for (i = 0; i < svg_p->nr_max; i++) {
2456 * Check if there is something to display.
2457 * Don't test sndc->interface because maybe the network
2458 * interface has been registered later.
2464 /* Recalculate min and max values in kB, not in B */
2465 *(spmin + pos + 2) /= 1024;
2466 *(spmax + pos + 2) /= 1024;
2467 *(spmin + pos + 3) /= 1024;
2468 *(spmax + pos + 3) /= 1024;
2470 item_name = *(out + pos + 8);
2471 draw_activity_graphs(a->g_nr, g_type,
2472 title, g_title, item_name, group,
2473 spmin + pos, spmax + pos, out + pos, outsize + pos,
2474 svg_p, record_hdr, FALSE, a->id, i);
2477 /* Free remaining structures */
2478 free_graphs(out, outsize, spmin, spmax);
2483 ***************************************************************************
2484 * Display network interfaces errors statistics in SVG.
2487 * @a Activity structure with statistics.
2488 * @curr Index in array for current sample statistics.
2489 * @action Action expected from current function.
2490 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
2491 * flag indicating that a restart record has been previously
2492 * found (.@restart) and time used for the X axis origin
2494 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
2495 * @record_hdr Pointer on record header of current stats sample.
2496 ***************************************************************************
2498 __print_funct_t svg_print_net_edev_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
2499 unsigned long long itv, struct record_header *record_hdr)
2501 struct stats_net_edev *snedc, *snedp, snedzero;
2502 int group[] = {2, 2, 2, 3};
2503 int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH,
2505 char *title[] = {"Network interfaces errors statistics (1)", "Network interfaces errors statistics (2)",
2506 "Network interfaces errors statistics (3)", "Network interfaces errors statistics (4)"};
2507 char *g_title[] = {"rxerr/s", "txerr/s",
2508 "rxdrop/s", "txdrop/s",
2509 "rxfifo/s", "txfifo/s",
2510 "coll/s", "txcarr/s", "rxfram/s"};
2511 int g_fields[] = {6, 0, 1, 2, 3, 4, 5, 8, 7};
2512 static double *spmin, *spmax;
2514 static int *outsize;
2516 int i, j, k, pos, restart, *unregistered;
2518 if (action & F_BEGIN) {
2520 * Allocate arrays (#0..8) that will contain the graphs data
2521 * and the min/max values.
2522 * Also allocate one additional array (#9) for each interface:
2523 * out + 9 will contain the interface name,
2524 * outsize + 9 will contain a positive value (TRUE) if the interface
2525 * has either still not been registered, or has been unregistered.
2527 out = allocate_graph_lines(10 * svg_p->nr_max, &outsize, &spmin, &spmax);
2530 if (action & F_MAIN) {
2531 memset(&snedzero, 0, STATS_NET_EDEV_SIZE);
2532 restart = svg_p->restart;
2534 * Mark previously registered interfaces as now
2535 * possibly unregistered for all graphs.
2537 for (k = 0; k < svg_p->nr_max; k++) {
2538 unregistered = outsize + k * 10 + 9;
2539 if (*unregistered == FALSE) {
2540 *unregistered = MAYBE;
2544 /* For each network interfaces structure */
2545 for (i = 0; i < a->nr[curr]; i++) {
2546 snedc = (struct stats_net_edev *) ((char *) a->buf[curr] + i * a->msize);
2547 if (!strcmp(snedc->interface, ""))
2548 /* Empty structure: This is the end of the list */
2551 if (dlst_iface_idx) {
2552 /* A list of devices has been entered on the command line */
2553 if (!search_sa_dlist(st_iface_list, dlst_iface_idx, snedc->interface))
2554 /* Device not found */
2558 /* Look for corresponding graph */
2559 for (k = 0; k < svg_p->nr_max; k++) {
2560 item_name = *(out + k * 10 + 9);
2561 if (!strcmp(snedc->interface, item_name))
2565 if (k == svg_p->nr_max) {
2566 /* Graph not found: Look for first free entry */
2567 for (k = 0; k < svg_p->nr_max; k++) {
2568 item_name = *(out + k * 10 + 9);
2569 if (!strcmp(item_name, ""))
2572 if (k == svg_p->nr_max) {
2573 /* No free graph entry: Extend all buffers */
2574 reallocate_all_graph_lines(svg_p->nr_max,
2575 &out, &outsize, &spmin, &spmax);
2581 unregistered = outsize + pos + 9;
2583 j = check_net_edev_reg(a, curr, !curr, i);
2585 /* This is a newly registered interface. Previous stats are zero */
2589 snedp = (struct stats_net_edev *) ((char *) a->buf[!curr] + j * a->msize);
2593 * If current interface was marked as previously unregistered,
2594 * then set restart variable to TRUE so that the graph will be
2595 * discontinuous, and mark it as now registered.
2597 if (*unregistered == TRUE) {
2600 *unregistered = FALSE;
2602 if (!item_name[0]) {
2603 /* Save network interface name (if not already done) */
2604 strncpy(item_name, snedc->interface, CHUNKSIZE);
2605 item_name[CHUNKSIZE - 1] = '\0';
2608 /* Check for min/max values */
2609 save_extrema(a->gtypes_nr, (void *) snedc, (void *) snedp,
2610 itv, spmin + pos, spmax + pos, g_fields);
2613 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2614 S_VALUE(snedp->rx_errors, snedc->rx_errors, itv),
2615 out + pos, outsize + pos, restart);
2617 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2618 S_VALUE(snedp->tx_errors, snedc->tx_errors, itv),
2619 out + pos + 1, outsize + pos + 1, restart);
2621 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2622 S_VALUE(snedp->rx_dropped, snedc->rx_dropped, itv),
2623 out + pos + 2, outsize + pos + 2, restart);
2625 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2626 S_VALUE(snedp->tx_dropped, snedc->tx_dropped, itv),
2627 out + pos + 3, outsize + pos + 3, restart);
2629 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2630 S_VALUE(snedp->rx_fifo_errors, snedc->rx_fifo_errors, itv),
2631 out + pos + 4, outsize + pos + 4, restart);
2633 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2634 S_VALUE(snedp->tx_fifo_errors, snedc->tx_fifo_errors, itv),
2635 out + pos + 5, outsize + pos + 5, restart);
2637 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2638 S_VALUE(snedp->collisions, snedc->collisions, itv),
2639 out + pos + 6, outsize + pos + 6, restart);
2641 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2642 S_VALUE(snedp->tx_carrier_errors, snedc->tx_carrier_errors, itv),
2643 out + pos + 7, outsize + pos + 7, restart);
2645 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2646 S_VALUE(snedp->rx_frame_errors, snedc->rx_frame_errors, itv),
2647 out + pos + 8, outsize + pos + 8, restart);
2650 /* Mark interfaces not seen here as now unregistered */
2651 for (k = 0; k < svg_p->nr_max; k++) {
2652 unregistered = outsize + k * 10 + 9;
2653 if (*unregistered != FALSE) {
2654 *unregistered = TRUE;
2659 if (action & F_END) {
2660 for (i = 0; i < svg_p->nr_max; i++) {
2662 * Check if there is something to display.
2663 * Don't test snedc->interface because maybe the network
2664 * interface has been registered later.
2670 item_name = *(out + pos + 9);
2671 draw_activity_graphs(a->g_nr, g_type,
2672 title, g_title, item_name, group,
2673 spmin + pos, spmax + pos, out + pos, outsize + pos,
2674 svg_p, record_hdr, FALSE, a->id, i);
2677 /* Free remaining structures */
2678 free_graphs(out, outsize, spmin, spmax);
2683 ***************************************************************************
2684 * Display NFS client statistics in SVG.
2687 * @a Activity structure with statistics.
2688 * @curr Index in array for current sample statistics.
2689 * @action Action expected from current function.
2690 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
2691 * flag indicating that a restart record has been previously
2692 * found (.@restart) and time used for the X axis origin
2694 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
2695 * @record_hdr Pointer on record header of current stats sample.
2696 ***************************************************************************
2698 __print_funct_t svg_print_net_nfs_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
2699 unsigned long long itv, struct record_header *record_hdr)
2701 struct stats_net_nfs
2702 *snnc = (struct stats_net_nfs *) a->buf[curr],
2703 *snnp = (struct stats_net_nfs *) a->buf[!curr];
2704 int group[] = {2, 2, 2};
2705 int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH};
2706 char *title[] = {"NFS client statistics (1)", "NFS client statistics (2)",
2707 "NFS client statistics (3)"};
2708 char *g_title[] = {"call/s", "retrans/s",
2709 "read/s", "write/s",
2710 "access/s", "getatt/s"};
2711 int g_fields[] = {0, 1, 2, 3, 4, 5};
2712 static double *spmin, *spmax;
2714 static int *outsize;
2716 if (action & F_BEGIN) {
2718 * Allocate arrays that will contain the graphs data
2719 * and the min/max values.
2721 out = allocate_graph_lines(6, &outsize, &spmin, &spmax);
2724 if (action & F_MAIN) {
2725 /* Check for min/max values */
2726 save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
2727 itv, spmin, spmax, g_fields);
2730 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2731 S_VALUE(snnp->nfs_rpccnt, snnc->nfs_rpccnt, itv),
2732 out, outsize, svg_p->restart);
2734 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2735 S_VALUE(snnp->nfs_rpcretrans, snnc->nfs_rpcretrans, itv),
2736 out + 1, outsize + 1, svg_p->restart);
2738 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2739 S_VALUE(snnp->nfs_readcnt, snnc->nfs_readcnt, itv),
2740 out + 2, outsize + 2, svg_p->restart);
2742 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2743 S_VALUE(snnp->nfs_writecnt, snnc->nfs_writecnt, itv),
2744 out + 3, outsize + 3, svg_p->restart);
2746 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2747 S_VALUE(snnp->nfs_accesscnt, snnc->nfs_accesscnt, itv),
2748 out + 4, outsize + 4, svg_p->restart);
2750 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2751 S_VALUE(snnp->nfs_getattcnt, snnc->nfs_getattcnt, itv),
2752 out + 5, outsize + 5, svg_p->restart);
2755 if (action & F_END) {
2756 draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
2757 spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
2759 /* Free remaining structures */
2760 free_graphs(out, outsize, spmin, spmax);
2765 ***************************************************************************
2766 * Display NFS server statistics in SVG.
2769 * @a Activity structure with statistics.
2770 * @curr Index in array for current sample statistics.
2771 * @action Action expected from current function.
2772 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
2773 * flag indicating that a restart record has been previously
2774 * found (.@restart) and time used for the X axis origin
2776 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
2777 * @record_hdr Pointer on record header of current stats sample.
2778 ***************************************************************************
2780 __print_funct_t svg_print_net_nfsd_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
2781 unsigned long long itv, struct record_header *record_hdr)
2783 struct stats_net_nfsd
2784 *snndc = (struct stats_net_nfsd *) a->buf[curr],
2785 *snndp = (struct stats_net_nfsd *) a->buf[!curr];
2786 int group[] = {2, 3, 2, 2, 2};
2787 int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH,
2788 SVG_LINE_GRAPH, SVG_LINE_GRAPH};
2789 char *title[] = {"NFS server statistics (1)", "NFS server statistics (2)",
2790 "NFS server statistics (3)", "NFS server statistics (4)",
2791 "NFS server statistics (5)"};
2792 char *g_title[] = {"scall/s", "badcall/s",
2793 "packet/s", "udp/s", "tcp/s",
2795 "sread/s", "swrite/s",
2796 "saccess/s", "sgetatt/s"};
2797 int g_fields[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
2798 static double *spmin, *spmax;
2800 static int *outsize;
2802 if (action & F_BEGIN) {
2804 * Allocate arrays that will contain the graphs data
2805 * and the min/max values.
2807 out = allocate_graph_lines(11, &outsize, &spmin, &spmax);
2810 if (action & F_MAIN) {
2811 /* Check for min/max values */
2812 save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
2813 itv, spmin, spmax, g_fields);
2816 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2817 S_VALUE(snndp->nfsd_rpccnt, snndc->nfsd_rpccnt, itv),
2818 out, outsize, svg_p->restart);
2820 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2821 S_VALUE(snndp->nfsd_rpcbad, snndc->nfsd_rpcbad, itv),
2822 out + 1, outsize + 1, svg_p->restart);
2824 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2825 S_VALUE(snndp->nfsd_netcnt, snndc->nfsd_netcnt, itv),
2826 out + 2, outsize + 2, svg_p->restart);
2828 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2829 S_VALUE(snndp->nfsd_netudpcnt, snndc->nfsd_netudpcnt, itv),
2830 out + 3, outsize + 3, svg_p->restart);
2832 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2833 S_VALUE(snndp->nfsd_nettcpcnt, snndc->nfsd_nettcpcnt, itv),
2834 out + 4, outsize + 4, svg_p->restart);
2836 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2837 S_VALUE(snndp->nfsd_rchits, snndc->nfsd_rchits, itv),
2838 out + 5, outsize + 5, svg_p->restart);
2840 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2841 S_VALUE(snndp->nfsd_rcmisses, snndc->nfsd_rcmisses, itv),
2842 out + 6, outsize + 6, svg_p->restart);
2844 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2845 S_VALUE(snndp->nfsd_readcnt, snndc->nfsd_readcnt, itv),
2846 out + 7, outsize + 7, svg_p->restart);
2848 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2849 S_VALUE(snndp->nfsd_writecnt, snndc->nfsd_writecnt, itv),
2850 out + 8, outsize + 8, svg_p->restart);
2852 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2853 S_VALUE(snndp->nfsd_accesscnt, snndc->nfsd_accesscnt, itv),
2854 out + 9, outsize + 9, svg_p->restart);
2856 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2857 S_VALUE(snndp->nfsd_getattcnt, snndc->nfsd_getattcnt, itv),
2858 out + 10, outsize + 10, svg_p->restart);
2861 if (action & F_END) {
2862 draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
2863 spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
2865 /* Free remaining structures */
2866 free_graphs(out, outsize, spmin, spmax);
2871 ***************************************************************************
2872 * Display socket statistics in SVG.
2875 * @a Activity structure with statistics.
2876 * @curr Index in array for current sample statistics.
2877 * @action Action expected from current function.
2878 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
2879 * flag indicating that a restart record has been previously
2880 * found (.@restart) and time used for the X axis origin
2882 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
2883 * @record_hdr Pointer on record header of current stats sample.
2884 ***************************************************************************
2886 __print_funct_t svg_print_net_sock_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
2887 unsigned long long itv, struct record_header *record_hdr)
2889 struct stats_net_sock
2890 *snsc = (struct stats_net_sock *) a->buf[curr];
2891 int group[] = {1, 5};
2892 int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH};
2893 char *title[] = {"IPv4 sockets statistics (1)", "IPv4 sockets statistics (2)"};
2894 char *g_title[] = {"~totsck",
2895 "~tcpsck", "~udpsck", "~rawsck", "~ip-frag", "~tcp-tw"};
2896 int g_fields[] = {0, 1, 5, 2, 3, 4};
2897 static double *spmin, *spmax;
2899 static int *outsize;
2901 if (action & F_BEGIN) {
2903 * Allocate arrays that will contain the graphs data
2904 * and the min/max values.
2906 out = allocate_graph_lines(6, &outsize, &spmin, &spmax);
2909 if (action & F_MAIN) {
2910 /* Check for min/max values */
2911 save_extrema(a->gtypes_nr, (void *) a->buf[curr], NULL,
2912 itv, spmin, spmax, g_fields);
2914 lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
2915 (unsigned long long) snsc->sock_inuse,
2916 out, outsize, svg_p->restart);
2918 lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
2919 (unsigned long long) snsc->tcp_inuse,
2920 out + 1, outsize + 1, svg_p->restart);
2922 lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
2923 (unsigned long long) snsc->udp_inuse,
2924 out + 2, outsize + 2, svg_p->restart);
2926 lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
2927 (unsigned long long) snsc->raw_inuse,
2928 out + 3, outsize + 3, svg_p->restart);
2930 lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
2931 (unsigned long long) snsc->frag_inuse,
2932 out + 4, outsize + 4, svg_p->restart);
2934 lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
2935 (unsigned long long) snsc->tcp_tw,
2936 out + 5, outsize + 5, svg_p->restart);
2939 if (action & F_END) {
2940 draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
2941 spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
2943 /* Free remaining structures */
2944 free_graphs(out, outsize, spmin, spmax);
2949 ***************************************************************************
2950 * Display IPv4 traffic statistics in SVG.
2953 * @a Activity structure with statistics.
2954 * @curr Index in array for current sample statistics.
2955 * @action Action expected from current function.
2956 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
2957 * flag indicating that a restart record has been previously
2958 * found (.@restart) and time used for the X axis origin
2960 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
2961 * @record_hdr Pointer on record header of current stats sample.
2962 ***************************************************************************
2964 __print_funct_t svg_print_net_ip_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
2965 unsigned long long itv, struct record_header *record_hdr)
2968 *snic = (struct stats_net_ip *) a->buf[curr],
2969 *snip = (struct stats_net_ip *) a->buf[!curr];
2970 int group[] = {4, 2, 2};
2971 int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH};
2972 char *title[] = {"IPv4 traffic statistics (1)", "IPv4 traffic statistics (2)", "IPv4 traffic statistics (3)"};
2973 char *g_title[] = {"irec/s", "fwddgm/s", "idel/s", "orq/s",
2974 "asmrq/s", "asmok/s",
2975 "fragok/s", "fragcrt/s"};
2976 int g_fields[] = {0, 1, 2, 3, 4, 5, 6, 7};
2977 static double *spmin, *spmax;
2979 static int *outsize;
2981 if (action & F_BEGIN) {
2983 * Allocate arrays that will contain the graphs data
2984 * and the min/max values.
2986 out = allocate_graph_lines(8, &outsize, &spmin, &spmax);
2989 if (action & F_MAIN) {
2990 /* Check for min/max values */
2991 save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
2992 itv, spmin, spmax, g_fields);
2995 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
2996 S_VALUE(snip->InReceives, snic->InReceives, itv),
2997 out, outsize, svg_p->restart);
2999 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3000 S_VALUE(snip->ForwDatagrams, snic->ForwDatagrams, itv),
3001 out + 1, outsize + 1, svg_p->restart);
3003 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3004 S_VALUE(snip->InDelivers, snic->InDelivers, itv),
3005 out + 2, outsize + 2, svg_p->restart);
3007 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3008 S_VALUE(snip->OutRequests, snic->OutRequests, itv),
3009 out + 3, outsize + 3, svg_p->restart);
3011 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3012 S_VALUE(snip->ReasmReqds, snic->ReasmReqds, itv),
3013 out + 4, outsize + 4, svg_p->restart);
3015 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3016 S_VALUE(snip->ReasmOKs, snic->ReasmOKs, itv),
3017 out + 5, outsize + 5, svg_p->restart);
3019 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3020 S_VALUE(snip->FragOKs, snic->FragOKs, itv),
3021 out + 6, outsize + 6, svg_p->restart);
3023 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3024 S_VALUE(snip->FragCreates, snic->FragCreates, itv),
3025 out + 7, outsize + 7, svg_p->restart);
3028 if (action & F_END) {
3029 draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
3030 spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
3032 /* Free remaining structures */
3033 free_graphs(out, outsize, spmin, spmax);
3038 ***************************************************************************
3039 * Display IPv4 traffic errors statistics in SVG.
3042 * @a Activity structure with statistics.
3043 * @curr Index in array for current sample statistics.
3044 * @action Action expected from current function.
3045 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
3046 * flag indicating that a restart record has been previously
3047 * found (.@restart) and time used for the X axis origin
3049 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
3050 * @record_hdr Pointer on record header of current stats sample.
3051 ***************************************************************************
3053 __print_funct_t svg_print_net_eip_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
3054 unsigned long long itv, struct record_header *record_hdr)
3056 struct stats_net_eip
3057 *sneic = (struct stats_net_eip *) a->buf[curr],
3058 *sneip = (struct stats_net_eip *) a->buf[!curr];
3059 int group[] = {3, 2, 3};
3060 int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH};
3061 char *title[] = {"IPv4 traffic errors statistics (1)", "IPv4 traffic errors statistics (2)",
3062 "IPv4 traffic errors statistics (3)"};
3063 char *g_title[] = {"ihdrerr/s", "iadrerr/s", "iukwnpr/s",
3064 "idisc/s", "odisc/s",
3065 "onort/s", "asmf/s", "fragf/s"};
3066 int g_fields[] = {0, 1, 2, 3, 4, 5, 6, 7};
3067 static double *spmin, *spmax;
3069 static int *outsize;
3071 if (action & F_BEGIN) {
3073 * Allocate arrays that will contain the graphs data
3074 * and the min/max values.
3076 out = allocate_graph_lines(8, &outsize, &spmin, &spmax);
3079 if (action & F_MAIN) {
3080 /* Check for min/max values */
3081 save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
3082 itv, spmin, spmax, g_fields);
3085 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3086 S_VALUE(sneip->InHdrErrors, sneic->InHdrErrors, itv),
3087 out, outsize, svg_p->restart);
3089 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3090 S_VALUE(sneip->InAddrErrors, sneic->InAddrErrors, itv),
3091 out + 1, outsize + 1, svg_p->restart);
3093 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3094 S_VALUE(sneip->InUnknownProtos, sneic->InUnknownProtos, itv),
3095 out + 2, outsize + 2, svg_p->restart);
3097 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3098 S_VALUE(sneip->InDiscards, sneic->InDiscards, itv),
3099 out + 3, outsize + 3, svg_p->restart);
3101 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3102 S_VALUE(sneip->OutDiscards, sneic->OutDiscards, itv),
3103 out + 4, outsize + 4, svg_p->restart);
3105 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3106 S_VALUE(sneip->OutNoRoutes, sneic->OutNoRoutes, itv),
3107 out + 5, outsize + 5, svg_p->restart);
3109 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3110 S_VALUE(sneip->ReasmFails, sneic->ReasmFails, itv),
3111 out + 6, outsize + 6, svg_p->restart);
3113 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3114 S_VALUE(sneip->FragFails, sneic->FragFails, itv),
3115 out + 7, outsize + 7, svg_p->restart);
3118 if (action & F_END) {
3119 draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
3120 spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
3122 /* Free remaining structures */
3123 free_graphs(out, outsize, spmin, spmax);
3128 ***************************************************************************
3129 * Display ICMPv4 traffic statistics in SVG.
3132 * @a Activity structure with statistics.
3133 * @curr Index in array for current sample statistics.
3134 * @action Action expected from current function.
3135 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
3136 * flag indicating that a restart record has been previously
3137 * found (.@restart) and time used for the X axis origin
3139 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
3140 * @record_hdr Pointer on record header of current stats sample.
3141 ***************************************************************************
3143 __print_funct_t svg_print_net_icmp_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
3144 unsigned long long itv, struct record_header *record_hdr)
3146 struct stats_net_icmp
3147 *snic = (struct stats_net_icmp *) a->buf[curr],
3148 *snip = (struct stats_net_icmp *) a->buf[!curr];
3149 int group[] = {2, 4, 4, 4};
3150 int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH,
3152 char *title[] = {"ICMPv4 traffic statistics (1)", "ICMPv4 traffic statistics (2)",
3153 "ICMPv4 traffic statistics (3)", "ICMPv4 traffic statistics (4)"};
3154 char *g_title[] = {"imsg/s", "omsg/s",
3155 "iech/s", "iechr/s", "oech/s", "oechr/s",
3156 "itm/s", "itmr/s", "otm/s", "otmr/s",
3157 "iadrmk/s", "iadrmkr/s", "oadrmk/s", "oadrmkr/s"};
3158 int g_fields[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
3159 static double *spmin, *spmax;
3161 static int *outsize;
3163 if (action & F_BEGIN) {
3165 * Allocate arrays that will contain the graphs data
3166 * and the min/max values.
3168 out = allocate_graph_lines(14, &outsize, &spmin, &spmax);
3171 if (action & F_MAIN) {
3172 /* Check for min/max values */
3173 save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
3174 itv, spmin, spmax, g_fields);
3177 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3178 S_VALUE(snip->InMsgs, snic->InMsgs, itv),
3179 out, outsize, svg_p->restart);
3181 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3182 S_VALUE(snip->OutMsgs, snic->OutMsgs, itv),
3183 out + 1, outsize + 1, svg_p->restart);
3185 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3186 S_VALUE(snip->InEchos, snic->InEchos, itv),
3187 out + 2, outsize + 2, svg_p->restart);
3189 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3190 S_VALUE(snip->InEchoReps, snic->InEchoReps, itv),
3191 out + 3, outsize + 3, svg_p->restart);
3193 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3194 S_VALUE(snip->OutEchos, snic->OutEchos, itv),
3195 out + 4, outsize + 4, svg_p->restart);
3197 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3198 S_VALUE(snip->OutEchoReps, snic->OutEchoReps, itv),
3199 out + 5, outsize + 5, svg_p->restart);
3201 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3202 S_VALUE(snip->InTimestamps, snic->InTimestamps, itv),
3203 out + 6, outsize + 6, svg_p->restart);
3205 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3206 S_VALUE(snip->InTimestampReps, snic->InTimestampReps, itv),
3207 out + 7, outsize + 7, svg_p->restart);
3209 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3210 S_VALUE(snip->OutTimestamps, snic->OutTimestamps, itv),
3211 out + 8, outsize + 8, svg_p->restart);
3213 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3214 S_VALUE(snip->OutTimestampReps, snic->OutTimestampReps, itv),
3215 out + 9, outsize + 9, svg_p->restart);
3217 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3218 S_VALUE(snip->InAddrMasks, snic->InAddrMasks, itv),
3219 out + 10, outsize + 10, svg_p->restart);
3221 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3222 S_VALUE(snip->InAddrMaskReps, snic->InAddrMaskReps, itv),
3223 out + 11, outsize + 11, svg_p->restart);
3225 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3226 S_VALUE(snip->OutAddrMasks, snic->OutAddrMasks, itv),
3227 out + 12, outsize + 12, svg_p->restart);
3229 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3230 S_VALUE(snip->OutAddrMaskReps, snic->OutAddrMaskReps, itv),
3231 out + 13, outsize + 13, svg_p->restart);
3234 if (action & F_END) {
3235 draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
3236 spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
3238 /* Free remaining structures */
3239 free_graphs(out, outsize, spmin, spmax);
3244 ***************************************************************************
3245 * Display ICMPv4 traffic errors statistics in SVG.
3248 * @a Activity structure with statistics.
3249 * @curr Index in array for current sample statistics.
3250 * @action Action expected from current function.
3251 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
3252 * flag indicating that a restart record has been previously
3253 * found (.@restart) and time used for the X axis origin
3255 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
3256 * @record_hdr Pointer on record header of current stats sample.
3257 ***************************************************************************
3259 __print_funct_t svg_print_net_eicmp_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
3260 unsigned long long itv, struct record_header *record_hdr)
3262 struct stats_net_eicmp
3263 *sneic = (struct stats_net_eicmp *) a->buf[curr],
3264 *sneip = (struct stats_net_eicmp *) a->buf[!curr];
3265 int group[] = {2, 2, 2, 2, 2, 2};
3266 int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH,
3267 SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH};
3268 char *title[] = {"ICMPv4 traffic errors statistics (1)", "ICMPv4 traffic errors statistics (2)",
3269 "ICMPv4 traffic errors statistics (3)", "ICMPv4 traffic errors statistics (4)",
3270 "ICMPv4 traffic errors statistics (5)", "ICMPv4 traffic errors statistics (6)"};
3271 char *g_title[] = {"ierr/s", "oerr/s",
3272 "idstunr/s", "odstunr/s",
3273 "itmex/s", "otmex/s",
3274 "iparmpb/s", "oparmpb/s",
3275 "isrcq/s", "osrcq/s",
3276 "iredir/s", "oredir/s"};
3277 int g_fields[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
3278 static double *spmin, *spmax;
3280 static int *outsize;
3282 if (action & F_BEGIN) {
3284 * Allocate arrays that will contain the graphs data
3285 * and the min/max values.
3287 out = allocate_graph_lines(12, &outsize, &spmin, &spmax);
3290 if (action & F_MAIN) {
3291 /* Check for min/max values */
3292 save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
3293 itv, spmin, spmax, g_fields);
3296 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3297 S_VALUE(sneip->InErrors, sneic->InErrors, itv),
3298 out, outsize, svg_p->restart);
3300 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3301 S_VALUE(sneip->OutErrors, sneic->OutErrors, itv),
3302 out + 1, outsize + 1, svg_p->restart);
3304 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3305 S_VALUE(sneip->InDestUnreachs, sneic->InDestUnreachs, itv),
3306 out + 2, outsize + 2, svg_p->restart);
3308 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3309 S_VALUE(sneip->OutDestUnreachs, sneic->OutDestUnreachs, itv),
3310 out + 3, outsize + 3, svg_p->restart);
3312 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3313 S_VALUE(sneip->InTimeExcds, sneic->InTimeExcds, itv),
3314 out + 4, outsize + 4, svg_p->restart);
3316 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3317 S_VALUE(sneip->OutTimeExcds, sneic->OutTimeExcds, itv),
3318 out + 5, outsize + 5, svg_p->restart);
3320 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3321 S_VALUE(sneip->InParmProbs, sneic->InParmProbs, itv),
3322 out + 6, outsize + 6, svg_p->restart);
3324 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3325 S_VALUE(sneip->OutParmProbs, sneic->OutParmProbs, itv),
3326 out + 7, outsize + 7, svg_p->restart);
3328 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3329 S_VALUE(sneip->InSrcQuenchs, sneic->InSrcQuenchs, itv),
3330 out + 8, outsize + 8, svg_p->restart);
3332 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3333 S_VALUE(sneip->OutSrcQuenchs, sneic->OutSrcQuenchs, itv),
3334 out + 9, outsize + 9, svg_p->restart);
3336 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3337 S_VALUE(sneip->InRedirects, sneic->InRedirects, itv),
3338 out + 10, outsize + 10, svg_p->restart);
3340 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3341 S_VALUE(sneip->OutRedirects, sneic->OutRedirects, itv),
3342 out + 11, outsize + 11, svg_p->restart);
3345 if (action & F_END) {
3346 draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
3347 spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
3349 /* Free remaining structures */
3350 free_graphs(out, outsize, spmin, spmax);
3355 ***************************************************************************
3356 * Display TCPv4 traffic statistics in SVG.
3359 * @a Activity structure with statistics.
3360 * @curr Index in array for current sample statistics.
3361 * @action Action expected from current function.
3362 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
3363 * flag indicating that a restart record has been previously
3364 * found (.@restart) and time used for the X axis origin
3366 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
3367 * @record_hdr Pointer on record header of current stats sample.
3368 ***************************************************************************
3370 __print_funct_t svg_print_net_tcp_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
3371 unsigned long long itv, struct record_header *record_hdr)
3373 struct stats_net_tcp
3374 *sntc = (struct stats_net_tcp *) a->buf[curr],
3375 *sntp = (struct stats_net_tcp *) a->buf[!curr];
3376 int group[] = {2, 2};
3377 int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH};
3378 char *title[] = {"TCPv4 traffic statistics (1)", "TCPv4 traffic statistics (2)"};
3379 char *g_title[] = {"active/s", "passive/s",
3380 "iseg/s", "oseg/s"};
3381 int g_fields[] = {0, 1, 2, 3};
3382 static double *spmin, *spmax;
3384 static int *outsize;
3386 if (action & F_BEGIN) {
3388 * Allocate arrays that will contain the graphs data
3389 * and the min/max values.
3391 out = allocate_graph_lines(4, &outsize, &spmin, &spmax);
3394 if (action & F_MAIN) {
3395 /* Check for min/max values */
3396 save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
3397 itv, spmin, spmax, g_fields);
3400 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3401 S_VALUE(sntp->ActiveOpens, sntc->ActiveOpens, itv),
3402 out, outsize, svg_p->restart);
3404 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3405 S_VALUE(sntp->PassiveOpens, sntc->PassiveOpens, itv),
3406 out + 1, outsize + 1, svg_p->restart);
3408 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3409 S_VALUE(sntp->InSegs, sntc->InSegs, itv),
3410 out + 2, outsize + 2, svg_p->restart);
3412 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3413 S_VALUE(sntp->OutSegs, sntc->OutSegs, itv),
3414 out + 3, outsize + 3, svg_p->restart);
3417 if (action & F_END) {
3418 draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
3419 spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
3421 /* Free remaining structures */
3422 free_graphs(out, outsize, spmin, spmax);
3427 ***************************************************************************
3428 * Display TCPv4 traffic errors statistics in SVG.
3431 * @a Activity structure with statistics.
3432 * @curr Index in array for current sample statistics.
3433 * @action Action expected from current function.
3434 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
3435 * flag indicating that a restart record has been previously
3436 * found (.@restart) and time used for the X axis origin
3438 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
3439 * @record_hdr Pointer on record header of current stats sample.
3440 ***************************************************************************
3442 __print_funct_t svg_print_net_etcp_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
3443 unsigned long long itv, struct record_header *record_hdr)
3445 struct stats_net_etcp
3446 *snetc = (struct stats_net_etcp *) a->buf[curr],
3447 *snetp = (struct stats_net_etcp *) a->buf[!curr];
3448 int group[] = {2, 3};
3449 int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH};
3450 char *title[] = {"TCPv4 traffic errors statistics (1)", "TCPv4 traffic errors statistics (2)"};
3451 char *g_title[] = {"atmptf/s", "estres/s",
3452 "retrans/s", "isegerr/s", "orsts/s"};
3453 int g_fields[] = {0, 1, 2, 3, 4};
3454 static double *spmin, *spmax;
3456 static int *outsize;
3458 if (action & F_BEGIN) {
3460 * Allocate arrays that will contain the graphs data
3461 * and the min/max values.
3463 out = allocate_graph_lines(5, &outsize, &spmin, &spmax);
3466 if (action & F_MAIN) {
3467 /* Check for min/max values */
3468 save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
3469 itv, spmin, spmax, g_fields);
3472 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3473 S_VALUE(snetp->AttemptFails, snetc->AttemptFails, itv),
3474 out, outsize, svg_p->restart);
3476 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3477 S_VALUE(snetp->EstabResets, snetc->EstabResets, itv),
3478 out + 1, outsize + 1, svg_p->restart);
3480 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3481 S_VALUE(snetp->RetransSegs, snetc->RetransSegs, itv),
3482 out + 2, outsize + 2, svg_p->restart);
3484 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3485 S_VALUE(snetp->InErrs, snetc->InErrs, itv),
3486 out + 3, outsize + 3, svg_p->restart);
3488 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3489 S_VALUE(snetp->OutRsts, snetc->OutRsts, itv),
3490 out + 4, outsize + 4, svg_p->restart);
3493 if (action & F_END) {
3494 draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
3495 spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
3497 /* Free remaining structures */
3498 free_graphs(out, outsize, spmin, spmax);
3503 ***************************************************************************
3504 * Display UDPv4 traffic statistics in SVG.
3507 * @a Activity structure with statistics.
3508 * @curr Index in array for current sample statistics.
3509 * @action Action expected from current function.
3510 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
3511 * flag indicating that a restart record has been previously
3512 * found (.@restart) and time used for the X axis origin
3514 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
3515 * @record_hdr Pointer on record header of current stats sample.
3516 ***************************************************************************
3518 __print_funct_t svg_print_net_udp_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
3519 unsigned long long itv, struct record_header *record_hdr)
3521 struct stats_net_udp
3522 *snuc = (struct stats_net_udp *) a->buf[curr],
3523 *snup = (struct stats_net_udp *) a->buf[!curr];
3524 int group[] = {2, 2};
3525 int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH};
3526 char *title[] = {"UDPv4 traffic statistics (1)", "UDPv4 traffic statistics (2)"};
3527 char *g_title[] = {"idgm/s", "odgm/s",
3528 "noport/s", "idgmerr/s"};
3529 int g_fields[] = {0, 1, 2, 3};
3530 static double *spmin, *spmax;
3532 static int *outsize;
3534 if (action & F_BEGIN) {
3536 * Allocate arrays that will contain the graphs data
3537 * and the min/max values.
3539 out = allocate_graph_lines(4, &outsize, &spmin, &spmax);
3542 if (action & F_MAIN) {
3543 /* Check for min/max values */
3544 save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
3545 itv, spmin, spmax, g_fields);
3548 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3549 S_VALUE(snup->InDatagrams, snuc->InDatagrams, itv),
3550 out, outsize, svg_p->restart);
3552 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3553 S_VALUE(snup->OutDatagrams, snuc->OutDatagrams, itv),
3554 out + 1, outsize + 1, svg_p->restart);
3556 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3557 S_VALUE(snup->NoPorts, snuc->NoPorts, itv),
3558 out + 2, outsize + 2, svg_p->restart);
3560 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3561 S_VALUE(snup->InErrors, snuc->InErrors, itv),
3562 out + 3, outsize + 3, svg_p->restart);
3565 if (action & F_END) {
3566 draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
3567 spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
3569 /* Free remaining structures */
3570 free_graphs(out, outsize, spmin, spmax);
3575 ***************************************************************************
3576 * Display IPV6 socket statistics in SVG.
3579 * @a Activity structure with statistics.
3580 * @curr Index in array for current sample statistics.
3581 * @action Action expected from current function.
3582 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
3583 * flag indicating that a restart record has been previously
3584 * found (.@restart) and time used for the X axis origin
3586 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
3587 * @record_hdr Pointer on record header of current stats sample.
3588 ***************************************************************************
3590 __print_funct_t svg_print_net_sock6_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
3591 unsigned long long itv, struct record_header *record_hdr)
3593 struct stats_net_sock6
3594 *snsc = (struct stats_net_sock6 *) a->buf[curr];
3596 int g_type[] = {SVG_LINE_GRAPH};
3597 char *title[] = {"IPv6 sockets statistics"};
3598 char *g_title[] = {"~tcp6sck", "~udp6sck", "~raw6sck", "~ip6-frag"};
3599 int g_fields[] = {0, 1, 2, 3};
3600 static double *spmin, *spmax;
3602 static int *outsize;
3604 if (action & F_BEGIN) {
3606 * Allocate arrays that will contain the graphs data
3607 * and the min/max values.
3609 out = allocate_graph_lines(4, &outsize, &spmin, &spmax);
3612 if (action & F_MAIN) {
3613 /* Check for min/max values */
3614 save_extrema(a->gtypes_nr, (void *) a->buf[curr], NULL,
3615 itv, spmin, spmax, g_fields);
3617 lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
3618 (unsigned long long) snsc->tcp6_inuse,
3619 out, outsize, svg_p->restart);
3621 lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
3622 (unsigned long long) snsc->udp6_inuse,
3623 out + 1, outsize + 1, svg_p->restart);
3625 lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
3626 (unsigned long long) snsc->raw6_inuse,
3627 out + 2, outsize + 2, svg_p->restart);
3629 lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
3630 (unsigned long long) snsc->frag6_inuse,
3631 out + 3, outsize + 3, svg_p->restart);
3634 if (action & F_END) {
3635 draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
3636 spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
3638 /* Free remaining structures */
3639 free_graphs(out, outsize, spmin, spmax);
3644 ***************************************************************************
3645 * Display IPv6 traffic statistics in SVG.
3648 * @a Activity structure with statistics.
3649 * @curr Index in array for current sample statistics.
3650 * @action Action expected from current function.
3651 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
3652 * flag indicating that a restart record has been previously
3653 * found (.@restart) and time used for the X axis origin
3655 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
3656 * @record_hdr Pointer on record header of current stats sample.
3657 ***************************************************************************
3659 __print_funct_t svg_print_net_ip6_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
3660 unsigned long long itv, struct record_header *record_hdr)
3662 struct stats_net_ip6
3663 *snic = (struct stats_net_ip6 *) a->buf[curr],
3664 *snip = (struct stats_net_ip6 *) a->buf[!curr];
3665 int group[] = {4, 2, 2, 2};
3666 int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH,
3668 char *title[] = {"IPv6 traffic statistics (1)", "IPv6 traffic statistics (2)",
3669 "IPv6 traffic statistics (3)", "IPv6 traffic statistics (4)"};
3670 char *g_title[] = {"irec6/s", "fwddgm6/s", "idel6/s", "orq6/s",
3671 "asmrq6/s", "asmok6/s",
3672 "imcpck6/s", "omcpck6/s",
3673 "fragok6/s", "fragcr6/s"};
3674 int g_fields[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
3675 static double *spmin, *spmax;
3677 static int *outsize;
3679 if (action & F_BEGIN) {
3681 * Allocate arrays that will contain the graphs data
3682 * and the min/max values.
3684 out = allocate_graph_lines(10, &outsize, &spmin, &spmax);
3687 if (action & F_MAIN) {
3688 /* Check for min/max values */
3689 save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
3690 itv, spmin, spmax, g_fields);
3693 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3694 S_VALUE(snip->InReceives6, snic->InReceives6, itv),
3695 out, outsize, svg_p->restart);
3697 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3698 S_VALUE(snip->OutForwDatagrams6, snic->OutForwDatagrams6, itv),
3699 out + 1, outsize + 1, svg_p->restart);
3701 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3702 S_VALUE(snip->InDelivers6, snic->InDelivers6, itv),
3703 out + 2, outsize + 2, svg_p->restart);
3705 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3706 S_VALUE(snip->OutRequests6, snic->OutRequests6, itv),
3707 out + 3, outsize + 3, svg_p->restart);
3709 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3710 S_VALUE(snip->ReasmReqds6, snic->ReasmReqds6, itv),
3711 out + 4, outsize + 4, svg_p->restart);
3713 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3714 S_VALUE(snip->ReasmOKs6, snic->ReasmOKs6, itv),
3715 out + 5, outsize + 5, svg_p->restart);
3717 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3718 S_VALUE(snip->InMcastPkts6, snic->InMcastPkts6, itv),
3719 out + 6, outsize + 6, svg_p->restart);
3721 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3722 S_VALUE(snip->OutMcastPkts6, snic->OutMcastPkts6, itv),
3723 out + 7, outsize + 7, svg_p->restart);
3725 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3726 S_VALUE(snip->FragOKs6, snic->FragOKs6, itv),
3727 out + 8, outsize + 8, svg_p->restart);
3729 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3730 S_VALUE(snip->FragCreates6, snic->FragCreates6, itv),
3731 out + 9, outsize + 9, svg_p->restart);
3734 if (action & F_END) {
3735 draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
3736 spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
3738 /* Free remaining structures */
3739 free_graphs(out, outsize, spmin, spmax);
3744 ***************************************************************************
3745 * Display IPv6 traffic errors statistics in SVG.
3748 * @a Activity structure with statistics.
3749 * @curr Index in array for current sample statistics.
3750 * @action Action expected from current function.
3751 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
3752 * flag indicating that a restart record has been previously
3753 * found (.@restart) and time used for the X axis origin
3755 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
3756 * @record_hdr Pointer on record header of current stats sample.
3757 ***************************************************************************
3759 __print_funct_t svg_print_net_eip6_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
3760 unsigned long long itv, struct record_header *record_hdr)
3762 struct stats_net_eip6
3763 *sneic = (struct stats_net_eip6 *) a->buf[curr],
3764 *sneip = (struct stats_net_eip6 *) a->buf[!curr];
3765 int group[] = {4, 2, 2, 3};
3766 int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH,
3768 char *title[] = {"IPv6 traffic errors statistics (1)", "IPv6 traffic errors statistics (2)",
3769 "IPv6 traffic errors statistics (3)", "IPv6 traffic errors statistics (4)",
3770 "IPv6 traffic errors statistics (5)"};
3771 char *g_title[] = {"ihdrer6/s", "iadrer6/s", "iukwnp6/s", "i2big6/s",
3772 "idisc6/s", "odisc6/s",
3773 "inort6/s", "onort6/s",
3774 "asmf6/s", "fragf6/s", "itrpck6/s"};
3775 int g_fields[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
3776 static double *spmin, *spmax;
3778 static int *outsize;
3780 if (action & F_BEGIN) {
3782 * Allocate arrays that will contain the graphs data
3783 * and the min/max values.
3785 out = allocate_graph_lines(11, &outsize, &spmin, &spmax);
3788 if (action & F_MAIN) {
3789 /* Check for min/max values */
3790 save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
3791 itv, spmin, spmax, g_fields);
3794 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3795 S_VALUE(sneip->InHdrErrors6, sneic->InHdrErrors6, itv),
3796 out, outsize, svg_p->restart);
3798 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3799 S_VALUE(sneip->InAddrErrors6, sneic->InAddrErrors6, itv),
3800 out + 1, outsize + 1, svg_p->restart);
3802 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3803 S_VALUE(sneip->InUnknownProtos6, sneic->InUnknownProtos6, itv),
3804 out + 2, outsize + 2, svg_p->restart);
3806 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3807 S_VALUE(sneip->InTooBigErrors6, sneic->InTooBigErrors6, itv),
3808 out + 3, outsize + 3, svg_p->restart);
3810 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3811 S_VALUE(sneip->InDiscards6, sneic->InDiscards6, itv),
3812 out + 4, outsize + 4, svg_p->restart);
3814 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3815 S_VALUE(sneip->OutDiscards6, sneic->OutDiscards6, itv),
3816 out + 5, outsize + 5, svg_p->restart);
3818 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3819 S_VALUE(sneip->InNoRoutes6, sneic->InNoRoutes6, itv),
3820 out + 6, outsize + 6, svg_p->restart);
3822 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3823 S_VALUE(sneip->OutNoRoutes6, sneic->OutNoRoutes6, itv),
3824 out + 7, outsize + 7, svg_p->restart);
3826 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3827 S_VALUE(sneip->ReasmFails6, sneic->ReasmFails6, itv),
3828 out + 8, outsize + 8, svg_p->restart);
3830 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3831 S_VALUE(sneip->FragFails6, sneic->FragFails6, itv),
3832 out + 9, outsize + 9, svg_p->restart);
3834 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3835 S_VALUE(sneip->InTruncatedPkts6, sneic->InTruncatedPkts6, itv),
3836 out + 10, outsize + 10, svg_p->restart);
3839 if (action & F_END) {
3840 draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
3841 spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
3843 /* Free remaining structures */
3844 free_graphs(out, outsize, spmin, spmax);
3849 ***************************************************************************
3850 * Display ICMPv6 traffic statistics in SVG.
3853 * @a Activity structure with statistics.
3854 * @curr Index in array for current sample statistics.
3855 * @action Action expected from current function.
3856 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
3857 * flag indicating that a restart record has been previously
3858 * found (.@restart) and time used for the X axis origin
3860 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
3861 * @record_hdr Pointer on record header of current stats sample.
3862 ***************************************************************************
3864 __print_funct_t svg_print_net_icmp6_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
3865 unsigned long long itv, struct record_header *record_hdr)
3867 struct stats_net_icmp6
3868 *snic = (struct stats_net_icmp6 *) a->buf[curr],
3869 *snip = (struct stats_net_icmp6 *) a->buf[!curr];
3870 int group[] = {2, 3, 5, 3, 4};
3871 int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH,
3872 SVG_LINE_GRAPH, SVG_LINE_GRAPH};
3873 char *title[] = {"ICMPv6 traffic statistics (1)", "ICMPv6 traffic statistics (2)",
3874 "ICMPv6 traffic statistics (3)", "ICMPv6 traffic statistics (4)",
3875 "ICMPv6 traffic statistics (5)"};
3876 char *g_title[] = {"imsg6/s", "omsg6/s",
3877 "iech6/s", "iechr6/s", "oechr6/s",
3878 "igmbq6/s", "igmbr6/s", "ogmbr6/s", "igmbrd6/s", "ogmbrd6/s",
3879 "irtsol6/s", "ortsol6/s", "irtad6/s",
3880 "inbsol6/s", "onbsol6/s", "inbad6/s", "onbad6/s"};
3881 int g_fields[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
3882 static double *spmin, *spmax;
3884 static int *outsize;
3886 if (action & F_BEGIN) {
3888 * Allocate arrays that will contain the graphs data
3889 * and the min/max values.
3891 out = allocate_graph_lines(17, &outsize, &spmin, &spmax);
3894 if (action & F_MAIN) {
3895 /* Check for min/max values */
3896 save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
3897 itv, spmin, spmax, g_fields);
3900 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3901 S_VALUE(snip->InMsgs6, snic->InMsgs6, itv),
3902 out, outsize, svg_p->restart);
3904 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3905 S_VALUE(snip->OutMsgs6, snic->OutMsgs6, itv),
3906 out + 1, outsize + 1, svg_p->restart);
3908 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3909 S_VALUE(snip->InEchos6, snic->InEchos6, itv),
3910 out + 2, outsize + 2, svg_p->restart);
3912 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3913 S_VALUE(snip->InEchoReplies6, snic->InEchoReplies6, itv),
3914 out + 3, outsize + 3, svg_p->restart);
3916 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3917 S_VALUE(snip->OutEchoReplies6, snic->OutEchoReplies6, itv),
3918 out + 4, outsize + 4, svg_p->restart);
3920 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3921 S_VALUE(snip->InGroupMembQueries6, snic->InGroupMembQueries6, itv),
3922 out + 5, outsize + 5, svg_p->restart);
3924 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3925 S_VALUE(snip->InGroupMembResponses6, snic->InGroupMembResponses6, itv),
3926 out + 6, outsize + 6, svg_p->restart);
3928 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3929 S_VALUE(snip->OutGroupMembResponses6, snic->OutGroupMembResponses6, itv),
3930 out + 7, outsize + 7, svg_p->restart);
3932 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3933 S_VALUE(snip->InGroupMembReductions6, snic->InGroupMembReductions6, itv),
3934 out + 8, outsize + 8, svg_p->restart);
3936 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3937 S_VALUE(snip->OutGroupMembReductions6, snic->OutGroupMembReductions6, itv),
3938 out + 9, outsize + 9, svg_p->restart);
3940 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3941 S_VALUE(snip->InRouterSolicits6, snic->InRouterSolicits6, itv),
3942 out + 10, outsize + 10, svg_p->restart);
3944 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3945 S_VALUE(snip->OutRouterSolicits6, snic->OutRouterSolicits6, itv),
3946 out + 11, outsize + 11, svg_p->restart);
3948 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3949 S_VALUE(snip->InRouterAdvertisements6, snic->InRouterAdvertisements6, itv),
3950 out + 12, outsize + 12, svg_p->restart);
3952 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3953 S_VALUE(snip->InNeighborSolicits6, snic->InNeighborSolicits6, itv),
3954 out + 13, outsize + 13, svg_p->restart);
3956 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3957 S_VALUE(snip->OutNeighborSolicits6, snic->OutNeighborSolicits6, itv),
3958 out + 14, outsize + 14, svg_p->restart);
3960 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3961 S_VALUE(snip->InNeighborAdvertisements6, snic->InNeighborAdvertisements6, itv),
3962 out + 15, outsize + 15, svg_p->restart);
3964 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
3965 S_VALUE(snip->OutNeighborAdvertisements6, snic->OutNeighborAdvertisements6, itv),
3966 out + 16, outsize + 16, svg_p->restart);
3969 if (action & F_END) {
3970 draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
3971 spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
3973 /* Free remaining structures */
3974 free_graphs(out, outsize, spmin, spmax);
3979 ***************************************************************************
3980 * Display ICMPv6 traffic errors statistics in SVG.
3983 * @a Activity structure with statistics.
3984 * @curr Index in array for current sample statistics.
3985 * @action Action expected from current function.
3986 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
3987 * flag indicating that a restart record has been previously
3988 * found (.@restart) and time used for the X axis origin
3990 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
3991 * @record_hdr Pointer on record header of current stats sample.
3992 ***************************************************************************
3994 __print_funct_t svg_print_net_eicmp6_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
3995 unsigned long long itv, struct record_header *record_hdr)
3997 struct stats_net_eicmp6
3998 *sneic = (struct stats_net_eicmp6 *) a->buf[curr],
3999 *sneip = (struct stats_net_eicmp6 *) a->buf[!curr];
4000 int group[] = {1, 2, 2, 2, 2, 2};
4001 int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH,
4002 SVG_LINE_GRAPH, SVG_LINE_GRAPH, SVG_LINE_GRAPH};
4003 char *title[] = {"ICMPv6 traffic errors statistics (1)", "ICMPv6 traffic errors statistics (2)",
4004 "ICMPv6 traffic errors statistics (3)", "ICMPv6 traffic errors statistics (4)",
4005 "ICMPv6 traffic errors statistics (5)", "ICMPv6 traffic errors statistics (6)"};
4006 char *g_title[] = {"ierr6/s",
4007 "idtunr6/s", "odtunr6/s",
4008 "itmex6/s", "otmex6/s",
4009 "iprmpb6/s", "oprmpb6/s",
4010 "iredir6/s", "oredir6/s",
4011 "ipck2b6/s", "opck2b6/s"};
4012 int g_fields[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
4013 static double *spmin, *spmax;
4015 static int *outsize;
4017 if (action & F_BEGIN) {
4019 * Allocate arrays that will contain the graphs data
4020 * and the min/max values.
4022 out = allocate_graph_lines(11, &outsize, &spmin, &spmax);
4025 if (action & F_MAIN) {
4026 /* Check for min/max values */
4027 save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
4028 itv, spmin, spmax, g_fields);
4031 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
4032 S_VALUE(sneip->InErrors6, sneic->InErrors6, itv),
4033 out, outsize, svg_p->restart);
4035 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
4036 S_VALUE(sneip->InDestUnreachs6, sneic->InDestUnreachs6, itv),
4037 out + 1, outsize + 1, svg_p->restart);
4039 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
4040 S_VALUE(sneip->OutDestUnreachs6, sneic->OutDestUnreachs6, itv),
4041 out + 2, outsize + 2, svg_p->restart);
4043 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
4044 S_VALUE(sneip->InTimeExcds6, sneic->InTimeExcds6, itv),
4045 out + 3, outsize + 3, svg_p->restart);
4047 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
4048 S_VALUE(sneip->OutTimeExcds6, sneic->OutTimeExcds6, itv),
4049 out + 4, outsize + 4, svg_p->restart);
4051 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
4052 S_VALUE(sneip->InParmProblems6, sneic->InParmProblems6, itv),
4053 out + 5, outsize + 5, svg_p->restart);
4055 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
4056 S_VALUE(sneip->OutParmProblems6, sneic->OutParmProblems6, itv),
4057 out + 6, outsize + 6, svg_p->restart);
4059 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
4060 S_VALUE(sneip->InRedirects6, sneic->InRedirects6, itv),
4061 out + 7, outsize + 7, svg_p->restart);
4063 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
4064 S_VALUE(sneip->OutRedirects6, sneic->OutRedirects6, itv),
4065 out + 8, outsize + 8, svg_p->restart);
4067 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
4068 S_VALUE(sneip->InPktTooBigs6, sneic->InPktTooBigs6, itv),
4069 out + 9, outsize + 9, svg_p->restart);
4071 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
4072 S_VALUE(sneip->OutPktTooBigs6, sneic->OutPktTooBigs6, itv),
4073 out + 10, outsize + 10, svg_p->restart);
4076 if (action & F_END) {
4077 draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
4078 spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
4080 /* Free remaining structures */
4081 free_graphs(out, outsize, spmin, spmax);
4086 ***************************************************************************
4087 * Display UDPv6 traffic statistics in SVG.
4090 * @a Activity structure with statistics.
4091 * @curr Index in array for current sample statistics.
4092 * @action Action expected from current function.
4093 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
4094 * flag indicating that a restart record has been previously
4095 * found (.@restart) and time used for the X axis origin
4097 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
4098 * @record_hdr Pointer on record header of current stats sample.
4099 ***************************************************************************
4101 __print_funct_t svg_print_net_udp6_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
4102 unsigned long long itv, struct record_header *record_hdr)
4104 struct stats_net_udp6
4105 *snuc = (struct stats_net_udp6 *) a->buf[curr],
4106 *snup = (struct stats_net_udp6 *) a->buf[!curr];
4107 int group[] = {2, 2};
4108 int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH};
4109 char *title[] = {"UDPv6 traffic statistics (1)", "UDPv6 traffic statistics (2)"};
4110 char *g_title[] = {"idgm6/s", "odgm6/s",
4111 "noport6/s", "idgmer6/s"};
4112 int g_fields[] = {0, 1, 2, 3};
4113 static double *spmin, *spmax;
4115 static int *outsize;
4117 if (action & F_BEGIN) {
4119 * Allocate arrays that will contain the graphs data
4120 * and the min/max values.
4122 out = allocate_graph_lines(4, &outsize, &spmin, &spmax);
4125 if (action & F_MAIN) {
4126 /* Check for min/max values */
4127 save_extrema(a->gtypes_nr, (void *) a->buf[curr], (void *) a->buf[!curr],
4128 itv, spmin, spmax, g_fields);
4131 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
4132 S_VALUE(snup->InDatagrams6, snuc->InDatagrams6, itv),
4133 out, outsize, svg_p->restart);
4135 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
4136 S_VALUE(snup->OutDatagrams6, snuc->OutDatagrams6, itv),
4137 out + 1, outsize + 1, svg_p->restart);
4139 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
4140 S_VALUE(snup->NoPorts6, snuc->NoPorts6, itv),
4141 out + 2, outsize + 2, svg_p->restart);
4143 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
4144 S_VALUE(snup->InErrors6, snuc->InErrors6, itv),
4145 out + 3, outsize + 3, svg_p->restart);
4148 if (action & F_END) {
4149 draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
4150 spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
4152 /* Free remaining structures */
4153 free_graphs(out, outsize, spmin, spmax);
4158 ***************************************************************************
4159 * Display CPU frequency statistics in SVG.
4162 * @a Activity structure with statistics.
4163 * @curr Index in array for current sample statistics.
4164 * @action Action expected from current function.
4165 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
4166 * flag indicating that a restart record has been previously
4167 * found (.@restart) and time used for the X axis origin
4169 * @itv Interval of time in 1/100th of a second (unused here).
4170 * @record_hdr Pointer on record header of current stats sample.
4171 ***************************************************************************
4173 __print_funct_t svg_print_pwr_cpufreq_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
4174 unsigned long long itv, struct record_header *record_hdr)
4176 struct stats_pwr_cpufreq *spc, *spp;
4178 int g_type[] = {SVG_LINE_GRAPH};
4179 char *title[] = {"CPU clock frequency"};
4180 char *g_title[] = {"MHz"};
4181 static double *spmin, *spmax;
4183 static int *outsize;
4187 if (action & F_BEGIN) {
4189 * Allocate arrays that will contain the graphs data
4190 * and the min/max values.
4192 out = allocate_graph_lines(svg_p->nr_max, &outsize, &spmin, &spmax);
4195 if (action & F_MAIN) {
4197 for (i = 0; (i < a->nr[curr]) && (i < a->bitmap->b_size + 1); i++) {
4199 spc = (struct stats_pwr_cpufreq *) ((char *) a->buf[curr] + i * a->msize);
4200 spp = (struct stats_pwr_cpufreq *) ((char *) a->buf[!curr] + i * a->msize);
4202 /* Should current CPU (including CPU "all") be displayed? */
4203 if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))))
4208 * Note: Don't skip offline CPU here as it is needed
4209 * to make the graph go though 0.
4213 recappend(record_hdr->ust_time - svg_p->ust_time_ref,
4214 ((double) spp->cpufreq) / 100,
4215 ((double) spc->cpufreq) / 100,
4216 out + i, outsize + i, svg_p->restart, svg_p->dt,
4217 spmin + i, spmax + i);
4221 if (action & F_END) {
4222 for (i = 0; (i < svg_p->nr_max) && (i < a->bitmap->b_size + 1); i++) {
4224 /* Should current CPU (including CPU "all") be displayed? */
4225 if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))))
4230 /* This is CPU "all" */
4231 strcpy(item_name, "all");
4235 * If the maximum frequency reached by the CPU is 0, then
4236 * the CPU has been offline on the whole period.
4237 * => Don't display it.
4239 if (*(spmax + i) == 0)
4242 sprintf(item_name, "%d", i - 1);
4245 draw_activity_graphs(a->g_nr, g_type,
4246 title, g_title, item_name, group,
4247 spmin + i, spmax + i, out + i, outsize + i,
4248 svg_p, record_hdr, i, a->id, i);
4251 /* Free remaining structures */
4252 free_graphs(out, outsize, spmin, spmax);
4257 ***************************************************************************
4258 * Display fan statistics in SVG.
4261 * @a Activity structure with statistics.
4262 * @curr Index in array for current sample statistics.
4263 * @action Action expected from current function.
4264 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
4265 * flag indicating that a restart record has been previously
4266 * found (.@restart) and time used for the X axis origin
4268 * @itv Interval of time in 1/100th of a second (unused here).
4269 * @record_hdr Pointer on record header of current stats sample.
4270 ***************************************************************************
4272 __print_funct_t svg_print_pwr_fan_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
4273 unsigned long long itv, struct record_header *record_hdr)
4275 struct stats_pwr_fan *spc, *spp;
4277 int g_type[] = {SVG_LINE_GRAPH};
4278 char *title[] = {"Fans speed"};
4279 char *g_title[] = {"~rpm"};
4280 static double *spmin, *spmax;
4282 static int *outsize;
4283 char item_name[MAX_SENSORS_DEV_LEN + 8];
4286 if (action & F_BEGIN) {
4288 * Allocate arrays that will contain the graphs data
4289 * and the min/max values.
4291 out = allocate_graph_lines(svg_p->nr_max, &outsize, &spmin, &spmax);
4294 if (action & F_MAIN) {
4296 for (i = 0; i < a->nr[curr]; i++) {
4298 spc = (struct stats_pwr_fan *) ((char *) a->buf[curr] + i * a->msize);
4299 spp = (struct stats_pwr_fan *) ((char *) a->buf[!curr] + i * a->msize);
4302 recappend(record_hdr->ust_time - svg_p->ust_time_ref,
4305 out + i, outsize + i, svg_p->restart, svg_p->dt,
4306 spmin + i, spmax + i);
4310 if (action & F_END) {
4311 for (i = 0; i < svg_p->nr_max; i++) {
4313 spc = (struct stats_pwr_fan *) ((char *) a->buf[curr] + i * a->msize);
4315 snprintf(item_name, MAX_SENSORS_DEV_LEN + 8, "%d: %s", i + 1, spc->device);
4316 item_name[MAX_SENSORS_DEV_LEN + 7] = '\0';
4318 draw_activity_graphs(a->g_nr, g_type,
4319 title, g_title, item_name, group,
4320 spmin + i, spmax + i, out + i, outsize + i,
4321 svg_p, record_hdr, FALSE, a->id, i);
4324 /* Free remaining structures */
4325 free_graphs(out, outsize, spmin, spmax);
4330 ***************************************************************************
4331 * Display temperature statistics in SVG.
4334 * @a Activity structure with statistics.
4335 * @curr Index in array for current sample statistics.
4336 * @action Action expected from current function.
4337 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
4338 * flag indicating that a restart record has been previously
4339 * found (.@restart) and time used for the X axis origin
4341 * @itv Interval of time in 1/100th of a second (unused here).
4342 * @record_hdr Pointer on record header of current stats sample.
4343 ***************************************************************************
4345 __print_funct_t svg_print_pwr_temp_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
4346 unsigned long long itv, struct record_header *record_hdr)
4348 struct stats_pwr_temp *spc;
4349 int group[] = {1, 1};
4350 int g_type[] = {SVG_LINE_GRAPH, SVG_BAR_GRAPH};
4351 char *title[] = {"Devices temperature (1)",
4352 "Devices temperature (2)"};
4353 char *g_title[] = {"~degC",
4355 static double *spmin, *spmax;
4357 static int *outsize;
4358 char item_name[MAX_SENSORS_DEV_LEN + 8];
4362 if (action & F_BEGIN) {
4364 * Allocate arrays that will contain the graphs data
4365 * and the min/max values.
4367 out = allocate_graph_lines(2 * svg_p->nr_max, &outsize, &spmin, &spmax);
4370 if (action & F_MAIN) {
4371 /* For each temperature sensor */
4372 for (i = 0; i < a->nr[curr]; i++) {
4374 spc = (struct stats_pwr_temp *) ((char *) a->buf[curr] + i * a->msize);
4376 /* Look for min/max values */
4377 if (spc->temp < *(spmin + 2 * i)) {
4378 *(spmin + 2 * i) = spc->temp;
4380 if (spc->temp > *(spmax + 2 * i)) {
4381 *(spmax + 2 * i) = spc->temp;
4383 tval = (spc->temp_max - spc->temp_min) ?
4384 (spc->temp - spc->temp_min) / (spc->temp_max - spc->temp_min) * 100 :
4386 if (tval < *(spmin + 2 * i + 1)) {
4387 *(spmin + 2 * i + 1) = tval;
4389 if (tval > *(spmax + 2 * i + 1)) {
4390 *(spmax + 2 * i + 1) = tval;
4394 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
4396 out + 2 * i, outsize + 2 * i, svg_p->restart);
4398 brappend(record_hdr->ust_time - svg_p->ust_time_ref,
4400 out + 2 * i + 1, outsize + 2 * i + 1, svg_p->dt);
4404 if (action & F_END) {
4405 for (i = 0; i < svg_p->nr_max; i++) {
4407 spc = (struct stats_pwr_temp *) ((char *) a->buf[curr] + i * a->msize);
4409 snprintf(item_name, MAX_SENSORS_DEV_LEN + 8, "%d: %s", i + 1, spc->device);
4410 item_name[MAX_SENSORS_DEV_LEN + 7] = '\0';
4412 draw_activity_graphs(a->g_nr, g_type,
4413 title, g_title, item_name, group,
4414 spmin + 2 * i, spmax + 2 * i, out + 2 * i, outsize + 2 * i,
4415 svg_p, record_hdr, FALSE, a->id, i);
4418 /* Free remaining structures */
4419 free_graphs(out, outsize, spmin, spmax);
4424 ***************************************************************************
4425 * Display voltage inputs statistics in SVG.
4428 * @a Activity structure with statistics.
4429 * @curr Index in array for current sample statistics.
4430 * @action Action expected from current function.
4431 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
4432 * flag indicating that a restart record has been previously
4433 * found (.@restart) and time used for the X axis origin
4435 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
4436 * @record_hdr Pointer on record header of current stats sample.
4437 ***************************************************************************
4439 __print_funct_t svg_print_pwr_in_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
4440 unsigned long long itv, struct record_header *record_hdr)
4442 struct stats_pwr_in *spc;
4443 int group[] = {1, 1};
4444 int g_type[] = {SVG_LINE_GRAPH, SVG_BAR_GRAPH};
4445 char *title[] = {"Voltage inputs statistics (1)",
4446 "Voltage inputs statistics (2)"};
4447 char *g_title[] = {"inV",
4449 static double *spmin, *spmax;
4451 static int *outsize;
4452 char item_name[MAX_SENSORS_DEV_LEN + 8];
4456 if (action & F_BEGIN) {
4458 * Allocate arrays that will contain the graphs data
4459 * and the min/max values.
4461 out = allocate_graph_lines(2 * svg_p->nr_max, &outsize, &spmin, &spmax);
4464 if (action & F_MAIN) {
4465 /* For each voltage input sensor */
4466 for (i = 0; i < a->nr[curr]; i++) {
4468 spc = (struct stats_pwr_in *) ((char *) a->buf[curr] + i * a->msize);
4470 /* Look for min/max values */
4471 if (spc->in < *(spmin + 2 * i)) {
4472 *(spmin + 2 * i) = spc->in;
4474 if (spc->in > *(spmax + 2 * i)) {
4475 *(spmax + 2 * i) = spc->in;
4477 tval = (spc->in_max - spc->in_min) ?
4478 (spc->in - spc->in_min) / (spc->in_max - spc->in_min) * 100 :
4480 if (tval < *(spmin + 2 * i + 1)) {
4481 *(spmin + 2 * i + 1) = tval;
4483 if (tval > *(spmax + 2 * i + 1)) {
4484 *(spmax + 2 * i + 1) = tval;
4488 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
4490 out + 2 * i, outsize + 2 * i, svg_p->restart);
4492 brappend(record_hdr->ust_time - svg_p->ust_time_ref,
4494 out + 2 * i + 1, outsize + 2 * i + 1, svg_p->dt);
4498 if (action & F_END) {
4499 for (i = 0; i < svg_p->nr_max; i++) {
4501 spc = (struct stats_pwr_in *) ((char *) a->buf[curr] + i * a->msize);
4503 snprintf(item_name, MAX_SENSORS_DEV_LEN + 8, "%d: %s", i + 1, spc->device);
4504 item_name[MAX_SENSORS_DEV_LEN + 7] = '\0';
4506 draw_activity_graphs(a->g_nr, g_type,
4507 title, g_title, item_name, group,
4508 spmin + 2 * i, spmax + 2 * i, out + 2 * i, outsize + 2 * i,
4509 svg_p, record_hdr, FALSE, a->id, i);
4512 /* Free remaining structures */
4513 free_graphs(out, outsize, spmin, spmax);
4518 ***************************************************************************
4519 * Display huge pages statistics in SVG.
4522 * @a Activity structure with statistics.
4523 * @curr Index in array for current sample statistics.
4524 * @action Action expected from current function.
4525 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
4526 * flag indicating that a restart record has been previously
4527 * found (.@restart) and time used for the X axis origin
4529 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
4530 * @record_hdr Pointer on record header of current stats sample.
4531 ***************************************************************************
4533 __print_funct_t svg_print_huge_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
4534 unsigned long long itv, struct record_header *record_hdr)
4537 *smc = (struct stats_huge *) a->buf[curr];
4538 int group[] = {2, 1};
4539 int g_type[] = {SVG_LINE_GRAPH, SVG_BAR_GRAPH};
4540 char *title[] = {"Huge pages utilization (1)",
4541 "Huge pages utilization (2)"};
4542 char *g_title[] = {"~kbhugfree", "~kbhugused",
4544 int g_fields[] = {0};
4545 unsigned int local_types_nr[] = {0, 1, 0};
4546 static double *spmin, *spmax;
4548 static int *outsize;
4551 if (action & F_BEGIN) {
4553 * Allocate arrays that will contain the graphs data
4554 * and the min/max values.
4556 out = allocate_graph_lines(3, &outsize, &spmin, &spmax);
4559 if (action & F_MAIN) {
4560 /* Check for min/max values */
4561 save_extrema(local_types_nr, (void *) a->buf[curr], NULL,
4562 itv, spmin, spmax, g_fields);
4564 if (smc->tlhkb - smc->frhkb < *(spmin + 1)) {
4565 *(spmin + 1) = smc->tlhkb - smc->frhkb;
4567 if (smc->tlhkb - smc->frhkb > *(spmax + 1)) {
4568 *(spmax + 1) = smc->tlhkb - smc->frhkb;
4570 tval = smc->tlhkb ? SP_VALUE(smc->frhkb, smc->tlhkb, smc->tlhkb) : 0.0;
4571 if (tval < *(spmin + 2)) {
4572 *(spmin + 2) = tval;
4574 if (tval > *(spmax + 2)) {
4575 *(spmax + 2) = tval;
4579 lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
4580 (unsigned long long) smc->frhkb,
4581 out, outsize, svg_p->restart);
4583 lniappend(record_hdr->ust_time - svg_p->ust_time_ref,
4584 (unsigned long long) smc->tlhkb - smc->frhkb,
4585 out + 1, outsize + 1, svg_p->restart);
4587 brappend(record_hdr->ust_time - svg_p->ust_time_ref,
4589 out + 2, outsize + 2, svg_p->dt);
4592 if (action & F_END) {
4593 draw_activity_graphs(a->g_nr, g_type,
4594 title, g_title, NULL, group,
4595 spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
4597 /* Free remaining structures */
4598 free_graphs(out, outsize, spmin, spmax);
4603 ***************************************************************************
4604 * Display filesystem statistics in SVG.
4607 * @a Activity structure with statistics.
4608 * @curr Index in array for current sample statistics.
4609 * @action Action expected from current function.
4610 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
4611 * flag indicating that a restart record has been previously
4612 * found (.@restart) and time used for the X axis origin
4614 * @itv Interval of time in 1/100th of a second (unused here).
4615 * @record_hdr Pointer on record header of current stats sample.
4616 ***************************************************************************
4618 __print_funct_t svg_print_filesystem_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
4619 unsigned long long itv, struct record_header *record_hdr)
4621 struct stats_filesystem *sfc, *sfp;
4622 int group[] = {2, 2, 2, 1};
4623 int g_type[] = {SVG_LINE_GRAPH, SVG_BAR_GRAPH,
4624 SVG_LINE_GRAPH, SVG_BAR_GRAPH};
4625 char *title[] = {"Filesystems statistics (1)", "Filesystems statistics (2)",
4626 "Filesystems statistics (3)", "Filesystems statistics (4)"};
4627 char *g_title[] = {"~MBfsfree", "~MBfsused",
4628 "%ufsused", "%fsused",
4629 "Ifree/1000", "Iused/1000",
4631 static double *spmin, *spmax;
4633 static int *outsize;
4634 char *item_name = NULL;
4636 int i, k, pos, restart;
4638 if (action & F_BEGIN) {
4640 * Allocate arrays (#0..6) that will contain the graphs data
4641 * and the min/max values.
4642 * Also allocate two additional arrays (#7..8) for each filesystem:
4643 * out + 7 will contain the filesystem name,
4644 * out + 8 will contain the mount point.
4646 out = allocate_graph_lines(9 * svg_p->nr_max, &outsize, &spmin, &spmax);
4649 if (action & F_MAIN) {
4650 /* For each filesystem structure */
4651 for (i = 0; i < a->nr[curr]; i++) {
4652 sfc = (struct stats_filesystem *) ((char *) a->buf[curr] + i * a->msize);
4655 /* A list of devices has been entered on the command line */
4656 if (!search_sa_dlist(st_fs_list, dlst_fs_idx,
4657 DISPLAY_MOUNT(a->opt_flags) ? sfc->mountp : sfc->fs_name))
4658 /* Device not found */
4662 /* Look for corresponding graph */
4663 for (k = 0; k < svg_p->nr_max; k++) {
4664 item_name = *(out + k * 9 + 7);
4665 if (!strcmp(sfc->fs_name, item_name))
4670 if (k == svg_p->nr_max) {
4671 /* Graph not found: Look for first free entry */
4672 for (k = 0; k < svg_p->nr_max; k++) {
4673 item_name = *(out + k * 9 + 7);
4674 if (!strcmp(item_name, ""))
4677 if (k == svg_p->nr_max) {
4678 /* No free graph entry: Extend all buffers */
4679 reallocate_all_graph_lines(svg_p->nr_max,
4680 &out, &outsize, &spmin, &spmax);
4687 if (!item_name[0]) {
4688 /* Save filesystem name and mount point (if not already done) */
4689 strncpy(item_name, sfc->fs_name, CHUNKSIZE);
4690 item_name[CHUNKSIZE - 1] = '\0';
4691 item_name = *(out + pos + 8);
4692 strncpy(item_name, sfc->mountp, CHUNKSIZE);
4693 item_name[CHUNKSIZE - 1] = '\0';
4697 for (k = 0; k < a->nr[!curr]; k++) {
4698 sfp = (struct stats_filesystem *) ((char *) a->buf[!curr] + k * a->msize);
4699 if (!strcmp(sfc->fs_name, sfp->fs_name)) {
4700 /* Filesystem found in previous sample */
4701 restart = svg_p->restart;
4705 /* Check for min/max values */
4707 /* Compute fsfree min/max values */
4708 tval = (double) sfc->f_bfree;
4709 if (tval > *(spmax + pos)) {
4710 *(spmax + pos) = tval;
4712 if (tval < *(spmin + pos)) {
4713 *(spmin + pos) = tval;
4715 /* Compute fsused min/max values */
4716 tval = (double) (sfc->f_blocks - sfc->f_bfree);
4717 if (tval > *(spmax + pos + 1)) {
4718 *(spmax + pos + 1) = tval;
4720 if (tval < *(spmin + pos + 1)) {
4721 *(spmin + pos + 1) = tval;
4723 /* Compute %ufsused min/max values */
4724 tval = sfc->f_blocks ?
4725 SP_VALUE(sfc->f_bavail, sfc->f_blocks, sfc->f_blocks) : 0.0;
4726 if (tval > *(spmax + pos + 2)) {
4727 *(spmax + pos + 2) = tval;
4729 if (tval < *(spmin + pos + 2)) {
4730 *(spmin + pos + 2) = tval;
4732 /* Compute %fsused min/max values */
4733 tval = sfc->f_blocks ?
4734 SP_VALUE(sfc->f_bfree, sfc->f_blocks, sfc->f_blocks) : 0.0;
4735 if (tval > *(spmax + pos + 3)) {
4736 *(spmax + pos + 3) = tval;
4738 if (tval < *(spmin + pos + 3)) {
4739 *(spmin + pos + 3) = tval;
4741 /* Compute Ifree min/max values */
4742 tval = (double) sfc->f_ffree;
4743 if (tval > *(spmax + pos + 4)) {
4744 *(spmax + pos + 4) = tval;
4746 if (tval < *(spmin + pos + 4)) {
4747 *(spmin + pos + 4) = tval;
4749 /* Compute Iused min/max values */
4750 tval = (double) (sfc->f_files - sfc->f_ffree);
4751 if (tval > *(spmax + pos + 5)) {
4752 *(spmax + pos + 5) = tval;
4754 if (tval < *(spmin + pos + 5)) {
4755 *(spmin + pos + 5) = tval;
4757 /* Compute %Iused min/max values */
4758 tval = sfc->f_files ?
4759 SP_VALUE(sfc->f_ffree, sfc->f_files, sfc->f_files) : 0.0;
4760 if (tval > *(spmax + pos + 6)) {
4761 *(spmax + pos + 6) = tval;
4763 if (tval < *(spmin + pos + 6)) {
4764 *(spmin + pos + 6) = tval;
4768 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
4769 (double) sfc->f_bfree / 1024 / 1024,
4770 out + pos, outsize + pos, restart);
4772 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
4773 (double) (sfc->f_blocks - sfc->f_bfree) / 1024 / 1024,
4774 out + pos + 1, outsize + pos + 1, restart);
4776 brappend(record_hdr->ust_time - svg_p->ust_time_ref,
4779 SP_VALUE(sfc->f_bavail, sfc->f_blocks, sfc->f_blocks) : 0.0,
4780 out + pos + 2, outsize + pos + 2, svg_p->dt);
4782 brappend(record_hdr->ust_time - svg_p->ust_time_ref,
4785 SP_VALUE(sfc->f_bfree, sfc->f_blocks, sfc->f_blocks) : 0.0,
4786 out + pos + 3, outsize + pos + 3, svg_p->dt);
4788 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
4789 ((double) sfc->f_ffree) / 1000,
4790 out + pos + 4, outsize + pos + 4, restart);
4792 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
4793 ((double) (sfc->f_files - sfc->f_ffree)) / 1000,
4794 out + pos + 5, outsize + pos + 5, restart);
4796 brappend(record_hdr->ust_time - svg_p->ust_time_ref,
4799 SP_VALUE(sfc->f_ffree, sfc->f_files, sfc->f_files) : 0.0,
4800 out + pos + 6, outsize + pos + 6, svg_p->dt);
4804 if (action & F_END) {
4806 for (i = 0; i < svg_p->nr_max; i++) {
4808 /* Check if there is something to display */
4813 /* Conversion B -> MB and inodes/1000 */
4814 for (k = 0; k < 2; k++) {
4815 *(spmin + pos + k) /= (1024 * 1024);
4816 *(spmax + pos + k) /= (1024 * 1024);
4817 *(spmin + pos + 4 + k) /= 1000;
4818 *(spmax + pos + 4 + k) /= 1000;
4821 if (DISPLAY_MOUNT(a->opt_flags)) {
4822 item_name = *(out + pos + 8);
4825 item_name = *(out + pos + 7);
4828 draw_activity_graphs(a->g_nr, g_type, title, g_title, item_name, group,
4829 spmin + pos, spmax + pos, out + pos, outsize + pos,
4830 svg_p, record_hdr, FALSE, a->id, i);
4833 /* Free remaining structures */
4834 free_graphs(out, outsize, spmin, spmax);
4839 ***************************************************************************
4840 * Display Fibre Channel HBA statistics in SVG.
4843 * @a Activity structure with statistics.
4844 * @curr Index in array for current sample statistics.
4845 * @action Action expected from current function.
4846 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
4847 * flag indicating that a restart record has been previously
4848 * found (.@restart) and time used for the X axis origin
4850 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
4851 * @record_hdr Pointer on record header of current stats sample.
4852 ***************************************************************************
4854 __print_funct_t svg_print_fchost_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
4855 unsigned long long itv, struct record_header *record_hdr)
4857 struct stats_fchost *sfcc, *sfcp;
4858 int group[] = {2, 2};
4859 int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH};
4860 char *title[] = {"Fibre Channel HBA statistics (1)", "Fibre Channel HBA statistics (2)"};
4861 char *g_title[] = {"fch_rxf/s", "fch_txf/s",
4862 "fch_rxw/s", "fch_txw/s"};
4863 int g_fields[] = {0, 1, 2, 3};
4864 static double *spmin, *spmax;
4866 static int *outsize;
4868 int i, j, j0, k, found, pos, restart, *unregistered;
4870 if (action & F_BEGIN) {
4872 * Allocate arrays (#0..3) that will contain the graphs data
4873 * and the min/max values.
4874 * Also allocate one additional array (#4) that will contain
4875 * FC HBA name (out + 4) and a positive value (TRUE) if the interface
4876 * has either still not been registered, or has been unregistered
4879 out = allocate_graph_lines(5 * svg_p->nr_max, &outsize, &spmin, &spmax);
4882 if (action & F_MAIN) {
4883 restart = svg_p->restart;
4885 * Mark previously registered interfaces as now
4886 * possibly unregistered for all graphs.
4888 for (k = 0; k < svg_p->nr_max; k++) {
4889 unregistered = outsize + k * 5 + 4;
4890 if (*unregistered == FALSE) {
4891 *unregistered = MAYBE;
4895 /* For each FC HBA */
4896 for (i = 0; i < a->nr[curr]; i++) {
4900 if (a->nr[!curr] > 0) {
4901 sfcc = (struct stats_fchost *) ((char *) a->buf[curr] + i * a->msize);
4903 /* Look for corresponding graph */
4904 for (k = 0; k < svg_p->nr_max; k++) {
4905 item_name = *(out + k * 5 + 4);
4906 if (!strcmp(sfcc->fchost_name, item_name))
4910 if (k == svg_p->nr_max) {
4911 /* Graph not found: Look for first free entry */
4912 for (k = 0; k < svg_p->nr_max; k++) {
4913 item_name = *(out + k * 5 + 4);
4914 if (!strcmp(item_name, ""))
4917 if (k == svg_p->nr_max) {
4918 /* No free graph entry: Extend all buffers */
4919 reallocate_all_graph_lines(svg_p->nr_max,
4920 &out, &outsize, &spmin, &spmax);
4926 unregistered = outsize + pos + 4;
4928 /* Look for corresponding structure in previous iteration */
4931 if (j >= a->nr[!curr]) {
4932 j = a->nr[!curr] - 1;
4938 sfcp = (struct stats_fchost *) ((char *) a->buf[!curr] + j * a->msize);
4939 if (!strcmp(sfcc->fchost_name, sfcp->fchost_name)) {
4943 if (++j >= a->nr[!curr]) {
4954 * If current interface was marked as previously unregistered,
4955 * then set restart variable to TRUE so that the graph will be
4956 * discontinuous, and mark it as now registered.
4958 if (*unregistered == TRUE) {
4961 *unregistered = FALSE;
4963 item_name = *(out + pos + 4);
4964 if (!item_name[0]) {
4965 /* Save FC HBA name */
4966 strncpy(item_name, sfcc->fchost_name, CHUNKSIZE);
4967 item_name[CHUNKSIZE - 1] = '\0';
4970 /* Look for min/max values */
4971 save_extrema(a->gtypes_nr, (void *) sfcc, (void *) sfcp,
4972 itv, spmin + pos, spmax + pos, g_fields);
4975 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
4976 S_VALUE(sfcp->f_rxframes, sfcc->f_rxframes, itv),
4977 out + pos, outsize + pos, restart);
4979 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
4980 S_VALUE(sfcp->f_txframes, sfcc->f_txframes, itv),
4981 out + pos + 1, outsize + pos + 1, restart);
4983 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
4984 S_VALUE(sfcp->f_rxwords, sfcc->f_rxwords, itv),
4985 out + pos + 2, outsize + pos + 2, restart);
4987 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
4988 S_VALUE(sfcp->f_txwords, sfcc->f_txwords, itv),
4989 out + pos + 3, outsize + pos + 3, restart);
4992 /* Mark interfaces not seen here as now unregistered */
4993 for (k = 0; k < svg_p->nr_max; k++) {
4994 unregistered = outsize + k * 5 + 4;
4995 if (*unregistered != FALSE) {
4996 *unregistered = TRUE;
5001 if (action & F_END) {
5002 for (i = 0; i < svg_p->nr_max; i++) {
5004 /* Check if there is something to display */
5009 item_name = *(out + pos + 4);
5010 draw_activity_graphs(a->g_nr, g_type,
5011 title, g_title, item_name, group,
5012 spmin + pos, spmax + pos, out + pos, outsize + pos,
5013 svg_p, record_hdr, FALSE, a->id, i);
5016 /* Free remaining structures */
5017 free_graphs(out, outsize, spmin, spmax);
5022 ***************************************************************************
5023 * Display softnet statistics in SVG.
5026 * @a Activity structure with statistics.
5027 * @curr Index in array for current sample statistics.
5028 * @action Action expected from current function.
5029 * @svg_p SVG specific parameters: Current graph number (.@graph_no),
5030 * flag indicating that a restart record has been previously
5031 * found (.@restart) and time used for the X axis origin
5033 * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
5034 * @record_hdr Pointer on record header of current stats sample.
5035 ***************************************************************************
5037 __print_funct_t svg_print_softnet_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
5038 unsigned long long itv, struct record_header *record_hdr)
5040 struct stats_softnet *ssnc, *ssnp, ssnczero;
5041 int group[] = {2, 3};
5042 int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH};
5043 char *title[] = {"Software-based network processing statistics (1)",
5044 "Software-based network processing statistics (2)"};
5045 char *g_title[] = {"total/s", "dropd/s",
5046 "squeezd/s", "rx_rps/s", "flw_lim/s"};
5047 int g_fields[] = {0, 1, 2, 3, 4};
5048 static double *spmin, *spmax;
5050 static int *outsize;
5052 unsigned char offline_cpu_bitmap[BITMAP_SIZE(NR_CPUS)] = {0};
5053 int i, pos, restart;
5055 if (action & F_BEGIN) {
5057 * Allocate arrays that will contain the graphs data
5058 * and the min/max values.
5060 out = allocate_graph_lines(5 * svg_p->nr_max, &outsize, &spmin, &spmax);
5063 if (action & F_MAIN) {
5064 memset(&ssnczero, 0, STATS_SOFTNET_SIZE);
5066 /* @nr[curr] cannot normally be greater than @nr_ini */
5067 if (a->nr[curr] > a->nr_ini) {
5068 a->nr_ini = a->nr[curr];
5071 /* Compute statistics for CPU "all" */
5072 get_global_soft_statistics(a, !curr, curr, flags, offline_cpu_bitmap);
5075 for (i = 0; (i < a->nr_ini) && (i < a->bitmap->b_size + 1); i++) {
5076 restart = svg_p->restart;
5078 /* Should current CPU (including CPU "all") be displayed? */
5079 if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))))
5083 ssnc = (struct stats_softnet *) ((char *) a->buf[curr] + i * a->msize);
5084 ssnp = (struct stats_softnet *) ((char *) a->buf[!curr] + i * a->msize);
5086 /* Is current CPU marked offline? */
5087 if (offline_cpu_bitmap[i >> 3] & (1 << (i & 0x07))) {
5089 * Yes and it doesn't follow a RESTART record.
5090 * To add a discontinuity in graph, we simulate
5094 if (svg_p->restart) {
5096 * CPU is offline and it follows a real
5097 * RESTART record. Ignore its current value
5098 * (no previous sample).
5105 /* Check for min/max values */
5106 save_extrema(a->gtypes_nr, (void *) ssnc, (void *) ssnp,
5107 itv, spmin + pos, spmax + pos, g_fields);
5110 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
5111 S_VALUE(ssnp->processed, ssnc->processed, itv),
5112 out + pos, outsize + pos, restart);
5114 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
5115 S_VALUE(ssnp->dropped, ssnc->dropped, itv),
5116 out + pos + 1, outsize + pos + 1, restart);
5118 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
5119 S_VALUE(ssnp->time_squeeze, ssnc->time_squeeze, itv),
5120 out + pos + 2, outsize + pos + 2, restart);
5122 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
5123 S_VALUE(ssnp->received_rps, ssnc->received_rps, itv),
5124 out + pos + 3, outsize + pos + 3, restart);
5126 lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
5127 S_VALUE(ssnp->flow_limit, ssnc->flow_limit, itv),
5128 out + pos + 4, outsize + pos + 4, restart);
5132 if (action & F_END) {
5133 for (i = 0; (i < svg_p->nr_max) && (i < a->bitmap->b_size + 1); i++) {
5135 /* Should current CPU (including CPU "all") be displayed? */
5136 if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))))
5143 /* This is CPU "all" */
5144 strcpy(item_name, "all");
5147 sprintf(item_name, "%d", i - 1);
5150 draw_activity_graphs(a->g_nr, g_type,
5151 title, g_title, item_name, group,
5152 spmin + pos, spmax + pos, out + pos, outsize + pos,
5153 svg_p, record_hdr, FALSE, a->id, i);
5156 /* Free remaining structures */
5157 free_graphs(out, outsize, spmin, spmax);