#include <sys/types.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <locale.h>
#include <sys/ioctl.h>
#include <err.h>
#include <perfmon/pfmlib_perf_event.h>
#define N 30
static unsigned long
fib(unsigned long n)
{
if (n == 0)
return 0;
if (n == 1)
return 2;
return fib(n-1)+fib(n-2);
}
int
main(int argc, char **argv)
{
struct perf_event_attr attr;
int fd, ret;
uint64_t count = 0, values[3];
setlocale(LC_ALL, "");
ret = pfm_initialize();
if (ret != PFM_SUCCESS)
errx(1, "cannot initialize library: %s", pfm_strerror(ret));
memset(&attr, 0, sizeof(attr));
ret = pfm_get_perf_event_encoding("cycles:u", PFM_PLM0|PFM_PLM3, &attr, NULL, NULL);
if (ret != PFM_SUCCESS)
errx(1, "cannot find encoding: %s", pfm_strerror(ret));
attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED|PERF_FORMAT_TOTAL_TIME_RUNNING;
attr.disabled = 1;
fd = perf_event_open(&attr, getpid(), -1, -1, 0);
if (fd < 0)
err(1, "cannot create event");
ret = ioctl(fd, PERF_EVENT_IOC_ENABLE, 0);
if (ret)
err(1, "ioctl(enable) failed");
printf("Fibonacci(%d)=%lu\n", N, fib(N));
ret = ioctl(fd, PERF_EVENT_IOC_DISABLE, 0);
if (ret)
err(1, "ioctl(disable) failed");
ret = read(fd, values, sizeof(values));
if (ret != sizeof(values))
err(1, "cannot read results: %s", strerror(errno));
if (values[2])
count = (uint64_t)((double)values[0] * values[1]/values[2]);
printf("count=%'"PRIu64"\n", count);
close(fd);
pfm_terminate();
return 0;
}