summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYogesh Tillu <yogesh.tillu@linaro.org>2015-06-02 12:31:23 +0530
committerYogesh Tillu <yogesh.tillu@linaro.org>2015-06-02 18:07:14 +0530
commitb71f2bcc165a0aebcfb92742277238bf609c4b30 (patch)
treebc4cb3aeba8996168a846c6758d21e7025d9ad69
parent3c6a1546e5de8da60181bb14954c63f16a035245 (diff)
Counter overflow support is added for Tests.
Signed-off-by: Yogesh Tillu <yogesh.tillu@linaro.org> Reviewed-by: Anders Roxell <anders.roxell@linaro.org>
-rw-r--r--perf_ev_open.c32
-rw-r--r--perf_rc_mmap.c31
2 files changed, 63 insertions, 0 deletions
diff --git a/perf_ev_open.c b/perf_ev_open.c
index bfc2fcd..b8cf681 100644
--- a/perf_ev_open.c
+++ b/perf_ev_open.c
@@ -18,16 +18,40 @@
#include <linux/perf_event.h>
#include <getopt.h>
#include <math.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
static int fddev = -1;
+static int overflow;
+
+static void sigio_handler(int signo, siginfo_t *info, void *uc)
+{
+ overflow = overflow + 1;
+}
static int counter_init(unsigned int counter)
{
static struct perf_event_attr attr;
attr.type = PERF_TYPE_HARDWARE;
+ static struct sigaction sigio;
+
if (counter < 0 || counter > PERF_COUNT_HW_MAX)
return -1;
+ /* setup SIGIO signal handler */
+ memset(&sigio, 0, sizeof(struct sigaction));
+ sigio.sa_sigaction = (void *)sigio_handler;
+ sigio.sa_flags = SA_SIGINFO;
+
+ if (sigaction(SIGIO, &sigio, NULL) == -1) {
+ printf("Error: SIGIO signal handler %s\n",strerror(errno));
+ }
+
+ attr.sample_period = 1000000;
+ attr.sample_type = PERF_SAMPLE_IP;
+ attr.wakeup_events = 1;
attr.config = counter;
fddev = syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0);
if (fddev == -1) {
@@ -37,6 +61,9 @@ static int counter_init(unsigned int counter)
return -1;
}
+ fcntl(fddev, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC);
+ fcntl(fddev, F_SETSIG, SIGIO);
+ fcntl(fddev, F_SETOWN, getpid());
return 0;
}
@@ -111,6 +138,8 @@ int main(int ac, char *argv[])
a = malloc(len*sizeof(*a));
b = malloc(len*sizeof(*b));
+ ioctl(fddev, PERF_EVENT_IOC_RESET, 0);
+ ioctl(fddev, PERF_EVENT_IOC_ENABLE, 0);
for (i = 0; i < len; ++i) {
a[i] = i+128;
@@ -131,6 +160,7 @@ int main(int ac, char *argv[])
printf("\nsum=%d Avg count [ Loop + Read ] = %ld\n", sum,
pre_loop_res);
time_start = time_end = 0;
+ ioctl(fddev, PERF_EVENT_IOC_RESET, 0);
/* --------------------Critical section-------------- */
time_start = cpucycles();
for (i = 0; i < 1000; i++)
@@ -138,11 +168,13 @@ int main(int ac, char *argv[])
time_end = cpucycles();
/* ---------------------------------- */
+ ioctl(fddev, PERF_EVENT_IOC_DISABLE, 0);
post_loop_res = abs(time_end-time_start)/1000;
printf("sum=%d Avg count [ Loop ] = %ld\n", sum,
post_loop_res);
printf("\n--------------------------------------------------------\n");
printf("\tDelay[cpucycles]=%d\n", abs(post_loop_res - pre_loop_res));
+ printf("\tNumber of time overflow happens=%d\n", overflow);
printf("\n--------------------------------------------------------\n");
free(a);
free(b);
diff --git a/perf_rc_mmap.c b/perf_rc_mmap.c
index 79d76ec..34dab28 100644
--- a/perf_rc_mmap.c
+++ b/perf_rc_mmap.c
@@ -22,20 +22,41 @@
#include <string.h>
#include <getopt.h>
#include <math.h>
+#include <signal.h>
+#include <fcntl.h>
#define barrier() asm volatile("dmb ish" : : : "memory")
#define isb() asm volatile("isb" : : : "memory")
#define ARMV8_PMCNTENSET_EL0_ENABLE (1<<31) /**< Enable Perf count reg */
static int fddev = -1;
static unsigned long page_size;
+static int overflow;
+
+static void sigio_handler(int signo, siginfo_t *info, void *uc)
+{
+ overflow = overflow + 1;
+}
static int counter_init(unsigned int counter)
{
static struct perf_event_attr attr;
+ static struct sigaction sigio;
attr.type = PERF_TYPE_HARDWARE;
if (counter < 0 || counter > PERF_COUNT_HW_MAX)
return -1;
+ /* setup SIGIO signal handler */
+ memset(&sigio, 0, sizeof(struct sigaction));
+ sigio.sa_sigaction = (void *)sigio_handler;
+ sigio.sa_flags = SA_SIGINFO;
+
+ if (sigaction(SIGIO, &sigio, NULL) == -1) {
+ printf("Error: SIGIO signal handler %s\n",strerror(errno));
+ }
+
+ attr.sample_period = 1000000;
+ attr.sample_type = PERF_SAMPLE_IP;
+ attr.wakeup_events = 1;
attr.config = counter;
fddev = syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0);
if (fddev == -1) {
@@ -45,6 +66,9 @@ static int counter_init(unsigned int counter)
return -1;
}
+ fcntl(fddev, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC);
+ fcntl(fddev, F_SETSIG, SIGIO);
+ fcntl(fddev, F_SETOWN, getpid());
return 0;
}
@@ -144,6 +168,9 @@ int main(int ac, char *argv[])
a = malloc(len*sizeof(*a));
b = malloc(len*sizeof(*b));
+ ioctl(fddev, PERF_EVENT_IOC_RESET, 0);
+ ioctl(fddev, PERF_EVENT_IOC_ENABLE, 0);
+
for (i = 0; i < len; ++i) {
a[i] = i+128;
b[i] = i+64;
@@ -152,6 +179,7 @@ int main(int ac, char *argv[])
page_size = sysconf(_SC_PAGESIZE);
/*Allocate memory for the page size */
addr = mmap(NULL, page_size, PROT_READ, MAP_SHARED, fddev, 0);
+
if (addr == (void *)(-1)) {
printf("Error: mmap() syscall returned with (%s)\n",
strerror(errno));
@@ -161,6 +189,7 @@ int main(int ac, char *argv[])
i = 0;
start_count = stop_count = 0;
+ ioctl(fddev, PERF_EVENT_IOC_RESET, 0);
/* --------------------Critical section-------------- */
start_count = mmap_read_self(addr);
for (i = 0; i < 1000; i++) {
@@ -180,12 +209,14 @@ int main(int ac, char *argv[])
sum = loop(a, b, len);
stop_count = mmap_read_self(addr);
+ ioctl(fddev, PERF_EVENT_IOC_DISABLE, 0);
/* --------------------End Critical section-------------- */
post_loop_res = abs(stop_count-start_count)/1000;
printf("sum=%d Avg count [ Loop ] = %ld\n", sum,
post_loop_res);
printf("\n--------------------------------------------------------\n");
printf("\tDelay[cpucycles]=%d\n", abs(post_loop_res - pre_loop_res));
+ printf("\tNumber of time overflow happens=%d\n", overflow);
printf("\n--------------------------------------------------------\n");
munmap(addr, page_size);
free(a);