#define COMP(m) do { \ if (s1->m != s2->m) { \
pr_debug("Samples differ at '"#m"'\n"); \ returnfalse; \
} \
} while (0)
#define MCOMP(m) do { \ if (memcmp(&s1->m, &s2->m, sizeof(s1->m))) { \
pr_debug("Samples differ at '"#m"'\n"); \ returnfalse; \
} \
} while (0)
/* * Hardcode the expected values for branch_entry flags. * These are based on the input value (213) specified * in branch_stack variable.
*/ #define BS_EXPECTED_BE 0xa000d00000000000 #define BS_EXPECTED_LE 0x1aa00000000 #define FLAG(s) s->branch_stack->entries[i].flags
if (type & PERF_SAMPLE_TID) {
COMP(pid);
COMP(tid);
}
if (type & PERF_SAMPLE_TIME)
COMP(time);
if (type & PERF_SAMPLE_ADDR)
COMP(addr);
if (type & PERF_SAMPLE_ID)
COMP(id);
if (type & PERF_SAMPLE_STREAM_ID)
COMP(stream_id);
if (type & PERF_SAMPLE_CPU)
COMP(cpu);
if (type & PERF_SAMPLE_PERIOD)
COMP(period);
if (type & PERF_SAMPLE_READ) { if (read_format & PERF_FORMAT_GROUP)
COMP(read.group.nr); else
COMP(read.one.value); if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
COMP(read.time_enabled); if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
COMP(read.time_running); /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */ if (read_format & PERF_FORMAT_GROUP) { for (i = 0; i < s1->read.group.nr; i++) { /* FIXME: check values without LOST */ if (read_format & PERF_FORMAT_LOST)
MCOMP(read.group.values[i]);
}
} else {
COMP(read.one.id); if (read_format & PERF_FORMAT_LOST)
COMP(read.one.lost);
}
}
if (type & PERF_SAMPLE_CALLCHAIN) {
COMP(callchain->nr); for (i = 0; i < s1->callchain->nr; i++)
COMP(callchain->ips[i]);
}
if (type & PERF_SAMPLE_RAW) {
COMP(raw_size); if (memcmp(s1->raw_data, s2->raw_data, s1->raw_size)) {
pr_debug("Samples differ at 'raw_data'\n"); returnfalse;
}
}
if (type & PERF_SAMPLE_BRANCH_STACK) {
COMP(branch_stack->nr);
COMP(branch_stack->hw_idx); for (i = 0; i < s1->branch_stack->nr; i++) { if (needs_swap) return ((host_is_bigendian()) ?
(FLAG(s2).value == BS_EXPECTED_BE) :
(FLAG(s2).value == BS_EXPECTED_LE)); else
MCOMP(branch_stack->entries[i]);
}
}
/* The data does not contain 0xff so we use that to check the size */ for (i = bufsz; i > 0; i--) { if (*(i - 1 + (u8 *)event) != 0xff) break;
} if (i != sz) {
pr_debug("Event size mismatch: actual %zu vs expected %zu\n",
i, sz); goto out_free;
}
if (!samples_same(&sample, &sample_out_endian, sample_type, read_format, evsel.needs_swap)) {
pr_debug("parsing failed for sample_type %#"PRIx64"\n",
sample_type); goto out_free;
}
}
ret = 0;
out_free:
free(event);
perf_sample__exit(&sample_out_endian);
perf_sample__exit(&sample_out); if (ret && read_format)
pr_debug("read_format %#"PRIx64"\n", read_format); return ret;
}
/** * test__sample_parsing - test sample parsing. * * This function implements a test that synthesizes a sample event, parses it * and then checks that the parsed sample matches the original sample. The test * checks sample format bits separately and together. If the test passes %0 is * returned, otherwise %-1 is returned.
*/ staticint test__sample_parsing(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
{ const u64 rf[] = {4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 28, 29, 30, 31};
u64 sample_type;
u64 sample_regs;
size_t i; int err;
/* * Fail the test if it has not been updated when new sample format bits * were added. Please actually update the test rather than just change * the condition below.
*/ if (PERF_SAMPLE_MAX > PERF_SAMPLE_WEIGHT_STRUCT << 1) {
pr_debug("sample format has changed, some new PERF_SAMPLE_ bit was introduced - test needs updating\n"); return -1;
}
/* Test each sample format bit separately */ for (sample_type = 1; sample_type != PERF_SAMPLE_MAX;
sample_type <<= 1) { /* Test read_format variations */ if (sample_type == PERF_SAMPLE_READ) { for (i = 0; i < ARRAY_SIZE(rf); i++) {
err = do_test(sample_type, 0, rf[i]); if (err) return err;
} continue;
}
sample_regs = 0;
if (sample_type == PERF_SAMPLE_REGS_USER)
sample_regs = 0x3fff;
if (sample_type == PERF_SAMPLE_REGS_INTR)
sample_regs = 0xff0fff;
err = do_test(sample_type, sample_regs, 0); if (err) return err;
}
/* * Test all sample format bits together * Note: PERF_SAMPLE_WEIGHT and PERF_SAMPLE_WEIGHT_STRUCT cannot * be set simultaneously.
*/
sample_type = (PERF_SAMPLE_MAX - 1) & ~PERF_SAMPLE_WEIGHT;
sample_regs = 0x3fff; /* shared yb intr and user regs */ for (i = 0; i < ARRAY_SIZE(rf); i++) {
err = do_test(sample_type, sample_regs, rf[i]); if (err) return err;
}
sample_type = (PERF_SAMPLE_MAX - 1) & ~PERF_SAMPLE_WEIGHT_STRUCT; for (i = 0; i < ARRAY_SIZE(rf); i++) {
err = do_test(sample_type, sample_regs, rf[i]); if (err) return err;
}
return 0;
}
DEFINE_SUITE("Sample parsing", sample_parsing);
Messung V0.5
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.