summaryrefslogtreecommitdiff
path: root/test/test_perfmon_cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/test_perfmon_cpu.c')
-rw-r--r--test/test_perfmon_cpu.c29
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);