/*
- * svg_stats.c: Funtions used by sadf to display statistics in SVG format.
- * (C) 2016-2018 by Sebastien GODARD (sysstat <at> orange.fr)
+ * svg_stats.c: Functions used by sadf to display statistics in SVG format.
+ * (C) 2016-2021 by Sebastien GODARD (sysstat <at> orange.fr)
*
***************************************************************************
* This program is free software; you can redistribute it and/or modify it *
#define _(string) (string)
#endif
-extern unsigned int flags;
+extern uint64_t flags;
extern int palette;
unsigned int svg_colors[SVG_COL_PALETTE_NR][SVG_COL_PALETTE_SIZE] =
0x000000, 0xffffff, 0x202020, 0xffff00,
0xffff00, 0x808080, 0xa52a2a, 0xff0000},
- {0x915c83, 0x0000ff, 0x8a2be2, 0xde5d83, /* Custom color palette */
- 0xff55a3, 0x993300, 0x800020, 0x008080,
- 0xdc143c, 0x006400, 0x483d8b, 0x2f4f4f,
- 0xcc3300, 0x50040f, 0xffffbf, 0x193d55,
- 0xf5f5dc, 0x000000, 0x536872, 0xff6347,
- 0xff6347, 0x808080, 0xa52a2a, 0xff0000},
+ {0x000000, 0x1a1aff, 0x1affb2, 0xb21aff, /* Custom color palette */
+ 0x1ab2ff, 0xff1a1a, 0xffb31a, 0xb2ff1a,
+ 0xefefef, 0x000000, 0x1a1aff, 0x1affb2,
+ 0xb21aff, 0x1ab2ff, 0xff1a1a, 0xffb31a,
+ 0xffffff, 0x000000, 0xbebebe, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000},
{0x696969, 0xbebebe, 0x000000, 0xa9a9a9, /* Black & white palette */
0x708090, 0xc0c0c0, 0x808080, 0xd3d3d3,
* the fields in the statistics structure.
*
* OUT:
- * @spmin Array containg the possible new min values for current activity.
- * @spmax Array containg the possible new max values for current activity.
+ * @spmin Array containing the possible new min values for current activity.
+ * @spmax Array containing the possible new max values for current activity.
***************************************************************************
*/
void save_extrema(unsigned int types_nr[], void *cs, void *ps, unsigned long long itv,
int j = 0;
char stmp[32];
+ /* Print marker in debug mode */
+ if (DISPLAY_DEBUG_MODE(flags)) {
+ printf("<!-- Hgrid -->\n");
+ }
+
do {
/* Display horizontal lines (except on X axis) */
if (j > 0) {
stamp.ust_time = svg_p->ust_time_ref; /* Only ust_time field needs to be set. TRUE_TIME not allowed */
+ /* Print marker in debug mode */
+ if (DISPLAY_DEBUG_MODE(flags)) {
+ printf("<!-- Vgrid -->\n");
+ }
+
/*
* What really matters to know when we should stop drawing vertical lines
* is the time end. v_gridnr is only informative and used to calculate
for (j = 0; (j <= (2 * v_gridnr)) && (stamp.ust_time <= svg_p->ust_time_end); j++) {
/* Display vertical lines */
- sa_get_record_timestamp_struct(flags, &stamp, &rectime, NULL);
+ if (sa_get_record_timestamp_struct(flags, &stamp, &rectime)) {
+#ifdef DEBUG
+ fprintf(stderr, "%s: ust_time: %llu\n", __FUNCTION__, stamp.ust_time);
+#endif
+ exit(1);
+ }
set_record_timestamp_string(flags, &stamp, NULL, cur_time, TIMESTAMP_LEN, &rectime);
printf("<polyline points=\"%ld,0 %ld,%d\" style=\"vector-effect: non-scaling-stroke; "
"stroke: #%06x\" transform=\"scale(%f,1)\"/>\n",
* @skip_void Set to <> 0 if graphs with no data should be skipped.
* This is typicallly used to not display CPU offline on the
* whole period.
- * @id Current activity id.
+ * @a Current activity structure.
* @xid Current activity extra id number.
*
* RETURNS:
int draw_activity_graphs(int g_nr, int g_type[], char *title[], char *g_title[], char *item_name,
int group[], double *spmin, double *spmax, char **out, int *outsize,
struct svg_parm *svg_p, struct record_header *record_hdr, int skip_void,
- unsigned int id, unsigned int xid)
+ struct activity *a, unsigned int xid)
{
char *out_p;
int i, j, dp, pos = 0, views_nr = 0, displayed = FALSE, palpos;
char val[32], cur_date[TIMESTAMP_LEN];
struct tm rectime;
+ /* Print activity name in debug mode */
+ if (DISPLAY_DEBUG_MODE(flags)) {
+ printf("<!-- Name: %s -->\n", a->name);
+ }
+
/* For each view which is part of current activity */
for (i = 0; i < g_nr; i++) {
+ /* Print view number in debug mode */
+ if (DISPLAY_DEBUG_MODE(flags)) {
+ printf("<!-- View %d -->\n", i + 1);
+ }
+
/* Used as index in color palette */
palpos = (palette == SVG_BW_COL_PALETTE ? 0 : pos);
if (!displayed) {
/* Translate to proper position for current activity */
printf("<g id=\"g%d-%d\" transform=\"translate(0,%d)\">\n",
- id, xid,
+ a->id, xid,
SVG_H_YSIZE +
SVG_C_YSIZE * (DISPLAY_TOC(flags) ? svg_p->nr_act_dispd : 0) +
SVG_T_YSIZE * svg_p->graph_no);
/* Display vertical lines and graduations */
display_vgrid(xpos, xfactor, v_gridnr, svg_p);
+ /* Print marker in debug mode */
+ if (DISPLAY_DEBUG_MODE(flags)) {
+ printf("<!-- Graphs -->\n");
+ }
+
/* Draw current graphs set */
for (j = 0; j < group[i]; j++) {
out_p = *(out + pos + j);
* @record_hdr Pointer on record header of current stats sample.
***************************************************************************
*/
+#define CPU_ARRAY_SZ 10
__print_funct_t svg_print_cpu_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
unsigned long long itv, struct record_header *record_hdr)
{
* Allocate arrays that will contain the graphs data
* and the min/max values.
*/
- out = allocate_graph_lines(10 * a->item_list_sz, &outsize, &spmin, &spmax);
+ out = allocate_graph_lines(CPU_ARRAY_SZ * a->item_list_sz, &outsize, &spmin, &spmax);
}
if (action & F_MAIN) {
scc = (struct stats_cpu *) ((char *) a->buf[curr] + i * a->msize);
scp = (struct stats_cpu *) ((char *) a->buf[!curr] + i * a->msize);
- pos = i * 10;
+ pos = i * CPU_ARRAY_SZ;
offset = 0.0;
if (i == 0) {
/* No */
continue;
- pos = i * 10;
+ pos = i * CPU_ARRAY_SZ;
if (!i) {
/* This is CPU "all" */
strcpy(item_name, "all");
displayed = draw_activity_graphs(a->g_nr, g_type,
title, g_title1, item_name, group1,
spmin + pos, spmax + pos, out + pos, outsize + pos,
- svg_p, record_hdr, i, a->id, xid);
+ svg_p, record_hdr, i, a, xid);
}
else {
displayed = draw_activity_graphs(a->g_nr, g_type,
title, g_title2, item_name, group2,
spmin + pos, spmax + pos, out + pos, outsize + pos,
- svg_p, record_hdr, i, a->id, xid);
+ svg_p, record_hdr, i, a, xid);
}
if (displayed) {
xid++;
if (action & F_END) {
draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
- spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
+ spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
/* Free remaining structures */
free_graphs(out, outsize, spmin, spmax);
if (action & F_END) {
draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
- spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
+ spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
/* Free remaining structures */
free_graphs(out, outsize, spmin, spmax);
if (action & F_END) {
draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
- spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
+ spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
/* Free remaining structures */
free_graphs(out, outsize, spmin, spmax);
if (action & F_END) {
draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
- spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
+ spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
/* Free remaining structures */
free_graphs(out, outsize, spmin, spmax);
if (draw_activity_graphs(DISPLAY_MEM_ALL(a->opt_flags) ? 6 : 5,
g_type1, title1, g_title1, NULL, group1,
spmin, spmax, out, outsize, svg_p, record_hdr,
- FALSE, a->id, xid)) {
+ FALSE, a, xid)) {
xid++;
}
}
if (DISPLAY_SWAP(a->opt_flags)) {
draw_activity_graphs(3, g_type2, title2, g_title2, NULL, group2,
spmin + 16, spmax + 16, out + 16, outsize + 16,
- svg_p, record_hdr, FALSE, a->id, xid);
+ svg_p, record_hdr, FALSE, a, xid);
}
/* Free remaining structures */
if (action & F_END) {
draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
- spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
+ spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
/* Free remaining structures */
free_graphs(out, outsize, spmin, spmax);
*(spmin + 5) /= 100; *(spmax + 5) /= 100;
draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
- spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
+ spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
/* Free remaining structures */
free_graphs(out, outsize, spmin, spmax);
* @record_hdr Pointer on record header of current stats sample.
***************************************************************************
*/
+#define DISK_ARRAY_SZ 9
__print_funct_t svg_print_disk_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
unsigned long long itv, struct record_header *record_hdr)
{
"await",
"%util"};
int g_fields[] = {0, 1, 2};
- int nr_arrays = 9;
unsigned int local_types_nr[] = {1, 0, 0};
static double *spmin, *spmax;
static char **out;
static int *outsize;
- char *item_name;
+ char *dev_name, *item_name;
double rkB, wkB, dkB, aqusz;
int i, j, k, pos, restart, *unregistered;
* Allocate arrays (#0..7) that will contain the graphs data
* and the min/max values.
* Also allocate one additional array (#8) for each disk device:
- * spmax + 8 will contain the device major number,
- * spmin + 8 will contain the device minor number,
+ * out + 8 will contain the device name (WWN id, pretty name or devm-n),
* outsize + 8 will contain a positive value (TRUE) if the device
* has either still not been registered, or has been unregistered.
*/
- out = allocate_graph_lines(nr_arrays * a->item_list_sz, &outsize, &spmin, &spmax);
+ out = allocate_graph_lines(DISK_ARRAY_SZ * a->item_list_sz, &outsize, &spmin, &spmax);
}
if (action & F_MAIN) {
memset(&sdpzero, 0, STATS_DISK_SIZE);
- restart = svg_p->restart;
/*
* Mark previously registered devices as now
* possibly unregistered for all graphs.
*/
for (k = 0; k < a->item_list_sz; k++) {
- unregistered = outsize + k * nr_arrays + 8;
+ unregistered = outsize + k * DISK_ARRAY_SZ + 8;
if (*unregistered == FALSE) {
*unregistered = MAYBE;
}
/* For each device structure */
for (i = 0; i < a->nr[curr]; i++) {
sdc = (struct stats_disk *) ((char *) a->buf[curr] + i * a->msize);
+ restart = svg_p->restart;
- /* Get device name */
- item_name = get_sa_devname(sdc->major, sdc->minor, flags);
+ /* Get device name */
+ dev_name = get_device_name(sdc->major, sdc->minor, sdc->wwn, sdc->part_nr,
+ DISPLAY_PRETTY(flags), DISPLAY_PERSIST_NAME_S(flags),
+ USE_STABLE_ID(flags), NULL);
if (a->item_list != NULL) {
/* A list of devices has been entered on the command line */
- if (!search_list_item(a->item_list, item_name))
+ if (!search_list_item(a->item_list, dev_name))
/* Device not found */
continue;
}
/* Look for corresponding graph */
for (k = 0; k < a->item_list_sz; k++) {
- if ((sdc->major == *(spmax + k * nr_arrays + 8)) &&
- (sdc->minor == *(spmin + k * nr_arrays + 8)))
+ item_name = *(out + k * DISK_ARRAY_SZ + 8);
+ if (!strcmp(dev_name, item_name))
/* Graph found! */
break;
}
if (k == a->item_list_sz) {
/* Graph not found: Look for first free entry */
for (k = 0; k < a->item_list_sz; k++) {
- if (*(spmax + k * nr_arrays + 8) == -DBL_MAX)
+ item_name = *(out + k * DISK_ARRAY_SZ + 8);
+ if (!strcmp(item_name, ""))
break;
}
if (k == a->item_list_sz) {
/* No free graph entry: Ignore it (should never happen) */
#ifdef DEBUG
fprintf(stderr, "%s: Name=%s major=%d minor=%d\n",
- __FUNCTION__, item_name, sdc->major, sdc->minor);
+ __FUNCTION__, dev_name, sdc->major, sdc->minor);
#endif
continue;
}
}
- pos = k * nr_arrays;
+ pos = k * DISK_ARRAY_SZ;
unregistered = outsize + pos + 8;
/*
}
*unregistered = FALSE;
- if (*(spmax + pos + 8) == -DBL_MAX) {
- /* Save device major and minor numbers (if not already done) */
- *(spmax + pos + 8) = sdc->major;
- *(spmin + pos + 8) = sdc->minor;
+ item_name = *(out + pos + 8);
+ if (!item_name[0]) {
+ /* Save device name (WWN id or pretty name) if not already done */
+ strncpy(item_name, dev_name, CHUNKSIZE);
+ item_name[CHUNKSIZE - 1] = '\0';
}
j = check_disk_reg(a, curr, !curr, i);
if (j < 0) {
/* This is a newly registered interface. Previous stats are zero */
sdp = &sdpzero;
+ restart = TRUE;
}
else {
sdp = (struct stats_disk *) ((char *) a->buf[!curr] + j * a->msize);
/* Mark devices not seen here as now unregistered */
for (k = 0; k < a->item_list_sz; k++) {
- unregistered = outsize + k * nr_arrays + 8;
+ unregistered = outsize + k * DISK_ARRAY_SZ + 8;
if (*unregistered != FALSE) {
*unregistered = TRUE;
}
for (i = 0; i < a->item_list_sz; i++) {
/* Check if there is something to display */
- pos = i * nr_arrays;
+ pos = i * DISK_ARRAY_SZ;
if (!**(out + pos))
continue;
- /* Get device name */
- item_name = get_sa_devname(*(spmax + pos + 8), *(spmin + pos + 8), flags);
-
+ item_name = *(out + pos + 8);
if (draw_activity_graphs(a->g_nr, g_type,
title, g_title, item_name, group,
spmin + pos, spmax + pos, out + pos, outsize + pos,
- svg_p, record_hdr, FALSE, a->id, xid)) {
+ svg_p, record_hdr, FALSE, a, xid)) {
xid++;
}
}
* @record_hdr Pointer on record header of current stats sample.
***************************************************************************
*/
+#define NET_DEV_ARRAY_SZ 9
__print_funct_t svg_print_net_dev_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
unsigned long long itv, struct record_header *record_hdr)
{
* outsize + 8 will contain a positive value (TRUE) if the interface
* has either still not been registered, or has been unregistered.
*/
- out = allocate_graph_lines(9 * a->item_list_sz, &outsize, &spmin, &spmax);
+ out = allocate_graph_lines(NET_DEV_ARRAY_SZ * a->item_list_sz, &outsize, &spmin, &spmax);
}
if (action & F_MAIN) {
memset(&sndzero, 0, STATS_NET_DEV_SIZE);
- restart = svg_p->restart;
/*
* Mark previously registered interfaces as now
* possibly unregistered for all graphs.
*/
for (k = 0; k < a->item_list_sz; k++) {
- unregistered = outsize + k * 9 + 8;
+ unregistered = outsize + k * NET_DEV_ARRAY_SZ + 8;
if (*unregistered == FALSE) {
*unregistered = MAYBE;
}
/* For each network interfaces structure */
for (i = 0; i < a->nr[curr]; i++) {
sndc = (struct stats_net_dev *) ((char *) a->buf[curr] + i * a->msize);
+ restart = svg_p->restart;
if (a->item_list != NULL) {
/* A list of devices has been entered on the command line */
/* Look for corresponding graph */
for (k = 0; k < a->item_list_sz; k++) {
- item_name = *(out + k * 9 + 8);
+ item_name = *(out + k * NET_DEV_ARRAY_SZ + 8);
if (!strcmp(sndc->interface, item_name))
/* Graph found! */
break;
if (k == a->item_list_sz) {
/* Graph not found: Look for first free entry */
for (k = 0; k < a->item_list_sz; k++) {
- item_name = *(out + k * 9 + 8);
+ item_name = *(out + k * NET_DEV_ARRAY_SZ + 8);
if (!strcmp(item_name, ""))
break;
}
continue;
}
}
- pos = k * 9;
+ pos = k * NET_DEV_ARRAY_SZ;
unregistered = outsize + pos + 8;
j = check_net_dev_reg(a, curr, !curr, i);
if (j < 0) {
/* This is a newly registered interface. Previous stats are zero */
sndp = &sndzero;
+ restart = TRUE;
}
else {
sndp = (struct stats_net_dev *) ((char *) a->buf[!curr] + j * a->msize);
/* Mark interfaces not seen here as now unregistered */
for (k = 0; k < a->item_list_sz; k++) {
- unregistered = outsize + k * 9 + 8;
+ unregistered = outsize + k * NET_DEV_ARRAY_SZ + 8;
if (*unregistered != FALSE) {
*unregistered = TRUE;
}
* Don't test sndc->interface because maybe the network
* interface has been registered later.
*/
- pos = i * 9;
+ pos = i * NET_DEV_ARRAY_SZ;
if (!**(out + pos))
continue;
if (draw_activity_graphs(a->g_nr, g_type,
title, g_title, item_name, group,
spmin + pos, spmax + pos, out + pos, outsize + pos,
- svg_p, record_hdr, FALSE, a->id, xid)) {
+ svg_p, record_hdr, FALSE, a, xid)) {
xid++;
}
}
* @record_hdr Pointer on record header of current stats sample.
***************************************************************************
*/
+#define NET_EDEV_ARRAY_SZ 10
__print_funct_t svg_print_net_edev_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
unsigned long long itv, struct record_header *record_hdr)
{
* outsize + 9 will contain a positive value (TRUE) if the interface
* has either still not been registered, or has been unregistered.
*/
- out = allocate_graph_lines(10 * a->item_list_sz, &outsize, &spmin, &spmax);
+ out = allocate_graph_lines(NET_EDEV_ARRAY_SZ * a->item_list_sz, &outsize, &spmin, &spmax);
}
if (action & F_MAIN) {
memset(&snedzero, 0, STATS_NET_EDEV_SIZE);
- restart = svg_p->restart;
/*
* Mark previously registered interfaces as now
* possibly unregistered for all graphs.
*/
for (k = 0; k < a->item_list_sz; k++) {
- unregistered = outsize + k * 10 + 9;
+ unregistered = outsize + k * NET_EDEV_ARRAY_SZ + 9;
if (*unregistered == FALSE) {
*unregistered = MAYBE;
}
/* For each network interfaces structure */
for (i = 0; i < a->nr[curr]; i++) {
snedc = (struct stats_net_edev *) ((char *) a->buf[curr] + i * a->msize);
- if (!strcmp(snedc->interface, ""))
- /* Empty structure: This is the end of the list */
- break;
+ restart = svg_p->restart;
if (a->item_list != NULL) {
/* A list of devices has been entered on the command line */
/* Look for corresponding graph */
for (k = 0; k < a->item_list_sz; k++) {
- item_name = *(out + k * 10 + 9);
+ item_name = *(out + k * NET_EDEV_ARRAY_SZ + 9);
if (!strcmp(snedc->interface, item_name))
/* Graph found! */
break;
if (k == a->item_list_sz) {
/* Graph not found: Look for first free entry */
for (k = 0; k < a->item_list_sz; k++) {
- item_name = *(out + k * 10 + 9);
+ item_name = *(out + k * NET_EDEV_ARRAY_SZ + 9);
if (!strcmp(item_name, ""))
break;
}
}
}
- pos = k * 10;
+ pos = k * NET_EDEV_ARRAY_SZ;
unregistered = outsize + pos + 9;
j = check_net_edev_reg(a, curr, !curr, i);
if (j < 0) {
/* This is a newly registered interface. Previous stats are zero */
snedp = &snedzero;
+ restart = TRUE;
}
else {
snedp = (struct stats_net_edev *) ((char *) a->buf[!curr] + j * a->msize);
/* Mark interfaces not seen here as now unregistered */
for (k = 0; k < a->item_list_sz; k++) {
- unregistered = outsize + k * 10 + 9;
+ unregistered = outsize + k * NET_EDEV_ARRAY_SZ + 9;
if (*unregistered != FALSE) {
*unregistered = TRUE;
}
* Don't test snedc->interface because maybe the network
* interface has been registered later.
*/
- pos = i * 10;
+ pos = i * NET_EDEV_ARRAY_SZ;
if (!**(out + pos))
continue;
if (draw_activity_graphs(a->g_nr, g_type,
title, g_title, item_name, group,
spmin + pos, spmax + pos, out + pos, outsize + pos,
- svg_p, record_hdr, FALSE, a->id, xid)) {
+ svg_p, record_hdr, FALSE, a, xid)) {
xid++;
}
}
if (action & F_END) {
draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
- spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
+ spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
/* Free remaining structures */
free_graphs(out, outsize, spmin, spmax);
if (action & F_END) {
draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
- spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
+ spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
/* Free remaining structures */
free_graphs(out, outsize, spmin, spmax);
if (action & F_END) {
draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
- spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
+ spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
/* Free remaining structures */
free_graphs(out, outsize, spmin, spmax);
if (action & F_END) {
draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
- spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
+ spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
/* Free remaining structures */
free_graphs(out, outsize, spmin, spmax);
if (action & F_END) {
draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
- spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
+ spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
/* Free remaining structures */
free_graphs(out, outsize, spmin, spmax);
if (action & F_END) {
draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
- spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
+ spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
/* Free remaining structures */
free_graphs(out, outsize, spmin, spmax);
if (action & F_END) {
draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
- spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
+ spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
/* Free remaining structures */
free_graphs(out, outsize, spmin, spmax);
if (action & F_END) {
draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
- spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
+ spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
/* Free remaining structures */
free_graphs(out, outsize, spmin, spmax);
if (action & F_END) {
draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
- spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
+ spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
/* Free remaining structures */
free_graphs(out, outsize, spmin, spmax);
if (action & F_END) {
draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
- spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
+ spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
/* Free remaining structures */
free_graphs(out, outsize, spmin, spmax);
if (action & F_END) {
draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
- spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
+ spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
/* Free remaining structures */
free_graphs(out, outsize, spmin, spmax);
if (action & F_END) {
draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
- spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
+ spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
/* Free remaining structures */
free_graphs(out, outsize, spmin, spmax);
if (action & F_END) {
draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
- spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
+ spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
/* Free remaining structures */
free_graphs(out, outsize, spmin, spmax);
if (action & F_END) {
draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
- spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
+ spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
/* Free remaining structures */
free_graphs(out, outsize, spmin, spmax);
if (action & F_END) {
draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
- spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
+ spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
/* Free remaining structures */
free_graphs(out, outsize, spmin, spmax);
if (action & F_END) {
draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
- spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
+ spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
/* Free remaining structures */
free_graphs(out, outsize, spmin, spmax);
static double *spmin, *spmax;
static char **out;
static int *outsize;
- char item_name[8];
+ char item_name[16];
int i;
if (action & F_BEGIN) {
if (draw_activity_graphs(a->g_nr, g_type,
title, g_title, item_name, group,
spmin + i, spmax + i, out + i, outsize + i,
- svg_p, record_hdr, i, a->id, xid)) {
+ svg_p, record_hdr, i, a, xid)) {
xid++;
}
}
static double *spmin, *spmax;
static char **out;
static int *outsize;
- char item_name[MAX_SENSORS_DEV_LEN + 8];
+ char item_name[MAX_SENSORS_DEV_LEN + 16];
int i;
if (action & F_BEGIN) {
spc = (struct stats_pwr_fan *) ((char *) a->buf[curr] + i * a->msize);
- snprintf(item_name, MAX_SENSORS_DEV_LEN + 8, "%d: %s", i + 1, spc->device);
- item_name[MAX_SENSORS_DEV_LEN + 7] = '\0';
+ snprintf(item_name, sizeof(item_name), "%d: %s", i + 1, spc->device);
+ item_name[sizeof(item_name) - 1] = '\0';
if (draw_activity_graphs(a->g_nr, g_type,
title, g_title, item_name, group,
spmin + i, spmax + i, out + i, outsize + i,
- svg_p, record_hdr, FALSE, a->id, xid)) {
+ svg_p, record_hdr, FALSE, a, xid)) {
xid++;
}
}
* @record_hdr Pointer on record header of current stats sample.
***************************************************************************
*/
+#define TEMP_ARRAY_SZ 2
__print_funct_t svg_print_pwr_temp_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
unsigned long long itv, struct record_header *record_hdr)
{
static double *spmin, *spmax;
static char **out;
static int *outsize;
- char item_name[MAX_SENSORS_DEV_LEN + 8];
+ char item_name[MAX_SENSORS_DEV_LEN + 16];
int i;
double tval;
* Allocate arrays that will contain the graphs data
* and the min/max values.
*/
- out = allocate_graph_lines(2 * a->item_list_sz, &outsize, &spmin, &spmax);
+ out = allocate_graph_lines(TEMP_ARRAY_SZ * a->item_list_sz, &outsize, &spmin, &spmax);
}
if (action & F_MAIN) {
spc = (struct stats_pwr_temp *) ((char *) a->buf[curr] + i * a->msize);
/* Look for min/max values */
- if (spc->temp < *(spmin + 2 * i)) {
- *(spmin + 2 * i) = spc->temp;
+ if (spc->temp < *(spmin + TEMP_ARRAY_SZ * i)) {
+ *(spmin + TEMP_ARRAY_SZ * i) = spc->temp;
}
- if (spc->temp > *(spmax + 2 * i)) {
- *(spmax + 2 * i) = spc->temp;
+ if (spc->temp > *(spmax + TEMP_ARRAY_SZ * i)) {
+ *(spmax + TEMP_ARRAY_SZ * i) = spc->temp;
}
tval = (spc->temp_max - spc->temp_min) ?
(spc->temp - spc->temp_min) / (spc->temp_max - spc->temp_min) * 100 :
0.0;
- if (tval < *(spmin + 2 * i + 1)) {
- *(spmin + 2 * i + 1) = tval;
+ if (tval < *(spmin + TEMP_ARRAY_SZ * i + 1)) {
+ *(spmin + TEMP_ARRAY_SZ * i + 1) = tval;
}
- if (tval > *(spmax + 2 * i + 1)) {
- *(spmax + 2 * i + 1) = tval;
+ if (tval > *(spmax + TEMP_ARRAY_SZ * i + 1)) {
+ *(spmax + TEMP_ARRAY_SZ * i + 1) = tval;
}
/* degC */
lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
(double) spc->temp,
- out + 2 * i, outsize + 2 * i, svg_p->restart);
+ out + TEMP_ARRAY_SZ * i, outsize + TEMP_ARRAY_SZ * i, svg_p->restart);
/* %temp */
brappend(record_hdr->ust_time - svg_p->ust_time_ref,
0.0, tval,
- out + 2 * i + 1, outsize + 2 * i + 1, svg_p->dt);
+ out + TEMP_ARRAY_SZ * i + 1, outsize + TEMP_ARRAY_SZ * i + 1, svg_p->dt);
}
}
spc = (struct stats_pwr_temp *) ((char *) a->buf[curr] + i * a->msize);
- snprintf(item_name, MAX_SENSORS_DEV_LEN + 8, "%d: %s", i + 1, spc->device);
- item_name[MAX_SENSORS_DEV_LEN + 7] = '\0';
+ snprintf(item_name, sizeof(item_name), "%d: %s", i + 1, spc->device);
+ item_name[sizeof(item_name) - 1] = '\0';
if (draw_activity_graphs(a->g_nr, g_type,
title, g_title, item_name, group,
- spmin + 2 * i, spmax + 2 * i, out + 2 * i, outsize + 2 * i,
- svg_p, record_hdr, FALSE, a->id, xid)) {
+ spmin + TEMP_ARRAY_SZ * i, spmax + TEMP_ARRAY_SZ * i,
+ out + TEMP_ARRAY_SZ * i, outsize + TEMP_ARRAY_SZ * i,
+ svg_p, record_hdr, FALSE, a, xid)) {
xid++;
}
}
* @record_hdr Pointer on record header of current stats sample.
***************************************************************************
*/
+#define IN_ARRAY_SZ 2
__print_funct_t svg_print_pwr_in_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
unsigned long long itv, struct record_header *record_hdr)
{
static double *spmin, *spmax;
static char **out;
static int *outsize;
- char item_name[MAX_SENSORS_DEV_LEN + 8];
+ char item_name[MAX_SENSORS_DEV_LEN + 16];
int i;
double tval;
* Allocate arrays that will contain the graphs data
* and the min/max values.
*/
- out = allocate_graph_lines(2 * a->item_list_sz, &outsize, &spmin, &spmax);
+ out = allocate_graph_lines(IN_ARRAY_SZ * a->item_list_sz, &outsize, &spmin, &spmax);
}
if (action & F_MAIN) {
spc = (struct stats_pwr_in *) ((char *) a->buf[curr] + i * a->msize);
/* Look for min/max values */
- if (spc->in < *(spmin + 2 * i)) {
- *(spmin + 2 * i) = spc->in;
+ if (spc->in < *(spmin + IN_ARRAY_SZ * i)) {
+ *(spmin + IN_ARRAY_SZ * i) = spc->in;
}
- if (spc->in > *(spmax + 2 * i)) {
- *(spmax + 2 * i) = spc->in;
+ if (spc->in > *(spmax + IN_ARRAY_SZ * i)) {
+ *(spmax + IN_ARRAY_SZ * i) = spc->in;
}
tval = (spc->in_max - spc->in_min) ?
(spc->in - spc->in_min) / (spc->in_max - spc->in_min) * 100 :
0.0;
- if (tval < *(spmin + 2 * i + 1)) {
- *(spmin + 2 * i + 1) = tval;
+ if (tval < *(spmin + IN_ARRAY_SZ * i + 1)) {
+ *(spmin + IN_ARRAY_SZ * i + 1) = tval;
}
- if (tval > *(spmax + 2 * i + 1)) {
- *(spmax + 2 * i + 1) = tval;
+ if (tval > *(spmax + IN_ARRAY_SZ * i + 1)) {
+ *(spmax + IN_ARRAY_SZ * i + 1) = tval;
}
/* inV */
lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
(double) spc->in,
- out + 2 * i, outsize + 2 * i, svg_p->restart);
+ out + IN_ARRAY_SZ * i, outsize + IN_ARRAY_SZ * i, svg_p->restart);
/* %in */
brappend(record_hdr->ust_time - svg_p->ust_time_ref,
0.0, tval,
- out + 2 * i + 1, outsize + 2 * i + 1, svg_p->dt);
+ out + IN_ARRAY_SZ * i + 1, outsize + IN_ARRAY_SZ * i + 1, svg_p->dt);
}
}
spc = (struct stats_pwr_in *) ((char *) a->buf[curr] + i * a->msize);
- snprintf(item_name, MAX_SENSORS_DEV_LEN + 8, "%d: %s", i + 1, spc->device);
- item_name[MAX_SENSORS_DEV_LEN + 7] = '\0';
+ snprintf(item_name, sizeof(item_name), "%d: %s", i + 1, spc->device);
+ item_name[sizeof(item_name) - 1] = '\0';
if (draw_activity_graphs(a->g_nr, g_type,
title, g_title, item_name, group,
- spmin + 2 * i, spmax + 2 * i, out + 2 * i, outsize + 2 * i,
- svg_p, record_hdr, FALSE, a->id, xid)) {
+ spmin + IN_ARRAY_SZ * i, spmax + IN_ARRAY_SZ * i,
+ out + IN_ARRAY_SZ * i, outsize + IN_ARRAY_SZ * i,
+ svg_p, record_hdr, FALSE, a, xid)) {
xid++;
}
}
if (action & F_END) {
draw_activity_graphs(a->g_nr, g_type,
title, g_title, NULL, group,
- spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a->id, 0);
+ spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
/* Free remaining structures */
free_graphs(out, outsize, spmin, spmax);
* @record_hdr Pointer on record header of current stats sample.
***************************************************************************
*/
+#define FS_ARRAY_SZ 8
__print_funct_t svg_print_filesystem_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
unsigned long long itv, struct record_header *record_hdr)
{
static double *spmin, *spmax;
static char **out;
static int *outsize;
- char *item_name;
+ char *dev_name, *item_name;
double tval;
int i, k, pos, restart;
/*
* Allocate arrays (#0..6) that will contain the graphs data
* and the min/max values.
- * Also allocate two additional arrays (#7..8) for each filesystem:
- * out + 7 will contain the filesystem name,
- * out + 8 will contain the mount point.
+ * Also allocate an additional arrays (#7) for each filesystem:
+ * out + 7 will contain the persistent or standard fs name, or mount point.
*/
- out = allocate_graph_lines(9 * a->item_list_sz, &outsize, &spmin, &spmax);
+ out = allocate_graph_lines(FS_ARRAY_SZ * a->item_list_sz, &outsize, &spmin, &spmax);
}
if (action & F_MAIN) {
for (i = 0; i < a->nr[curr]; i++) {
sfc = (struct stats_filesystem *) ((char *) a->buf[curr] + i * a->msize);
+ /* Get name to display (persistent or standard fs name, or mount point) */
+ dev_name = get_fs_name_to_display(a, flags, sfc);
+
if (a->item_list != NULL) {
/* A list of devices has been entered on the command line */
- if (!search_list_item(a->item_list,
- DISPLAY_MOUNT(a->opt_flags) ? sfc->mountp : sfc->fs_name))
+ if (!search_list_item(a->item_list, dev_name))
/* Device not found */
continue;
}
/* Look for corresponding graph */
for (k = 0; k < a->item_list_sz; k++) {
- item_name = *(out + k * 9 + 7);
- if (!strcmp(sfc->fs_name, item_name))
+ item_name = *(out + k * FS_ARRAY_SZ + 7);
+ if (!strcmp(dev_name, item_name))
/* Graph found! */
break;
}
if (k == a->item_list_sz) {
/* Graph not found: Look for first free entry */
for (k = 0; k < a->item_list_sz; k++) {
- item_name = *(out + k * 9 + 7);
+ item_name = *(out + k * FS_ARRAY_SZ + 7);
if (!strcmp(item_name, ""))
break;
}
}
}
- pos = k * 9;
+ pos = k * FS_ARRAY_SZ;
item_name = *(out + pos + 7);
if (!item_name[0]) {
/* Save filesystem name and mount point (if not already done) */
- strncpy(item_name, sfc->fs_name, CHUNKSIZE);
- item_name[CHUNKSIZE - 1] = '\0';
- item_name = *(out + pos + 8);
- strncpy(item_name, sfc->mountp, CHUNKSIZE);
+ strncpy(item_name, dev_name, CHUNKSIZE);
item_name[CHUNKSIZE - 1] = '\0';
}
for (i = 0; i < a->item_list_sz; i++) {
/* Check if there is something to display */
- pos = i * 9;
+ pos = i * FS_ARRAY_SZ;
if (!**(out + pos))
continue;
- /* Conversion B -> MB and inodes/1000 */
+ /* Conversion B -> MiB and inodes/1000 */
for (k = 0; k < 2; k++) {
*(spmin + pos + k) /= (1024 * 1024);
*(spmax + pos + k) /= (1024 * 1024);
*(spmax + pos + 4 + k) /= 1000;
}
- if (DISPLAY_MOUNT(a->opt_flags)) {
- item_name = *(out + pos + 8);
- }
- else {
- item_name = *(out + pos + 7);
- }
+ item_name = *(out + pos + 7);
if (draw_activity_graphs(a->g_nr, g_type, title, g_title, item_name, group,
spmin + pos, spmax + pos, out + pos, outsize + pos,
- svg_p, record_hdr, FALSE, a->id, xid)) {
+ svg_p, record_hdr, FALSE, a, xid)) {
xid++;
}
}
* @record_hdr Pointer on record header of current stats sample.
***************************************************************************
*/
+#define FC_ARRAY_SZ 5
__print_funct_t svg_print_fchost_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
unsigned long long itv, struct record_header *record_hdr)
{
- struct stats_fchost *sfcc, *sfcp;
+ struct stats_fchost *sfcc, *sfcp, sfczero;
int group[] = {2, 2};
int g_type[] = {SVG_LINE_GRAPH, SVG_LINE_GRAPH};
char *title[] = {"Fibre Channel HBA statistics (1)", "Fibre Channel HBA statistics (2)"};
* has either still not been registered, or has been unregistered
* (outsize + 4).
*/
- out = allocate_graph_lines(5 * a->item_list_sz, &outsize, &spmin, &spmax);
+ out = allocate_graph_lines(FC_ARRAY_SZ * a->item_list_sz, &outsize, &spmin, &spmax);
}
if (action & F_MAIN) {
- restart = svg_p->restart;
+ memset(&sfczero, 0, sizeof(struct stats_fchost));
/*
* Mark previously registered interfaces as now
* possibly unregistered for all graphs.
*/
for (k = 0; k < a->item_list_sz; k++) {
- unregistered = outsize + k * 5 + 4;
+ unregistered = outsize + k * FC_ARRAY_SZ + 4;
if (*unregistered == FALSE) {
*unregistered = MAYBE;
}
for (i = 0; i < a->nr[curr]; i++) {
found = FALSE;
+ sfcc = (struct stats_fchost *) ((char *) a->buf[curr] + i * a->msize);
+ restart = svg_p->restart;
- if (a->nr[!curr] > 0) {
- sfcc = (struct stats_fchost *) ((char *) a->buf[curr] + i * a->msize);
-
- /* Look for corresponding graph */
+ /* Look for corresponding graph */
+ for (k = 0; k < a->item_list_sz; k++) {
+ item_name = *(out + k * FC_ARRAY_SZ + 4);
+ if (!strcmp(sfcc->fchost_name, item_name))
+ /* Graph found! */
+ break;
+ }
+ if (k == a->item_list_sz) {
+ /* Graph not found: Look for first free entry */
for (k = 0; k < a->item_list_sz; k++) {
- item_name = *(out + k * 5 + 4);
- if (!strcmp(sfcc->fchost_name, item_name))
- /* Graph found! */
+ item_name = *(out + k * FC_ARRAY_SZ + 4);
+ if (!strcmp(item_name, ""))
break;
}
if (k == a->item_list_sz) {
- /* Graph not found: Look for first free entry */
- for (k = 0; k < a->item_list_sz; k++) {
- item_name = *(out + k * 5 + 4);
- if (!strcmp(item_name, ""))
- break;
- }
- if (k == a->item_list_sz) {
- /* No free graph entry: Ignore it (should never happen) */
+ /* No free graph entry: Ignore it (should never happen) */
#ifdef DEBUG
- fprintf(stderr, "%s: Name=%s\n",
- __FUNCTION__, sfcc->fchost_name);
+ fprintf(stderr, "%s: Name=%s\n",
+ __FUNCTION__, sfcc->fchost_name);
#endif
- continue;
- }
+ continue;
}
+ }
- pos = k * 5;
- unregistered = outsize + pos + 4;
+ pos = k * FC_ARRAY_SZ;
+ unregistered = outsize + pos + 4;
+ if (a->nr[!curr] > 0) {
/* Look for corresponding structure in previous iteration */
j = i;
while (j != j0);
}
- if (!found)
- continue;
+ if (!found) {
+ /* This is a newly registered host */
+ sfcp = &sfczero;
+ restart = TRUE;
+ }
/*
* If current interface was marked as previously unregistered,
/* Mark interfaces not seen here as now unregistered */
for (k = 0; k < a->item_list_sz; k++) {
- unregistered = outsize + k * 5 + 4;
+ unregistered = outsize + k * FC_ARRAY_SZ + 4;
if (*unregistered != FALSE) {
*unregistered = TRUE;
}
for (i = 0; i < a->item_list_sz; i++) {
/* Check if there is something to display */
- pos = i * 5;
+ pos = i * FC_ARRAY_SZ;
if (!**(out + pos))
continue;
draw_activity_graphs(a->g_nr, g_type,
title, g_title, item_name, group,
spmin + pos, spmax + pos, out + pos, outsize + pos,
- svg_p, record_hdr, FALSE, a->id, i);
+ svg_p, record_hdr, FALSE, a, i);
}
/* Free remaining structures */
* @record_hdr Pointer on record header of current stats sample.
***************************************************************************
*/
+#define SOFT_ARRAY_SZ 5
__print_funct_t svg_print_softnet_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
unsigned long long itv, struct record_header *record_hdr)
{
* Allocate arrays that will contain the graphs data
* and the min/max values.
*/
- out = allocate_graph_lines(5 * a->item_list_sz, &outsize, &spmin, &spmax);
+ out = allocate_graph_lines(SOFT_ARRAY_SZ * a->item_list_sz, &outsize, &spmin, &spmax);
}
if (action & F_MAIN) {
ssnc = &ssnczero;
}
}
- pos = i * 5;
+ pos = i * SOFT_ARRAY_SZ;
/* Check for min/max values */
save_extrema(a->gtypes_nr, (void *) ssnc, (void *) ssnp,
/* No */
continue;
- pos = i * 5;
+ pos = i * SOFT_ARRAY_SZ;
if (!i) {
/* This is CPU "all" */
draw_activity_graphs(a->g_nr, g_type,
title, g_title, item_name, group,
spmin + pos, spmax + pos, out + pos, outsize + pos,
- svg_p, record_hdr, FALSE, a->id, i);
+ svg_p, record_hdr, FALSE, a, i);
+ }
+
+ /* Free remaining structures */
+ free_graphs(out, outsize, spmin, spmax);
+ }
+}
+
+/*
+ ***************************************************************************
+ * Display pressure-stall CPU statistics in SVG.
+ *
+ * IN:
+ * @a Activity structure with statistics.
+ * @curr Index in array for current sample statistics.
+ * @action Action expected from current function.
+ * @svg_p SVG specific parameters: Current graph number (.@graph_no),
+ * flag indicating that a restart record has been previously
+ * found (.@restart) and time used for the X axis origin
+ * (@ust_time_ref).
+ * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
+ * @record_hdr Pointer on record header of current stats sample.
+ ***************************************************************************
+ */
+__print_funct_t svg_print_psicpu_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
+ unsigned long long itv, struct record_header *record_hdr)
+{
+ struct stats_psi_cpu
+ *psic = (struct stats_psi_cpu *) a->buf[curr],
+ *psip = (struct stats_psi_cpu *) a->buf[!curr];
+ int group[] = {3, 1};
+ int g_type[] = {SVG_LINE_GRAPH, SVG_BAR_GRAPH};
+ char *title[] = {"CPU pressure trends (some tasks)", "CPU stall time (some tasks)"};
+ char *g_title[] = {"%scpu-10", "%scpu-60", "%scpu-300",
+ "%scpu"};
+ static double *spmin, *spmax;
+ static char **out;
+ static int *outsize;
+ double tval;
+
+ if (action & F_BEGIN) {
+ /*
+ * Allocate arrays that will contain the graphs data
+ * and the min/max values.
+ */
+ out = allocate_graph_lines(4, &outsize, &spmin, &spmax);
+ }
+
+ if (action & F_MAIN) {
+ /* Check for min/max values */
+ if (psic->some_acpu_10 > *spmax) {
+ *spmax = psic->some_acpu_10;
+ }
+ if (psic->some_acpu_10 < *spmin) {
+ *spmin = psic->some_acpu_10;
+ }
+ if (psic->some_acpu_60 > *(spmax + 1)) {
+ *(spmax + 1) = psic->some_acpu_60;
+ }
+ if (psic->some_acpu_60 < *(spmin + 1)) {
+ *(spmin + 1) = psic->some_acpu_60;
+ }
+ if (psic->some_acpu_300 > *(spmax + 2)) {
+ *(spmax + 2) = psic->some_acpu_300;
+ }
+ if (psic->some_acpu_300 < *(spmin + 2)) {
+ *(spmin + 2) = psic->some_acpu_300;
+ }
+ tval = ((double) psic->some_cpu_total - psip->some_cpu_total) / (100 * itv);
+ if (tval > *(spmax + 3)) {
+ *(spmax + 3) = tval;
+ }
+ if (tval < *(spmin + 3)) {
+ *(spmin + 3) = tval;
+ }
+
+ /* %scpu-10 */
+ lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+ (double) psic->some_acpu_10 / 100,
+ out, outsize, svg_p->restart);
+ /* %scpu-60 */
+ lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+ (double) psic->some_acpu_60 / 100,
+ out + 1, outsize + 1, svg_p->restart);
+ /* %scpu-300 */
+ lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+ (double) psic->some_acpu_300 / 100,
+ out + 2, outsize + 2, svg_p->restart);
+ /* %scpu */
+ brappend(record_hdr->ust_time - svg_p->ust_time_ref,
+ 0.0,
+ ((double) psic->some_cpu_total - psip->some_cpu_total) / (100 * itv),
+ out + 3, outsize + 3, svg_p->dt);
+ }
+
+ if (action & F_END) {
+ /* Fix min/max values for pressure ratios */
+ *spmin /= 100; *spmax /= 100;
+ *(spmin + 1) /= 100; *(spmax + 1) /= 100;
+ *(spmin + 2) /= 100; *(spmax + 2) /= 100;
+
+ draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
+ spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
+
+ /* Free remaining structures */
+ free_graphs(out, outsize, spmin, spmax);
+ }
+}
+
+/*
+ ***************************************************************************
+ * Display pressure-stall I/O statistics in SVG.
+ *
+ * IN:
+ * @a Activity structure with statistics.
+ * @curr Index in array for current sample statistics.
+ * @action Action expected from current function.
+ * @svg_p SVG specific parameters: Current graph number (.@graph_no),
+ * flag indicating that a restart record has been previously
+ * found (.@restart) and time used for the X axis origin
+ * (@ust_time_ref).
+ * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
+ * @record_hdr Pointer on record header of current stats sample.
+ ***************************************************************************
+ */
+__print_funct_t svg_print_psiio_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
+ unsigned long long itv, struct record_header *record_hdr)
+{
+ struct stats_psi_io
+ *psic = (struct stats_psi_io *) a->buf[curr],
+ *psip = (struct stats_psi_io *) a->buf[!curr];
+ int group[] = {3, 1, 3, 1};
+ int g_type[] = {SVG_LINE_GRAPH, SVG_BAR_GRAPH, SVG_LINE_GRAPH, SVG_BAR_GRAPH};
+ char *title[] = {"I/O pressure trends (some tasks)", "I/O stall time (some tasks)",
+ "I/O pressure trends (full)", "I/O stall time (full)"};
+ char *g_title[] = {"%sio-10", "%sio-60", "%sio-300",
+ "%sio",
+ "%fio-10", "%fio-60", "%fio-300",
+ "%fio"};
+ static double *spmin, *spmax;
+ static char **out;
+ static int *outsize;
+ double tval;
+
+ if (action & F_BEGIN) {
+ /*
+ * Allocate arrays that will contain the graphs data
+ * and the min/max values.
+ */
+ out = allocate_graph_lines(8, &outsize, &spmin, &spmax);
+ }
+
+ if (action & F_MAIN) {
+ /* Check for min/max values */
+ if (psic->some_aio_10 > *spmax) {
+ *spmax = psic->some_aio_10;
}
+ if (psic->some_aio_10 < *spmin) {
+ *spmin = psic->some_aio_10;
+ }
+ if (psic->some_aio_60 > *(spmax + 1)) {
+ *(spmax + 1) = psic->some_aio_60;
+ }
+ if (psic->some_aio_60 < *(spmin + 1)) {
+ *(spmin + 1) = psic->some_aio_60;
+ }
+ if (psic->some_aio_300 > *(spmax + 2)) {
+ *(spmax + 2) = psic->some_aio_300;
+ }
+ if (psic->some_aio_300 < *(spmin + 2)) {
+ *(spmin + 2) = psic->some_aio_300;
+ }
+ tval = ((double) psic->some_io_total - psip->some_io_total) / (100 * itv);
+ if (tval > *(spmax + 3)) {
+ *(spmax + 3) = tval;
+ }
+ if (tval < *(spmin + 3)) {
+ *(spmin + 3) = tval;
+ }
+
+ if (psic->full_aio_10 > *(spmax + 4)) {
+ *(spmax + 4) = psic->full_aio_10;
+ }
+ if (psic->full_aio_10 < *(spmin + 4)) {
+ *(spmin + 4) = psic->full_aio_10;
+ }
+ if (psic->full_aio_60 > *(spmax + 5)) {
+ *(spmax + 5) = psic->full_aio_60;
+ }
+ if (psic->full_aio_60 < *(spmin + 5)) {
+ *(spmin + 5) = psic->full_aio_60;
+ }
+ if (psic->full_aio_300 > *(spmax + 6)) {
+ *(spmax + 6) = psic->full_aio_300;
+ }
+ if (psic->full_aio_300 < *(spmin + 6)) {
+ *(spmin + 6) = psic->full_aio_300;
+ }
+ tval = ((double) psic->full_io_total - psip->full_io_total) / (100 * itv);
+ if (tval > *(spmax + 7)) {
+ *(spmax + 7) = tval;
+ }
+ if (tval < *(spmin + 7)) {
+ *(spmin + 7) = tval;
+ }
+
+ /* %sio-10 */
+ lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+ (double) psic->some_aio_10 / 100,
+ out, outsize, svg_p->restart);
+ /* %sio-60 */
+ lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+ (double) psic->some_aio_60 / 100,
+ out + 1, outsize + 1, svg_p->restart);
+ /* %sio-300 */
+ lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+ (double) psic->some_aio_300 / 100,
+ out + 2, outsize + 2, svg_p->restart);
+ /* %sio */
+ brappend(record_hdr->ust_time - svg_p->ust_time_ref,
+ 0.0,
+ ((double) psic->some_io_total - psip->some_io_total) / (100 * itv),
+ out + 3, outsize + 3, svg_p->dt);
+
+ /* %fio-10 */
+ lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+ (double) psic->full_aio_10 / 100,
+ out + 4, outsize + 4, svg_p->restart);
+ /* %fio-60 */
+ lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+ (double) psic->full_aio_60 / 100,
+ out + 5, outsize + 5, svg_p->restart);
+ /* %fio-300 */
+ lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+ (double) psic->full_aio_300 / 100,
+ out + 6, outsize + 6, svg_p->restart);
+ /* %fio */
+ brappend(record_hdr->ust_time - svg_p->ust_time_ref,
+ 0.0,
+ ((double) psic->full_io_total - psip->full_io_total) / (100 * itv),
+ out + 7, outsize + 7, svg_p->dt);
+ }
+
+ if (action & F_END) {
+ /* Fix min/max values for pressure ratios */
+ *spmin /= 100; *spmax /= 100;
+ *(spmin + 1) /= 100; *(spmax + 1) /= 100;
+ *(spmin + 2) /= 100; *(spmax + 2) /= 100;
+
+ *(spmin + 4) /= 100; *(spmax + 4) /= 100;
+ *(spmin + 5) /= 100; *(spmax + 5) /= 100;
+ *(spmin + 6) /= 100; *(spmax + 6) /= 100;
+
+ draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
+ spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
+
+ /* Free remaining structures */
+ free_graphs(out, outsize, spmin, spmax);
+ }
+}
+
+/*
+ ***************************************************************************
+ * Display pressure-stall memory statistics in SVG.
+ *
+ * IN:
+ * @a Activity structure with statistics.
+ * @curr Index in array for current sample statistics.
+ * @action Action expected from current function.
+ * @svg_p SVG specific parameters: Current graph number (.@graph_no),
+ * flag indicating that a restart record has been previously
+ * found (.@restart) and time used for the X axis origin
+ * (@ust_time_ref).
+ * @itv Interval of time in 1/100th of a second (only with F_MAIN action).
+ * @record_hdr Pointer on record header of current stats sample.
+ ***************************************************************************
+ */
+__print_funct_t svg_print_psimem_stats(struct activity *a, int curr, int action, struct svg_parm *svg_p,
+ unsigned long long itv, struct record_header *record_hdr)
+{
+ struct stats_psi_mem
+ *psic = (struct stats_psi_mem *) a->buf[curr],
+ *psip = (struct stats_psi_mem *) a->buf[!curr];
+ int group[] = {3, 1, 3, 1};
+ int g_type[] = {SVG_LINE_GRAPH, SVG_BAR_GRAPH, SVG_LINE_GRAPH, SVG_BAR_GRAPH};
+ char *title[] = {"Memory pressure trends (some tasks)", "Memory stall time (some tasks)",
+ "Memory pressure trends (full)", "Memory stall time (full)"};
+ char *g_title[] = {"%smem-10", "%smem-60", "%smem-300",
+ "%smem",
+ "%fmem-10", "%fmem-60", "%fmem-300",
+ "%fmem"};
+ static double *spmin, *spmax;
+ static char **out;
+ static int *outsize;
+ double tval;
+
+ if (action & F_BEGIN) {
+ /*
+ * Allocate arrays that will contain the graphs data
+ * and the min/max values.
+ */
+ out = allocate_graph_lines(8, &outsize, &spmin, &spmax);
+ }
+
+ if (action & F_MAIN) {
+ /* Check for min/max values */
+ if (psic->some_amem_10 > *spmax) {
+ *spmax = psic->some_amem_10;
+ }
+ if (psic->some_amem_10 < *spmin) {
+ *spmin = psic->some_amem_10;
+ }
+ if (psic->some_amem_60 > *(spmax + 1)) {
+ *(spmax + 1) = psic->some_amem_60;
+ }
+ if (psic->some_amem_60 < *(spmin + 1)) {
+ *(spmin + 1) = psic->some_amem_60;
+ }
+ if (psic->some_amem_300 > *(spmax + 2)) {
+ *(spmax + 2) = psic->some_amem_300;
+ }
+ if (psic->some_amem_300 < *(spmin + 2)) {
+ *(spmin + 2) = psic->some_amem_300;
+ }
+ tval = ((double) psic->some_mem_total - psip->some_mem_total) / (100 * itv);
+ if (tval > *(spmax + 3)) {
+ *(spmax + 3) = tval;
+ }
+ if (tval < *(spmin + 3)) {
+ *(spmin + 3) = tval;
+ }
+
+ if (psic->full_amem_10 > *(spmax + 4)) {
+ *(spmax + 4) = psic->full_amem_10;
+ }
+ if (psic->full_amem_10 < *(spmin + 4)) {
+ *(spmin + 4) = psic->full_amem_10;
+ }
+ if (psic->full_amem_60 > *(spmax + 5)) {
+ *(spmax + 5) = psic->full_amem_60;
+ }
+ if (psic->full_amem_60 < *(spmin + 5)) {
+ *(spmin + 5) = psic->full_amem_60;
+ }
+ if (psic->full_amem_300 > *(spmax + 6)) {
+ *(spmax + 6) = psic->full_amem_300;
+ }
+ if (psic->full_amem_300 < *(spmin + 6)) {
+ *(spmin + 6) = psic->full_amem_300;
+ }
+ tval = ((double) psic->full_mem_total - psip->full_mem_total) / (100 * itv);
+ if (tval > *(spmax + 7)) {
+ *(spmax + 7) = tval;
+ }
+ if (tval < *(spmin + 7)) {
+ *(spmin + 7) = tval;
+ }
+
+ /* %smem-10 */
+ lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+ (double) psic->some_amem_10 / 100,
+ out, outsize, svg_p->restart);
+ /* %smem-60 */
+ lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+ (double) psic->some_amem_60 / 100,
+ out + 1, outsize + 1, svg_p->restart);
+ /* %smem-300 */
+ lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+ (double) psic->some_amem_300 / 100,
+ out + 2, outsize + 2, svg_p->restart);
+ /* %smem */
+ brappend(record_hdr->ust_time - svg_p->ust_time_ref,
+ 0.0,
+ ((double) psic->some_mem_total - psip->some_mem_total) / (100 * itv),
+ out + 3, outsize + 3, svg_p->dt);
+
+ /* %fmem-10 */
+ lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+ (double) psic->full_amem_10 / 100,
+ out + 4, outsize + 4, svg_p->restart);
+ /* %fmem-60 */
+ lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+ (double) psic->full_amem_60 / 100,
+ out + 5, outsize + 5, svg_p->restart);
+ /* %fmem-300 */
+ lnappend(record_hdr->ust_time - svg_p->ust_time_ref,
+ (double) psic->full_amem_300 / 100,
+ out + 6, outsize + 6, svg_p->restart);
+ /* %fmem */
+ brappend(record_hdr->ust_time - svg_p->ust_time_ref,
+ 0.0,
+ ((double) psic->full_mem_total - psip->full_mem_total) / (100 * itv),
+ out + 7, outsize + 7, svg_p->dt);
+ }
+
+ if (action & F_END) {
+ /* Fix min/max values for pressure ratios */
+ *spmin /= 100; *spmax /= 100;
+ *(spmin + 1) /= 100; *(spmax + 1) /= 100;
+ *(spmin + 2) /= 100; *(spmax + 2) /= 100;
+
+ *(spmin + 4) /= 100; *(spmax + 4) /= 100;
+ *(spmin + 5) /= 100; *(spmax + 5) /= 100;
+ *(spmin + 6) /= 100; *(spmax + 6) /= 100;
+
+ draw_activity_graphs(a->g_nr, g_type, title, g_title, NULL, group,
+ spmin, spmax, out, outsize, svg_p, record_hdr, FALSE, a, 0);
/* Free remaining structures */
free_graphs(out, outsize, spmin, spmax);