20 #include <linux/bitmap.h> 21 #include <linux/time64.h> 32 #define SLOT_MULT 30.0 33 #define SLOT_HEIGHT 25.0 34 #define SLOT_HALF (SLOT_HEIGHT / 2) 40 #define MIN_TEXT_SIZE 0.01 82 target = target / 2.0;
93 fprintf(stderr,
"Cannot open %s for output\n", filename);
110 fprintf(
svgfile,
"<?xml version=\"1.0\" standalone=\"no\"?> \n");
111 fprintf(
svgfile,
"<!DOCTYPE svg SYSTEM \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
114 fprintf(
svgfile,
"<defs>\n <style type=\"text/css\">\n <![CDATA[\n");
116 fprintf(
svgfile,
" rect { stroke-width: 1; }\n");
117 fprintf(
svgfile,
" rect.process { fill:rgb(180,180,180); fill-opacity:0.9; stroke-width:1; stroke:rgb( 0, 0, 0); } \n");
118 fprintf(
svgfile,
" rect.process2 { fill:rgb(180,180,180); fill-opacity:0.9; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
119 fprintf(
svgfile,
" rect.process3 { fill:rgb(180,180,180); fill-opacity:0.5; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
120 fprintf(
svgfile,
" rect.sample { fill:rgb( 0, 0,255); fill-opacity:0.8; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
121 fprintf(
svgfile,
" rect.sample_hi{ fill:rgb(255,128, 0); fill-opacity:0.8; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
122 fprintf(
svgfile,
" rect.error { fill:rgb(255, 0, 0); fill-opacity:0.5; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
123 fprintf(
svgfile,
" rect.net { fill:rgb( 0,128, 0); fill-opacity:0.5; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
124 fprintf(
svgfile,
" rect.disk { fill:rgb( 0, 0,255); fill-opacity:0.5; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
125 fprintf(
svgfile,
" rect.sync { fill:rgb(128,128, 0); fill-opacity:0.5; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
126 fprintf(
svgfile,
" rect.poll { fill:rgb( 0,128,128); fill-opacity:0.2; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
127 fprintf(
svgfile,
" rect.blocked { fill:rgb(255, 0, 0); fill-opacity:0.5; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
128 fprintf(
svgfile,
" rect.waiting { fill:rgb(224,214, 0); fill-opacity:0.8; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
129 fprintf(
svgfile,
" rect.WAITING { fill:rgb(255,214, 48); fill-opacity:0.6; stroke-width:0; stroke:rgb( 0, 0, 0); } \n");
130 fprintf(
svgfile,
" rect.cpu { fill:rgb(192,192,192); fill-opacity:0.2; stroke-width:0.5; stroke:rgb(128,128,128); } \n");
131 fprintf(
svgfile,
" rect.pstate { fill:rgb(128,128,128); fill-opacity:0.8; stroke-width:0; } \n");
132 fprintf(
svgfile,
" rect.c1 { fill:rgb(255,214,214); fill-opacity:0.5; stroke-width:0; } \n");
133 fprintf(
svgfile,
" rect.c2 { fill:rgb(255,172,172); fill-opacity:0.5; stroke-width:0; } \n");
134 fprintf(
svgfile,
" rect.c3 { fill:rgb(255,130,130); fill-opacity:0.5; stroke-width:0; } \n");
135 fprintf(
svgfile,
" rect.c4 { fill:rgb(255, 88, 88); fill-opacity:0.5; stroke-width:0; } \n");
136 fprintf(
svgfile,
" rect.c5 { fill:rgb(255, 44, 44); fill-opacity:0.5; stroke-width:0; } \n");
137 fprintf(
svgfile,
" rect.c6 { fill:rgb(255, 0, 0); fill-opacity:0.5; stroke-width:0; } \n");
138 fprintf(
svgfile,
" line.pstate { stroke:rgb(255,255, 0); stroke-opacity:0.8; stroke-width:2; } \n");
140 fprintf(
svgfile,
" ]]>\n </style>\n</defs>\n");
147 else if (height < 0.50)
149 else if (height < 0.75)
155 void svg_ubox(
int Yslot, u64
start, u64 end,
double height,
const char *type,
int fd,
int err,
int merges)
164 fprintf(
svgfile,
"<title>fd=%d error=%d merges=%d</title>\n", fd, err, merges);
165 fprintf(
svgfile,
"<rect x=\"%.8f\" width=\"%.8f\" y=\"%.1f\" height=\"%.1f\" class=\"%s\"/>\n",
174 void svg_lbox(
int Yslot, u64
start, u64 end,
double height,
const char *type,
int fd,
int err,
int merges)
183 fprintf(
svgfile,
"<title>fd=%d error=%d merges=%d</title>\n", fd, err, merges);
184 fprintf(
svgfile,
"<rect x=\"%.8f\" width=\"%.8f\" y=\"%.1f\" height=\"%.1f\" class=\"%s\"/>\n",
193 void svg_fbox(
int Yslot, u64
start, u64 end,
double height,
const char *type,
int fd,
int err,
int merges)
202 fprintf(
svgfile,
"<title>fd=%d error=%d merges=%d</title>\n", fd, err, merges);
203 fprintf(
svgfile,
"<rect x=\"%.8f\" width=\"%.8f\" y=\"%.1f\" height=\"%.1f\" class=\"%s\"/>\n",
217 fprintf(
svgfile,
"<rect x=\"%.8f\" width=\"%.8f\" y=\"%.1f\" height=\"%.1f\" class=\"%s\"/>\n",
228 fprintf(
svgfile,
"<title>#%d blocked %s</title>\n", cpu,
231 fprintf(
svgfile,
"<desc>Blocked on:\n%s</desc>\n", backtrace);
232 svg_box(Yslot, start, end,
"blocked");
250 fprintf(
svgfile,
"<title>#%d running %s</title>\n",
253 fprintf(
svgfile,
"<desc>Switched because:\n%s</desc>\n", backtrace);
254 fprintf(
svgfile,
"<rect x=\"%.8f\" width=\"%.8f\" y=\"%.1f\" height=\"%.1f\" class=\"%s\"/>\n",
260 text_size = text_size/2;
261 if (text_size > 1.25)
266 fprintf(
svgfile,
"<text x=\"%.8f\" y=\"%.8f\" font-size=\"%.8fpt\">%i</text>\n",
274 static char text[80];
278 if (duration < NSEC_PER_USEC)
281 if (duration < NSEC_PER_MSEC) {
282 sprintf(text,
"%.1f us", duration / (
double)NSEC_PER_USEC);
285 sprintf(text,
"%.1f ms", duration / (
double)NSEC_PER_MSEC);
301 if (end-start > 10 * NSEC_PER_MSEC)
316 fprintf(
svgfile,
"<desc>Waiting on:\n%s</desc>\n", backtrace);
317 fprintf(
svgfile,
"<rect x=\"0\" width=\"%.8f\" y=\"0\" height=\"%.1f\" class=\"%s\"/>\n",
320 fprintf(
svgfile,
"<text transform=\"rotate(90)\" font-size=\"%.8fpt\"> %s</text>\n",
327 static char cpu_m[255];
333 file = fopen(
"/proc/cpuinfo",
"r");
335 while (fgets(buf, 255, file)) {
336 if (strstr(buf,
"model name")) {
337 strncpy(cpu_m, &buf[13], 255);
345 file = fopen(
"/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies",
"r");
347 while (fgets(buf, 255, file)) {
349 freq = strtoull(buf, NULL, 10);
369 fprintf(
svgfile,
"<rect x=\"%.8f\" width=\"%.8f\" y=\"%.1f\" height=\"%.1f\" class=\"cpu\"/>\n",
374 sprintf(cpu_string,
"CPU %i", (
int)cpu);
375 fprintf(
svgfile,
"<text x=\"%.8f\" y=\"%.8f\">%s</text>\n",
378 fprintf(
svgfile,
"<text transform=\"translate(%.8f,%.8f)\" font-size=\"1.25pt\">%s</text>\n",
402 fprintf(
svgfile,
"<desc>Switched because:\n%s</desc>\n", backtrace);
403 fprintf(
svgfile,
"<rect x=\"0\" width=\"%.8f\" y=\"0\" height=\"%.1f\" class=\"%s\"/>\n",
412 fprintf(
svgfile,
"<text transform=\"rotate(90)\" font-size=\"%.8fpt\">%s</text>\n",
431 sprintf(style,
"c%i", type);
433 fprintf(
svgfile,
"<rect class=\"%s\" x=\"%.8f\" width=\"%.8f\" y=\"%.1f\" height=\"%.1f\"/>\n",
445 fprintf(
svgfile,
"<text x=\"%.8f\" y=\"%.8f\" font-size=\"%.8fpt\">C%i</text>\n",
453 static char buffer[1024];
454 unsigned long long Hz;
461 sprintf(buffer,
"%9lli", Hz);
464 sprintf(buffer,
" %6lli Mhz", (Hz+500)/1000);
467 sprintf(buffer,
" %6.2f Ghz", (Hz+5000.0)/1000000);
470 sprintf(buffer,
"Turbo");
487 fprintf(
svgfile,
"<line x1=\"%.8f\" x2=\"%.8f\" y1=\"%.1f\" y2=\"%.1f\" class=\"pstate\"/>\n",
489 fprintf(
svgfile,
"<text x=\"%.8f\" y=\"%.8f\" font-size=\"0.25pt\">%s</text>\n",
506 fprintf(
svgfile,
"<title>%s wakes up %s</title>\n",
508 desc2 ? desc2 :
"?");
511 fprintf(
svgfile,
"<desc>%s</desc>\n", backtrace);
515 fprintf(
svgfile,
"<line x1=\"%.8f\" y1=\"%.2f\" x2=\"%.8f\" y2=\"%.2f\" style=\"stroke:rgb(32,255,32);stroke-width:0.009\"/>\n",
518 fprintf(
svgfile,
"<g transform=\"translate(%.8f,%.8f)\"><text transform=\"rotate(90)\" font-size=\"0.02pt\">%s ></text></g>\n",
522 fprintf(
svgfile,
"<line x1=\"%.8f\" y1=\"%.2f\" x2=\"%.8f\" y2=\"%.2f\" style=\"stroke:rgb(32,255,32);stroke-width:0.009\"/>\n",
525 fprintf(
svgfile,
"<g transform=\"translate(%.8f,%.8f)\"><text transform=\"rotate(90)\" font-size=\"0.02pt\">%s ></text></g>\n",
526 time2pixels(start), row2 * SLOT_MULT - SLOT_MULT/32, desc1);
530 fprintf(
svgfile,
"<line x1=\"%.8f\" y1=\"%.2f\" x2=\"%.8f\" y2=\"%.2f\" style=\"stroke:rgb(32,255,32);stroke-width:0.009\"/>\n",
533 fprintf(
svgfile,
"<g transform=\"translate(%.8f,%.8f)\"><text transform=\"rotate(90)\" font-size=\"0.02pt\">%s <</text></g>\n",
537 fprintf(
svgfile,
"<line x1=\"%.8f\" y1=\"%.2f\" x2=\"%.8f\" y2=\"%.2f\" style=\"stroke:rgb(32,255,32);stroke-width:0.009\"/>\n",
540 fprintf(
svgfile,
"<g transform=\"translate(%.8f,%.8f)\"><text transform=\"rotate(90)\" font-size=\"0.02pt\">%s <</text></g>\n",
548 fprintf(
svgfile,
"<circle cx=\"%.8f\" cy=\"%.2f\" r = \"0.01\" style=\"fill:rgb(32,255,32)\"/>\n",
565 fprintf(
svgfile,
"<desc>%s</desc>\n", backtrace);
568 fprintf(
svgfile,
"<line x1=\"%.8f\" y1=\"%.2f\" x2=\"%.8f\" y2=\"%.2f\" style=\"stroke:rgb(32,255,32);stroke-width:0.009\"/>\n",
571 fprintf(
svgfile,
"<line x1=\"%.8f\" y1=\"%.2f\" x2=\"%.8f\" y2=\"%.2f\" style=\"stroke:rgb(32,255,32);stroke-width:0.009\"/>\n",
577 fprintf(
svgfile,
"<circle cx=\"%.8f\" cy=\"%.2f\" r = \"0.01\" style=\"fill:rgb(32,255,32)\"/>\n",
590 fprintf(
svgfile,
"<title>Wakeup from interrupt</title>\n");
593 fprintf(
svgfile,
"<desc>%s</desc>\n", backtrace);
595 fprintf(
svgfile,
"<circle cx=\"%.8f\" cy=\"%.2f\" r = \"0.01\" style=\"fill:rgb(255,128,128)\"/>\n",
597 fprintf(
svgfile,
"<circle cx=\"%.8f\" cy=\"%.2f\" r = \"0.01\" style=\"fill:rgb(255,128,128)\"/>\n",
608 fprintf(
svgfile,
"<text x=\"%.8f\" y=\"%.8f\">%s</text>\n",
617 fprintf(
svgfile,
"<rect x=\"%i\" width=\"%.8f\" y=\"0\" height=\"%.1f\" class=\"%s\"/>\n",
618 X, boxsize, boxsize, style);
619 fprintf(
svgfile,
"<text transform=\"translate(%.8f, %.8f)\" font-size=\"%.8fpt\">%s</text>\n",
620 X + boxsize + 5, boxsize, 0.8 * boxsize, text);
663 double thickness = 0.075;
664 if ((i % 100000000) == 0) {
668 if ((i % 1000000000) == 0) {
673 if (thickness >= min_thickness)
674 fprintf(
svgfile,
"<line x1=\"%.8f\" y1=\"%.2f\" x2=\"%.8f\" y2=\"%" PRIu64
"\" style=\"stroke:rgb(%i,%i,%i);stroke-width:%.3f\"/>\n",
691 #define cpumask_bits(maskp) ((maskp)->bits) 710 for_each_set_bit(thr,
725 for_each_set_bit(cpu,
742 for (i = 0; i < m->
nr; i++) {
758 char *sib_thr,
int sib_thr_nr)
769 fprintf(stderr,
"topology: no memory\n");
775 fprintf(stderr,
"topology: can't parse siblings map\n");
779 sib_core += strlen(sib_core) + 1;
784 fprintf(stderr,
"topology: can't parse siblings map\n");
788 sib_thr += strlen(sib_thr) + 1;
793 fprintf(stderr,
"topology: no memory\n");
void svg_time_grid(double min_thickness)
void svg_cpu_box(int cpu, u64 __max_freq, u64 __turbo_freq)
void svg_waiting(int Yslot, int cpu, u64 start, u64 end, const char *backtrace)
void svg_box(int Yslot, u64 start, u64 end, const char *type)
#define cpumask_bits(maskp)
void svg_text(int Yslot, u64 start, const char *text)
void svg_wakeline(u64 start, int row1, int row2, const char *backtrace)
void svg_fbox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges)
static char * HzToHuman(unsigned long hz)
static double round_text_size(double size)
static double time2pixels(u64 __time)
x86 movsq based memset() in arch/x86/lib/memset_64.S") MEMSET_FN(memset_erms
void svg_cstate(int cpu, u64 start, u64 end, int type)
static char * time_to_string(u64 duration)
void svg_pstate(int cpu, u64 start, u64 end, u64 freq)
void cpu_map__put(struct cpu_map *map)
void open_svg(const char *filename, int cpus, int rows, u64 start, u64 end)
void svg_partial_wakeline(u64 start, int row1, char *desc1, int row2, char *desc2, const char *backtrace)
static double cpu2y(int cpu)
void svg_lbox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges)
void svg_interrupt(u64 start, int row, const char *backtrace)
static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS)
void svg_blocked(int Yslot, int cpu, u64 start, u64 end, const char *backtrace)
void svg_io_legenda(void)
const char * svg_highlight_name
int svg_build_topology_map(char *sib_core, int sib_core_nr, char *sib_thr, int sib_thr_nr)
static double cpu2slot(int cpu)
void svg_running(int Yslot, int cpu, u64 start, u64 end, const char *backtrace)
static int * topology_map
static double normalize_height(double height)
void svg_ubox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges)
void svg_process(int cpu, u64 start, u64 end, int pid, const char *name, const char *backtrace)
static void scan_thread_topology(int *map, struct topology *t, int cpu, int *pos)
static u64 turbo_frequency
static int str_to_bitmap(char *s, cpumask_t *b)
static char * cpu_model(void)
static void svg_legenda_box(int X, const char *text, const char *style)
static void scan_core_topology(int *map, struct topology *t)
struct cpu_map * cpu_map__new(const char *cpu_list)