Quoting Tvrtko Ursulin (2019-02-08 10:26:12) > +static unsigned int json_indent_level; > + > +static const char *json_indent[] = { > + "", > + "\t", > + "\t\t", > + "\t\t\t", > + "\t\t\t\t", > + "\t\t\t\t\t", > +}; > + > +#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0])) > + > +static unsigned int json_prev_struct_members; > +static unsigned int json_struct_members; > + > +static void > +json_open_struct(const char *name) > +{ > + assert(json_indent_level < ARRAY_SIZE(json_indent)); > + > + json_prev_struct_members = json_struct_members; > + json_struct_members = 0; > + > + if (name) > + printf("%s%s\"%s\": {\n", > + json_prev_struct_members ? ",\n" : "", > + json_indent[json_indent_level], > + name); "%*s", json_indent_level, "\t\t\t\t\t\t" Ok, that seems to tally with what I expect the output to look like. > +static unsigned int stdout_level; Ah, stdout == plain old output. > +static int > +print_header(struct engines *engines, double t, > + int lines, int con_w, int con_h, bool *consumed) > +{ > + struct pmu_counter fake_pmu = { > + .present = true, > + .val.cur = 1, > + }; > + struct cnt_item period_items[] = { > + { &fake_pmu, 0, 0, 1.0, 1.0, t * 1e3, "duration" }, > + { NULL, 0, 0, 0.0, 0.0, 0.0, "unit", "ms" }, > + { }, > + }; > + struct cnt_group period_group = { > + .name = "period", > + .items = period_items, > + }; > + struct cnt_item freq_items[] = { > + { &engines->freq_req, 4, 0, 1.0, t, 1, "requested", "req" }, > + { &engines->freq_act, 4, 0, 1.0, t, 1, "actual", "act" }, > + { NULL, 0, 0, 0.0, 0.0, 0.0, "unit", "MHz" }, > + { }, > + }; > + struct cnt_group freq_group = { > + .name = "frequency", > + .display_name = "Freq MHz", > + .items = freq_items, > + }; > + struct cnt_item irq_items[] = { > + { &engines->irq, 8, 0, 1.0, t, 1, "count", "/s" }, > + { NULL, 0, 0, 0.0, 0.0, 0.0, "unit", "irq/s" }, > + { }, > + }; > + struct cnt_group irq_group = { > + .name = "interrupts", > + .display_name = "IRQ", > + .items = irq_items, > + }; > + struct cnt_item rc6_items[] = { > + { &engines->rc6, 3, 0, 1e9, t, 100, "value", "%" }, > + { NULL, 0, 0, 0.0, 0.0, 0.0, "unit", "%" }, > + { }, > + }; > + struct cnt_group rc6_group = { > + .name = "rc6", > + .display_name = "RC6", > + .items = rc6_items, > + }; > + struct cnt_item power_items[] = { > + { &engines->rapl, 4, 2, 1.0, t, engines->rapl_scale, "value", > + "W" }, > + { NULL, 0, 0, 0.0, 0.0, 0.0, "unit", "W" }, > + { }, > + }; > + struct cnt_group power_group = { > + .name = "power", > + .display_name = "Power", > + .items = power_items, > + }; > + struct cnt_group *groups[] = { > + &period_group, > + &freq_group, > + &irq_group, > + &rc6_group, > + &power_group, > + NULL > + }; > + > + if (output_mode != JSON) > + memmove(&groups[0], &groups[1], > + sizeof(groups) - sizeof(groups[0])); > + > + pops->open_struct(NULL); > + > + *consumed = print_groups(groups); > + > + if (output_mode == INTERACTIVE) { > + printf("\033[H\033[J"); > + > + if (lines++ < con_h) > + printf("intel-gpu-top - %s/%s MHz; %s%% RC6; %s %s; %s irqs/s\n", > + freq_items[1].buf, freq_items[0].buf, > + rc6_items[0].buf, power_items[0].buf, > + engines->rapl_unit, > + irq_items[0].buf); I would suggest a timestamp (time of day) if room. Hang on, I don't recall seeing a timestamp amongst the output? Looks very, very neat. -Chris _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx