Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags   |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * svghelper.c - helper functions for outputting svg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * (C) Copyright 2009 Intel Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Authors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *     Arjan van de Ven <arjan@linux.intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <inttypes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/bitmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/time64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/zalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <internal/cpumap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <perf/cpumap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include "env.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include "svghelper.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) static u64 first_time, last_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) static u64 turbo_frequency, max_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define SLOT_MULT 30.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define SLOT_HEIGHT 25.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define SLOT_HALF (SLOT_HEIGHT / 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) int svg_page_width = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) u64 svg_highlight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) const char *svg_highlight_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define MIN_TEXT_SIZE 0.01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) static u64 total_height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) static FILE *svgfile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) static double cpu2slot(int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	return 2 * cpu + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) static int *topology_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) static double cpu2y(int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	if (topology_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		return cpu2slot(topology_map[cpu]) * SLOT_MULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		return cpu2slot(cpu) * SLOT_MULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) static double time2pixels(u64 __time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	double X;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	X = 1.0 * svg_page_width * (__time - first_time) / (last_time - first_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	return X;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  * Round text sizes so that the svg viewer only needs a discrete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  * number of renderings of the font
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) static double round_text_size(double size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	int loop = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	double target = 10.0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	if (size >= 10.0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	while (loop--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		if (size >= target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 			return target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		target = target / 2.0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) void open_svg(const char *filename, int cpus, int rows, u64 start, u64 end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	int new_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	svgfile = fopen(filename, "w");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	if (!svgfile) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		fprintf(stderr, "Cannot open %s for output\n", filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	first_time = start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	first_time = first_time / 100000000 * 100000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	last_time = end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	 * if the recording is short, we default to a width of 1000, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	 * for longer recordings we want at least 200 units of width per second
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	new_width = (last_time - first_time) / 5000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	if (new_width > svg_page_width)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		svg_page_width = new_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	total_height = (1 + rows + cpu2slot(cpus)) * SLOT_MULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	fprintf(svgfile, "<?xml version=\"1.0\" standalone=\"no\"?> \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	fprintf(svgfile, "<!DOCTYPE svg SYSTEM \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	fprintf(svgfile, "<svg width=\"%i\" height=\"%" PRIu64 "\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n", svg_page_width, total_height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	fprintf(svgfile, "<defs>\n  <style type=\"text/css\">\n    <![CDATA[\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	fprintf(svgfile, "      rect          { stroke-width: 1; }\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	fprintf(svgfile, "      rect.process  { fill:rgb(180,180,180); fill-opacity:0.9; stroke-width:1;   stroke:rgb(  0,  0,  0); } \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	fprintf(svgfile, "      rect.process2 { fill:rgb(180,180,180); fill-opacity:0.9; stroke-width:0;   stroke:rgb(  0,  0,  0); } \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	fprintf(svgfile, "      rect.process3 { fill:rgb(180,180,180); fill-opacity:0.5; stroke-width:0;   stroke:rgb(  0,  0,  0); } \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	fprintf(svgfile, "      rect.sample   { fill:rgb(  0,  0,255); fill-opacity:0.8; stroke-width:0;   stroke:rgb(  0,  0,  0); } \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	fprintf(svgfile, "      rect.sample_hi{ fill:rgb(255,128,  0); fill-opacity:0.8; stroke-width:0;   stroke:rgb(  0,  0,  0); } \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	fprintf(svgfile, "      rect.error    { fill:rgb(255,  0,  0); fill-opacity:0.5; stroke-width:0;   stroke:rgb(  0,  0,  0); } \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	fprintf(svgfile, "      rect.net      { fill:rgb(  0,128,  0); fill-opacity:0.5; stroke-width:0;   stroke:rgb(  0,  0,  0); } \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	fprintf(svgfile, "      rect.disk     { fill:rgb(  0,  0,255); fill-opacity:0.5; stroke-width:0;   stroke:rgb(  0,  0,  0); } \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	fprintf(svgfile, "      rect.sync     { fill:rgb(128,128,  0); fill-opacity:0.5; stroke-width:0;   stroke:rgb(  0,  0,  0); } \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	fprintf(svgfile, "      rect.poll     { fill:rgb(  0,128,128); fill-opacity:0.2; stroke-width:0;   stroke:rgb(  0,  0,  0); } \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	fprintf(svgfile, "      rect.blocked  { fill:rgb(255,  0,  0); fill-opacity:0.5; stroke-width:0;   stroke:rgb(  0,  0,  0); } \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	fprintf(svgfile, "      rect.waiting  { fill:rgb(224,214,  0); fill-opacity:0.8; stroke-width:0;   stroke:rgb(  0,  0,  0); } \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	fprintf(svgfile, "      rect.WAITING  { fill:rgb(255,214, 48); fill-opacity:0.6; stroke-width:0;   stroke:rgb(  0,  0,  0); } \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	fprintf(svgfile, "      rect.cpu      { fill:rgb(192,192,192); fill-opacity:0.2; stroke-width:0.5; stroke:rgb(128,128,128); } \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	fprintf(svgfile, "      rect.pstate   { fill:rgb(128,128,128); fill-opacity:0.8; stroke-width:0; } \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	fprintf(svgfile, "      rect.c1       { fill:rgb(255,214,214); fill-opacity:0.5; stroke-width:0; } \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	fprintf(svgfile, "      rect.c2       { fill:rgb(255,172,172); fill-opacity:0.5; stroke-width:0; } \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	fprintf(svgfile, "      rect.c3       { fill:rgb(255,130,130); fill-opacity:0.5; stroke-width:0; } \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	fprintf(svgfile, "      rect.c4       { fill:rgb(255, 88, 88); fill-opacity:0.5; stroke-width:0; } \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	fprintf(svgfile, "      rect.c5       { fill:rgb(255, 44, 44); fill-opacity:0.5; stroke-width:0; } \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	fprintf(svgfile, "      rect.c6       { fill:rgb(255,  0,  0); fill-opacity:0.5; stroke-width:0; } \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	fprintf(svgfile, "      line.pstate   { stroke:rgb(255,255,  0); stroke-opacity:0.8; stroke-width:2; } \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	fprintf(svgfile, "    ]]>\n   </style>\n</defs>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static double normalize_height(double height)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	if (height < 0.25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		return 0.25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	else if (height < 0.50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		return 0.50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	else if (height < 0.75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		return 0.75;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		return 0.100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) void svg_ubox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	double w = time2pixels(end) - time2pixels(start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	height = normalize_height(height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	if (!svgfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	fprintf(svgfile, "<g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	fprintf(svgfile, "<title>fd=%d error=%d merges=%d</title>\n", fd, err, merges);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	fprintf(svgfile, "<rect x=\"%.8f\" width=\"%.8f\" y=\"%.1f\" height=\"%.1f\" class=\"%s\"/>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		time2pixels(start),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		w,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		Yslot * SLOT_MULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		SLOT_HALF * height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	fprintf(svgfile, "</g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) void svg_lbox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	double w = time2pixels(end) - time2pixels(start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	height = normalize_height(height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	if (!svgfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	fprintf(svgfile, "<g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	fprintf(svgfile, "<title>fd=%d error=%d merges=%d</title>\n", fd, err, merges);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	fprintf(svgfile, "<rect x=\"%.8f\" width=\"%.8f\" y=\"%.1f\" height=\"%.1f\" class=\"%s\"/>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		time2pixels(start),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		w,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		Yslot * SLOT_MULT + SLOT_HEIGHT - SLOT_HALF * height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		SLOT_HALF * height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	fprintf(svgfile, "</g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) void svg_fbox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	double w = time2pixels(end) - time2pixels(start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	height = normalize_height(height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	if (!svgfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	fprintf(svgfile, "<g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	fprintf(svgfile, "<title>fd=%d error=%d merges=%d</title>\n", fd, err, merges);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	fprintf(svgfile, "<rect x=\"%.8f\" width=\"%.8f\" y=\"%.1f\" height=\"%.1f\" class=\"%s\"/>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		time2pixels(start),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		w,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		Yslot * SLOT_MULT + SLOT_HEIGHT - SLOT_HEIGHT * height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		SLOT_HEIGHT * height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	fprintf(svgfile, "</g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) void svg_box(int Yslot, u64 start, u64 end, const char *type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	if (!svgfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	fprintf(svgfile, "<rect x=\"%.8f\" width=\"%.8f\" y=\"%.1f\" height=\"%.1f\" class=\"%s\"/>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		time2pixels(start), time2pixels(end)-time2pixels(start), Yslot * SLOT_MULT, SLOT_HEIGHT, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static char *time_to_string(u64 duration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) void svg_blocked(int Yslot, int cpu, u64 start, u64 end, const char *backtrace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	if (!svgfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	fprintf(svgfile, "<g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	fprintf(svgfile, "<title>#%d blocked %s</title>\n", cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		time_to_string(end - start));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	if (backtrace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		fprintf(svgfile, "<desc>Blocked on:\n%s</desc>\n", backtrace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	svg_box(Yslot, start, end, "blocked");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	fprintf(svgfile, "</g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) void svg_running(int Yslot, int cpu, u64 start, u64 end, const char *backtrace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	double text_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	const char *type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	if (!svgfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	if (svg_highlight && end - start > svg_highlight)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		type = "sample_hi";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		type = "sample";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	fprintf(svgfile, "<g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	fprintf(svgfile, "<title>#%d running %s</title>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		cpu, time_to_string(end - start));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	if (backtrace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		fprintf(svgfile, "<desc>Switched because:\n%s</desc>\n", backtrace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	fprintf(svgfile, "<rect x=\"%.8f\" width=\"%.8f\" y=\"%.1f\" height=\"%.1f\" class=\"%s\"/>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		time2pixels(start), time2pixels(end)-time2pixels(start), Yslot * SLOT_MULT, SLOT_HEIGHT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	text_size = (time2pixels(end)-time2pixels(start));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	if (cpu > 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		text_size = text_size/2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	if (text_size > 1.25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		text_size = 1.25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	text_size = round_text_size(text_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	if (text_size > MIN_TEXT_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		fprintf(svgfile, "<text x=\"%.8f\" y=\"%.8f\" font-size=\"%.8fpt\">%i</text>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 			time2pixels(start), Yslot *  SLOT_MULT + SLOT_HEIGHT - 1, text_size,  cpu + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	fprintf(svgfile, "</g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static char *time_to_string(u64 duration)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	static char text[80];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	text[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	if (duration < NSEC_PER_USEC) /* less than 1 usec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		return text;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	if (duration < NSEC_PER_MSEC) { /* less than 1 msec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		sprintf(text, "%.1f us", duration / (double)NSEC_PER_USEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		return text;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	sprintf(text, "%.1f ms", duration / (double)NSEC_PER_MSEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	return text;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) void svg_waiting(int Yslot, int cpu, u64 start, u64 end, const char *backtrace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	char *text;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	const char *style;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	double font_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	if (!svgfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	style = "waiting";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	if (end-start > 10 * NSEC_PER_MSEC) /* 10 msec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		style = "WAITING";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	text = time_to_string(end-start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	font_size = 1.0 * (time2pixels(end)-time2pixels(start));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	if (font_size > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		font_size = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	font_size = round_text_size(font_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	fprintf(svgfile, "<g transform=\"translate(%.8f,%.8f)\">\n", time2pixels(start), Yslot * SLOT_MULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	fprintf(svgfile, "<title>#%d waiting %s</title>\n", cpu, time_to_string(end - start));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	if (backtrace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		fprintf(svgfile, "<desc>Waiting on:\n%s</desc>\n", backtrace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	fprintf(svgfile, "<rect x=\"0\" width=\"%.8f\" y=\"0\" height=\"%.1f\" class=\"%s\"/>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		time2pixels(end)-time2pixels(start), SLOT_HEIGHT, style);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	if (font_size > MIN_TEXT_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		fprintf(svgfile, "<text transform=\"rotate(90)\" font-size=\"%.8fpt\"> %s</text>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 			font_size, text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	fprintf(svgfile, "</g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static char *cpu_model(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	static char cpu_m[255];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	char buf[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	FILE *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	cpu_m[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	/* CPU type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	file = fopen("/proc/cpuinfo", "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	if (file) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		while (fgets(buf, 255, file)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 			if (strstr(buf, "model name")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 				strlcpy(cpu_m, &buf[13], 255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		fclose(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	/* CPU type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	file = fopen("/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies", "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	if (file) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		while (fgets(buf, 255, file)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 			unsigned int freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 			freq = strtoull(buf, NULL, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 			if (freq > max_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 				max_freq = freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		fclose(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	return cpu_m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) void svg_cpu_box(int cpu, u64 __max_freq, u64 __turbo_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	char cpu_string[80];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	if (!svgfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	max_freq = __max_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	turbo_frequency = __turbo_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	fprintf(svgfile, "<g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	fprintf(svgfile, "<rect x=\"%.8f\" width=\"%.8f\" y=\"%.1f\" height=\"%.1f\" class=\"cpu\"/>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		time2pixels(first_time),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		time2pixels(last_time)-time2pixels(first_time),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		cpu2y(cpu), SLOT_MULT+SLOT_HEIGHT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	sprintf(cpu_string, "CPU %i", (int)cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	fprintf(svgfile, "<text x=\"%.8f\" y=\"%.8f\">%s</text>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		10+time2pixels(first_time), cpu2y(cpu) + SLOT_HEIGHT/2, cpu_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	fprintf(svgfile, "<text transform=\"translate(%.8f,%.8f)\" font-size=\"1.25pt\">%s</text>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		10+time2pixels(first_time), cpu2y(cpu) + SLOT_MULT + SLOT_HEIGHT - 4, cpu_model());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	fprintf(svgfile, "</g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) void svg_process(int cpu, u64 start, u64 end, int pid, const char *name, const char *backtrace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	double width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	const char *type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	if (!svgfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	if (svg_highlight && end - start >= svg_highlight)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 		type = "sample_hi";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	else if (svg_highlight_name && strstr(name, svg_highlight_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		type = "sample_hi";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 		type = "sample";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	fprintf(svgfile, "<g transform=\"translate(%.8f,%.8f)\">\n", time2pixels(start), cpu2y(cpu));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	fprintf(svgfile, "<title>%d %s running %s</title>\n", pid, name, time_to_string(end - start));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	if (backtrace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		fprintf(svgfile, "<desc>Switched because:\n%s</desc>\n", backtrace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	fprintf(svgfile, "<rect x=\"0\" width=\"%.8f\" y=\"0\" height=\"%.1f\" class=\"%s\"/>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		time2pixels(end)-time2pixels(start), SLOT_MULT+SLOT_HEIGHT, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	width = time2pixels(end)-time2pixels(start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	if (width > 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 		width = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	width = round_text_size(width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	if (width > MIN_TEXT_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		fprintf(svgfile, "<text transform=\"rotate(90)\" font-size=\"%.8fpt\">%s</text>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 			width, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	fprintf(svgfile, "</g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) void svg_cstate(int cpu, u64 start, u64 end, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	double width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	char style[128];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	if (!svgfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	fprintf(svgfile, "<g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	if (type > 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		type = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	sprintf(style, "c%i", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	fprintf(svgfile, "<rect class=\"%s\" x=\"%.8f\" width=\"%.8f\" y=\"%.1f\" height=\"%.1f\"/>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 		style,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		time2pixels(start), time2pixels(end)-time2pixels(start),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 		cpu2y(cpu), SLOT_MULT+SLOT_HEIGHT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	width = (time2pixels(end)-time2pixels(start))/2.0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	if (width > 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		width = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	width = round_text_size(width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	if (width > MIN_TEXT_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		fprintf(svgfile, "<text x=\"%.8f\" y=\"%.8f\" font-size=\"%.8fpt\">C%i</text>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 			time2pixels(start), cpu2y(cpu)+width, width, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	fprintf(svgfile, "</g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) static char *HzToHuman(unsigned long hz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	static char buffer[1024];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	unsigned long long Hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	memset(buffer, 0, 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	Hz = hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	/* default: just put the Number in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	sprintf(buffer, "%9lli", Hz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	if (Hz > 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		sprintf(buffer, " %6lli Mhz", (Hz+500)/1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	if (Hz > 1500000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		sprintf(buffer, " %6.2f Ghz", (Hz+5000.0)/1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	if (Hz == turbo_frequency)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		sprintf(buffer, "Turbo");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	return buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) void svg_pstate(int cpu, u64 start, u64 end, u64 freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	double height = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	if (!svgfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	fprintf(svgfile, "<g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	if (max_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 		height = freq * 1.0 / max_freq * (SLOT_HEIGHT + SLOT_MULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	height = 1 + cpu2y(cpu) + SLOT_MULT + SLOT_HEIGHT - height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	fprintf(svgfile, "<line x1=\"%.8f\" x2=\"%.8f\" y1=\"%.1f\" y2=\"%.1f\" class=\"pstate\"/>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 		time2pixels(start), time2pixels(end), height, height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	fprintf(svgfile, "<text x=\"%.8f\" y=\"%.8f\" font-size=\"0.25pt\">%s</text>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 		time2pixels(start), height+0.9, HzToHuman(freq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	fprintf(svgfile, "</g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) void svg_partial_wakeline(u64 start, int row1, char *desc1, int row2, char *desc2, const char *backtrace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	double height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	if (!svgfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	fprintf(svgfile, "<g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	fprintf(svgfile, "<title>%s wakes up %s</title>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 		desc1 ? desc1 : "?",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 		desc2 ? desc2 : "?");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	if (backtrace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 		fprintf(svgfile, "<desc>%s</desc>\n", backtrace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	if (row1 < row2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		if (row1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 			fprintf(svgfile, "<line x1=\"%.8f\" y1=\"%.2f\" x2=\"%.8f\" y2=\"%.2f\" style=\"stroke:rgb(32,255,32);stroke-width:0.009\"/>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 				time2pixels(start), row1 * SLOT_MULT + SLOT_HEIGHT,  time2pixels(start), row1 * SLOT_MULT + SLOT_HEIGHT + SLOT_MULT/32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 			if (desc2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 				fprintf(svgfile, "<g transform=\"translate(%.8f,%.8f)\"><text transform=\"rotate(90)\" font-size=\"0.02pt\">%s &gt;</text></g>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 					time2pixels(start), row1 * SLOT_MULT + SLOT_HEIGHT + SLOT_HEIGHT/48, desc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		if (row2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 			fprintf(svgfile, "<line x1=\"%.8f\" y1=\"%.2f\" x2=\"%.8f\" y2=\"%.2f\" style=\"stroke:rgb(32,255,32);stroke-width:0.009\"/>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 				time2pixels(start), row2 * SLOT_MULT - SLOT_MULT/32,  time2pixels(start), row2 * SLOT_MULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 			if (desc1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 				fprintf(svgfile, "<g transform=\"translate(%.8f,%.8f)\"><text transform=\"rotate(90)\" font-size=\"0.02pt\">%s &gt;</text></g>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 					time2pixels(start), row2 * SLOT_MULT - SLOT_MULT/32, desc1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 		if (row2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 			fprintf(svgfile, "<line x1=\"%.8f\" y1=\"%.2f\" x2=\"%.8f\" y2=\"%.2f\" style=\"stroke:rgb(32,255,32);stroke-width:0.009\"/>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 				time2pixels(start), row2 * SLOT_MULT + SLOT_HEIGHT,  time2pixels(start), row2 * SLOT_MULT + SLOT_HEIGHT + SLOT_MULT/32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 			if (desc1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 				fprintf(svgfile, "<g transform=\"translate(%.8f,%.8f)\"><text transform=\"rotate(90)\" font-size=\"0.02pt\">%s &lt;</text></g>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 					time2pixels(start), row2 * SLOT_MULT + SLOT_HEIGHT + SLOT_MULT/48, desc1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 		if (row1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 			fprintf(svgfile, "<line x1=\"%.8f\" y1=\"%.2f\" x2=\"%.8f\" y2=\"%.2f\" style=\"stroke:rgb(32,255,32);stroke-width:0.009\"/>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 				time2pixels(start), row1 * SLOT_MULT - SLOT_MULT/32,  time2pixels(start), row1 * SLOT_MULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 			if (desc2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 				fprintf(svgfile, "<g transform=\"translate(%.8f,%.8f)\"><text transform=\"rotate(90)\" font-size=\"0.02pt\">%s &lt;</text></g>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 					time2pixels(start), row1 * SLOT_MULT - SLOT_HEIGHT/32, desc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	height = row1 * SLOT_MULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	if (row2 > row1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		height += SLOT_HEIGHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	if (row1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 		fprintf(svgfile, "<circle  cx=\"%.8f\" cy=\"%.2f\" r = \"0.01\"  style=\"fill:rgb(32,255,32)\"/>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 			time2pixels(start), height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	fprintf(svgfile, "</g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) void svg_wakeline(u64 start, int row1, int row2, const char *backtrace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	double height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	if (!svgfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	fprintf(svgfile, "<g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	if (backtrace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 		fprintf(svgfile, "<desc>%s</desc>\n", backtrace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	if (row1 < row2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 		fprintf(svgfile, "<line x1=\"%.8f\" y1=\"%.2f\" x2=\"%.8f\" y2=\"%.2f\" style=\"stroke:rgb(32,255,32);stroke-width:0.009\"/>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 			time2pixels(start), row1 * SLOT_MULT + SLOT_HEIGHT,  time2pixels(start), row2 * SLOT_MULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 		fprintf(svgfile, "<line x1=\"%.8f\" y1=\"%.2f\" x2=\"%.8f\" y2=\"%.2f\" style=\"stroke:rgb(32,255,32);stroke-width:0.009\"/>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 			time2pixels(start), row2 * SLOT_MULT + SLOT_HEIGHT,  time2pixels(start), row1 * SLOT_MULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	height = row1 * SLOT_MULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	if (row2 > row1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 		height += SLOT_HEIGHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	fprintf(svgfile, "<circle  cx=\"%.8f\" cy=\"%.2f\" r = \"0.01\"  style=\"fill:rgb(32,255,32)\"/>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 			time2pixels(start), height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	fprintf(svgfile, "</g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) void svg_interrupt(u64 start, int row, const char *backtrace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	if (!svgfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	fprintf(svgfile, "<g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	fprintf(svgfile, "<title>Wakeup from interrupt</title>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	if (backtrace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 		fprintf(svgfile, "<desc>%s</desc>\n", backtrace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	fprintf(svgfile, "<circle  cx=\"%.8f\" cy=\"%.2f\" r = \"0.01\"  style=\"fill:rgb(255,128,128)\"/>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 			time2pixels(start), row * SLOT_MULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	fprintf(svgfile, "<circle  cx=\"%.8f\" cy=\"%.2f\" r = \"0.01\"  style=\"fill:rgb(255,128,128)\"/>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 			time2pixels(start), row * SLOT_MULT + SLOT_HEIGHT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	fprintf(svgfile, "</g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) void svg_text(int Yslot, u64 start, const char *text)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	if (!svgfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	fprintf(svgfile, "<text x=\"%.8f\" y=\"%.8f\">%s</text>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 		time2pixels(start), Yslot * SLOT_MULT+SLOT_HEIGHT/2, text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) static void svg_legenda_box(int X, const char *text, const char *style)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	double boxsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	boxsize = SLOT_HEIGHT / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	fprintf(svgfile, "<rect x=\"%i\" width=\"%.8f\" y=\"0\" height=\"%.1f\" class=\"%s\"/>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 		X, boxsize, boxsize, style);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	fprintf(svgfile, "<text transform=\"translate(%.8f, %.8f)\" font-size=\"%.8fpt\">%s</text>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 		X + boxsize + 5, boxsize, 0.8 * boxsize, text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) void svg_io_legenda(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	if (!svgfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	fprintf(svgfile, "<g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	svg_legenda_box(0,	"Disk", "disk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	svg_legenda_box(100,	"Network", "net");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	svg_legenda_box(200,	"Sync", "sync");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	svg_legenda_box(300,	"Poll", "poll");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	svg_legenda_box(400,	"Error", "error");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	fprintf(svgfile, "</g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) void svg_legenda(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	if (!svgfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	fprintf(svgfile, "<g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	svg_legenda_box(0,	"Running", "sample");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	svg_legenda_box(100,	"Idle","c1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	svg_legenda_box(200,	"Deeper Idle", "c3");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	svg_legenda_box(350,	"Deepest Idle", "c6");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	svg_legenda_box(550,	"Sleeping", "process2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 	svg_legenda_box(650,	"Waiting for cpu", "waiting");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	svg_legenda_box(800,	"Blocked on IO", "blocked");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	fprintf(svgfile, "</g>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) void svg_time_grid(double min_thickness)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	u64 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	if (!svgfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	i = first_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	while (i < last_time) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 		int color = 220;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 		double thickness = 0.075;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 		if ((i % 100000000) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 			thickness = 0.5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 			color = 192;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 		if ((i % 1000000000) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 			thickness = 2.0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 			color = 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 		if (thickness >= min_thickness)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 			fprintf(svgfile, "<line x1=\"%.8f\" y1=\"%.2f\" x2=\"%.8f\" y2=\"%" PRIu64 "\" style=\"stroke:rgb(%i,%i,%i);stroke-width:%.3f\"/>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 				time2pixels(i), SLOT_MULT/2, time2pixels(i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 				total_height, color, color, color, thickness);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 		i += 10000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) void svg_close(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	if (svgfile) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 		fprintf(svgfile, "</svg>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 		fclose(svgfile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 		svgfile = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) #define cpumask_bits(maskp) ((maskp)->bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) typedef struct { DECLARE_BITMAP(bits, MAX_NR_CPUS); } cpumask_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) struct topology {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	cpumask_t *sib_core;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 	int sib_core_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	cpumask_t *sib_thr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	int sib_thr_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) static void scan_thread_topology(int *map, struct topology *t, int cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 				 int *pos, int nr_cpus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	int thr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	for (i = 0; i < t->sib_thr_nr; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 		if (!test_bit(cpu, cpumask_bits(&t->sib_thr[i])))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 		for_each_set_bit(thr, cpumask_bits(&t->sib_thr[i]), nr_cpus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 			if (map[thr] == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 				map[thr] = (*pos)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) static void scan_core_topology(int *map, struct topology *t, int nr_cpus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	int pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 	int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	for (i = 0; i < t->sib_core_nr; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 		for_each_set_bit(cpu, cpumask_bits(&t->sib_core[i]), nr_cpus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 			scan_thread_topology(map, t, cpu, &pos, nr_cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) static int str_to_bitmap(char *s, cpumask_t *b, int nr_cpus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 	struct perf_cpu_map *m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	int c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 	m = perf_cpu_map__new(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	if (!m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	for (i = 0; i < m->nr; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 		c = m->map[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 		if (c >= nr_cpus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 			ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 		set_bit(c, cpumask_bits(b));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	perf_cpu_map__put(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) int svg_build_topology_map(struct perf_env *env)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 	int i, nr_cpus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 	struct topology t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 	char *sib_core, *sib_thr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 	nr_cpus = min(env->nr_cpus_online, MAX_NR_CPUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 	t.sib_core_nr = env->nr_sibling_cores;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	t.sib_thr_nr = env->nr_sibling_threads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 	t.sib_core = calloc(env->nr_sibling_cores, sizeof(cpumask_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 	t.sib_thr = calloc(env->nr_sibling_threads, sizeof(cpumask_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 	sib_core = env->sibling_cores;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 	sib_thr = env->sibling_threads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 	if (!t.sib_core || !t.sib_thr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 		fprintf(stderr, "topology: no memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 	for (i = 0; i < env->nr_sibling_cores; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 		if (str_to_bitmap(sib_core, &t.sib_core[i], nr_cpus)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 			fprintf(stderr, "topology: can't parse siblings map\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 			goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 		sib_core += strlen(sib_core) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 	for (i = 0; i < env->nr_sibling_threads; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 		if (str_to_bitmap(sib_thr, &t.sib_thr[i], nr_cpus)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 			fprintf(stderr, "topology: can't parse siblings map\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 			goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 		sib_thr += strlen(sib_thr) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 	topology_map = malloc(sizeof(int) * nr_cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 	if (!topology_map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 		fprintf(stderr, "topology: no memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 	for (i = 0; i < nr_cpus; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 		topology_map[i] = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 	scan_core_topology(topology_map, &t, nr_cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 	zfree(&t.sib_core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 	zfree(&t.sib_thr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) }