diff options
author | Yogesh Tillu <yogesh.tillu@linaro.org> | 2015-06-02 12:31:23 +0530 |
---|---|---|
committer | Yogesh Tillu <yogesh.tillu@linaro.org> | 2015-06-02 18:07:14 +0530 |
commit | b71f2bcc165a0aebcfb92742277238bf609c4b30 (patch) | |
tree | bc4cb3aeba8996168a846c6758d21e7025d9ad69 | |
parent | 3c6a1546e5de8da60181bb14954c63f16a035245 (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.c | 32 | ||||
-rw-r--r-- | perf_rc_mmap.c | 31 |
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); |