diff options
Diffstat (limited to 'test/test_perfmon_cpu.c')
-rw-r--r-- | test/test_perfmon_cpu.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/test/test_perfmon_cpu.c b/test/test_perfmon_cpu.c index 8ecb241..6f1414c 100644 --- a/test/test_perfmon_cpu.c +++ b/test/test_perfmon_cpu.c @@ -49,17 +49,30 @@ test_report_event(const struct perfmon_event *event, const char *name) printf("test: %s: %llu\n", name, count); } +static uint64_t +test_get_pre_overflow_value(uint64_t value) +{ + uint64_t pmc_max; + unsigned int pmc_width; + + pmc_width = perfmon_get_pmc_width(); + pmc_max = (1ULL << pmc_width) - 1; + pmc_max &= 0xffffffff80000000; + + /* XXX: workaround most processor not allowing full width writes */ + return ((~value + 1) & 0x7fffffff) | pmc_max; +} + static void test_run(void *arg) { struct perfmon_event *ev_cycle, *ev_instruction; struct perfmon_group *group; int error; - uint64_t pmc_max; + uint64_t value; (void)arg; - pmc_max = (1 << perfmon_get_pmc_width()) - 1; error = perfmon_group_create(&group); error_check(error, "perfmon_group_create"); @@ -86,10 +99,14 @@ test_run(void *arg) test_report_event(ev_instruction, "instruction"); printf("checking with overflow ...\n"); - /* TODO: choose value depending of architecture */ - perfmon_event_write(ev_cycle, pmc_max - perfmon_event_read(ev_cycle) / 2); - perfmon_event_write(ev_instruction, - pmc_max - perfmon_event_read(ev_instruction) / 3); + value = test_get_pre_overflow_value( perfmon_event_read(ev_cycle) / 2); + error = perfmon_event_write(ev_cycle, value); + error_check(error, "perfmon_event_write"); + + value = test_get_pre_overflow_value(perfmon_event_read(ev_instruction) / 3); + error = perfmon_event_write(ev_instruction, value); + error_check(error, "perfmon_event_write"); + perfmon_event_reset(ev_cycle); perfmon_event_reset(ev_instruction); |