runners: bench: Added best effort --list-probes, --list-case-probes, etc
Adds a set of flags to query the bench_runner for available probes: - --list-probes - List estimated probes - --list-suite-probes - List estimated probes for each bench suite - --list-case-probes - List estimated probes for each bench case What's fun though, is we don't actually know the bench probes at compile time, since the BENCH_* macros take a C string. But we're already preprocessing bench_*.toml with Python, so guessing what probes are available is easy with a bit of regex: BENCH_(?:STOP|F?RESULT)\( *"((?:\\.|[^"])*)" This does make the --list*probes flags best effort, but I think unlikely to break in practice.
This commit is contained in:
+194
-13
@@ -1552,9 +1552,9 @@ static void list_suite_paths(void) {
|
||||
|| strcmp(bench_ids[t].name,
|
||||
bench_suites[i]->cases[j].name) == 0)) {
|
||||
continue;
|
||||
|
||||
cases += 1;
|
||||
}
|
||||
|
||||
cases += 1;
|
||||
}
|
||||
|
||||
// no benches found?
|
||||
@@ -1819,6 +1819,165 @@ static void list_implicit_defines(void) {
|
||||
free(defines.defines);
|
||||
}
|
||||
|
||||
static void list_probes(void) {
|
||||
// find relevant probes
|
||||
const char **probes = NULL;
|
||||
size_t probe_count = 0;
|
||||
size_t probe_capacity = 0;
|
||||
for (size_t t = 0; t < bench_id_count; t++) {
|
||||
for (size_t i = 0; i < bench_suite_count; i++) {
|
||||
for (size_t j = 0; j < bench_suites[i]->case_count; j++) {
|
||||
// does neither suite nor case name match?
|
||||
if (bench_ids[t].name && !(
|
||||
strcmp(bench_ids[t].name,
|
||||
bench_suites[i]->name) == 0
|
||||
|| strcmp(bench_ids[t].name,
|
||||
bench_suites[i]->cases[j].name) == 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// add unseen probes
|
||||
for (size_t p = 0;
|
||||
p < bench_suites[i]->cases[j].probe_count;
|
||||
p++) {
|
||||
for (size_t q = 0; q < probe_count; q++) {
|
||||
if (strcmp(probes[q],
|
||||
bench_suites[i]->cases[j].probes[p]) == 0) {
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
|
||||
const char **probe = mappend(
|
||||
(void**)&probes,
|
||||
sizeof(const char*),
|
||||
&probe_count,
|
||||
&probe_capacity);
|
||||
*probe = bench_suites[i]->cases[j].probes[p];
|
||||
}
|
||||
|
||||
next:;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t p = 0; p < probe_count; p++) {
|
||||
printf("%s\n", probes[p]);
|
||||
}
|
||||
|
||||
free(probes);
|
||||
}
|
||||
|
||||
static void list_suite_probes(void) {
|
||||
// at least size so that names fit
|
||||
unsigned name_width = 23;
|
||||
for (size_t i = 0; i < bench_suite_count; i++) {
|
||||
size_t len = strlen(bench_suites[i]->name);
|
||||
if (len > name_width) {
|
||||
name_width = len;
|
||||
}
|
||||
}
|
||||
name_width = 4*((name_width+1+4-1)/4)-1;
|
||||
|
||||
printf("%-*s %s\n", name_width, "suite", "probes");
|
||||
// find relevant probes
|
||||
for (size_t t = 0; t < bench_id_count; t++) {
|
||||
for (size_t i = 0; i < bench_suite_count; i++) {
|
||||
const char **probes = NULL;
|
||||
size_t probe_count = 0;
|
||||
size_t probe_capacity = 0;
|
||||
|
||||
for (size_t j = 0; j < bench_suites[i]->case_count; j++) {
|
||||
// does neither suite nor case name match?
|
||||
if (bench_ids[t].name && !(
|
||||
strcmp(bench_ids[t].name,
|
||||
bench_suites[i]->name) == 0
|
||||
|| strcmp(bench_ids[t].name,
|
||||
bench_suites[i]->cases[j].name) == 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// add unseen probes
|
||||
for (size_t p = 0;
|
||||
p < bench_suites[i]->cases[j].probe_count;
|
||||
p++) {
|
||||
for (size_t q = 0; q < probe_count; q++) {
|
||||
if (strcmp(probes[q],
|
||||
bench_suites[i]->cases[j].probes[p]) == 0) {
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
|
||||
const char **probe = mappend(
|
||||
(void**)&probes,
|
||||
sizeof(const char*),
|
||||
&probe_count,
|
||||
&probe_capacity);
|
||||
*probe = bench_suites[i]->cases[j].probes[p];
|
||||
}
|
||||
|
||||
next:;
|
||||
}
|
||||
|
||||
printf("%-*s ",
|
||||
name_width,
|
||||
bench_suites[i]->name);
|
||||
for (size_t p = 0; p < probe_count; p++) {
|
||||
printf("%s", probes[p]);
|
||||
if (p != probe_count-1) {
|
||||
printf(",");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
free(probes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void list_case_probes(void) {
|
||||
// at least size so that names fit
|
||||
unsigned name_width = 23;
|
||||
for (size_t i = 0; i < bench_suite_count; i++) {
|
||||
for (size_t j = 0; j < bench_suites[i]->case_count; j++) {
|
||||
size_t len = strlen(bench_suites[i]->cases[j].name);
|
||||
if (len > name_width) {
|
||||
name_width = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
name_width = 4*((name_width+1+4-1)/4)-1;
|
||||
|
||||
printf("%-*s %s\n", name_width, "case", "probes");
|
||||
// find relevant probes
|
||||
for (size_t t = 0; t < bench_id_count; t++) {
|
||||
for (size_t i = 0; i < bench_suite_count; i++) {
|
||||
for (size_t j = 0; j < bench_suites[i]->case_count; j++) {
|
||||
// does neither suite nor case name match?
|
||||
if (bench_ids[t].name && !(
|
||||
strcmp(bench_ids[t].name,
|
||||
bench_suites[i]->name) == 0
|
||||
|| strcmp(bench_ids[t].name,
|
||||
bench_suites[i]->cases[j].name) == 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("%-*s ",
|
||||
name_width,
|
||||
bench_suites[i]->cases[j].name);
|
||||
for (size_t p = 0;
|
||||
p < bench_suites[i]->cases[j].probe_count;
|
||||
p++) {
|
||||
printf("%s", bench_suites[i]->cases[j].probes[p]);
|
||||
if (p != bench_suites[i]->cases[j].probe_count-1) {
|
||||
printf(",");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// bench bd wrappers for heap/stack tracking
|
||||
@@ -2041,20 +2200,23 @@ enum opt_flags {
|
||||
OPT_LIST_DEFINES = 3,
|
||||
OPT_LIST_PERMUTATION_DEFINES = 4,
|
||||
OPT_LIST_IMPLICIT_DEFINES = 5,
|
||||
OPT_LIST_PROBES = 6,
|
||||
OPT_LIST_SUITE_PROBES = 7,
|
||||
OPT_LIST_CASE_PROBES = 8,
|
||||
OPT_DEFINE = 'D',
|
||||
OPT_DEFINE_DEPTH = 6,
|
||||
OPT_STEP = 7,
|
||||
OPT_FORCE = 8,
|
||||
OPT_NO_INTERNAL = 9,
|
||||
OPT_NO_LITMUS = 10,
|
||||
OPT_DEFINE_DEPTH = 9,
|
||||
OPT_STEP = 10,
|
||||
OPT_FORCE = 11,
|
||||
OPT_NO_INTERNAL = 12,
|
||||
OPT_NO_LITMUS = 13,
|
||||
OPT_DISK = 'd',
|
||||
OPT_TRACE = 't',
|
||||
OPT_TRACE_BACKTRACE = 11,
|
||||
OPT_TRACE_STEP = 12,
|
||||
OPT_TRACE_RUNFREQ = 13,
|
||||
OPT_READ_SLEEP = 14,
|
||||
OPT_PROG_SLEEP = 15,
|
||||
OPT_ERASE_SLEEP = 16,
|
||||
OPT_TRACE_BACKTRACE = 14,
|
||||
OPT_TRACE_STEP = 15,
|
||||
OPT_TRACE_RUNFREQ = 16,
|
||||
OPT_READ_SLEEP = 17,
|
||||
OPT_PROG_SLEEP = 18,
|
||||
OPT_ERASE_SLEEP = 19,
|
||||
};
|
||||
|
||||
const char *short_opts = "hYlLD:d:t:";
|
||||
@@ -2071,6 +2233,10 @@ const struct option long_opts[] = {
|
||||
no_argument, NULL, OPT_LIST_PERMUTATION_DEFINES},
|
||||
{"list-implicit-defines",
|
||||
no_argument, NULL, OPT_LIST_IMPLICIT_DEFINES},
|
||||
{"list-probes", no_argument, NULL, OPT_LIST_PROBES},
|
||||
{"list-suite-probes",
|
||||
no_argument, NULL, OPT_LIST_SUITE_PROBES},
|
||||
{"list-case-probes", no_argument, NULL, OPT_LIST_CASE_PROBES},
|
||||
{"define", required_argument, NULL, OPT_DEFINE},
|
||||
{"define-depth", required_argument, NULL, OPT_DEFINE_DEPTH},
|
||||
{"step", required_argument, NULL, OPT_STEP},
|
||||
@@ -2098,6 +2264,9 @@ const char *const help_text[] = {
|
||||
"List all defines in this bench-runner.",
|
||||
"List explicit defines in this bench-runner.",
|
||||
"List implicit defines in this bench-runner.",
|
||||
"List estimated probes.",
|
||||
"List estimated probes for each bench suite.",
|
||||
"List estimated probes for each bench case.",
|
||||
"Override a bench define.",
|
||||
"How deep to evaluate recursive defines before erroring.",
|
||||
"Comma-separated range of permutations to run.",
|
||||
@@ -2213,6 +2382,18 @@ int main(int argc, char **argv) {
|
||||
op = list_implicit_defines;
|
||||
break;
|
||||
|
||||
case OPT_LIST_PROBES:;
|
||||
op = list_probes;
|
||||
break;
|
||||
|
||||
case OPT_LIST_SUITE_PROBES:;
|
||||
op = list_suite_probes;
|
||||
break;
|
||||
|
||||
case OPT_LIST_CASE_PROBES:;
|
||||
op = list_case_probes;
|
||||
break;
|
||||
|
||||
// configuration
|
||||
case OPT_DEFINE:;
|
||||
// allocate space
|
||||
|
||||
Reference in New Issue
Block a user