summaryrefslogtreecommitdiffstats
path: root/llvm/include/pmu/pmu-utils.h
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/include/pmu/pmu-utils.h')
-rw-r--r--llvm/include/pmu/pmu-utils.h106
1 files changed, 106 insertions, 0 deletions
diff --git a/llvm/include/pmu/pmu-utils.h b/llvm/include/pmu/pmu-utils.h
new file mode 100644
index 0000000..5e3e014
--- /dev/null
+++ b/llvm/include/pmu/pmu-utils.h
@@ -0,0 +1,106 @@
+/*
+ * (C) 2018 by Computer System Laboratory, IIS, Academia Sinica, Taiwan.
+ * See COPYRIGHT in top-level directory.
+ */
+
+#ifndef __PMU_UTILS_H
+#define __PMU_UTILS_H
+
+#include <unistd.h>
+#include <string.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/syscall.h>
+#include "perf_event.h"
+
+#ifndef ACCESS_ONCE
+#define ACCESS_ONCE(x) (*(volatile decltype(x) *)&(x))
+#endif
+
+namespace pmu {
+
+static inline int sys_perf_event_open(struct perf_event_attr *attr, pid_t pid,
+ int cpu, int group_fd,
+ unsigned long flags) {
+ return syscall(__NR_perf_event_open, attr, pid, cpu, group_fd, flags);
+}
+
+static inline void perf_attr_init(struct perf_event_attr *attr, int type,
+ int config) {
+ memset(attr, 0, sizeof(struct perf_event_attr));
+ attr->type = type;
+ attr->config = config;
+ attr->size = sizeof(struct perf_event_attr);
+ attr->disabled = 1;
+ attr->exclude_kernel = 1;
+ attr->exclude_guest = 1;
+ attr->exclude_hv = 1;
+}
+
+static inline int perf_event_start(int fd) {
+ return ioctl(fd, PERF_EVENT_IOC_ENABLE, 0);
+}
+
+static inline int perf_event_stop(int fd) {
+ return ioctl(fd, PERF_EVENT_IOC_DISABLE, 0);
+}
+
+static inline int perf_event_reset(int fd) {
+ return ioctl(fd, PERF_EVENT_IOC_RESET, 0);
+}
+
+static inline int perf_event_set_filter(int fd, const char *arg) {
+ return ioctl(fd, PERF_EVENT_IOC_SET_FILTER, (void *)arg);
+}
+
+static inline uint64_t perf_read_data_head(void *header) {
+ struct perf_event_mmap_page *pc = (struct perf_event_mmap_page *)header;
+ uint64_t head = ACCESS_ONCE(pc->data_head);
+ pmu_rmb();
+ return head;
+}
+
+static inline void perf_write_data_tail(void *header, uint64_t val) {
+ struct perf_event_mmap_page *pc = (struct perf_event_mmap_page *)header;
+ pmu_mb();
+ pc->data_tail = val;
+}
+
+static inline uint64_t perf_read_aux_head(void *header) {
+ struct perf_event_mmap_page *pc = (struct perf_event_mmap_page *)header;
+ uint64_t head = ACCESS_ONCE(pc->aux_head);
+ pmu_rmb();
+ return head;
+}
+
+static inline void perf_write_aux_tail(void *header, uint64_t val) {
+ struct perf_event_mmap_page *pc = (struct perf_event_mmap_page *)header;
+ pmu_mb();
+ pc->aux_tail = val;
+}
+
+static inline int isPowerOf2(uint64_t value) {
+ if (!value)
+ return 0;
+ return !(value & (value - 1));
+}
+
+/* Convert system errno to PMU error code. */
+static inline int ErrorCode(int err)
+{
+ switch (err) {
+ case EPERM:
+ case EACCES: return PMU_EPERM;
+ case ENOMEM: return PMU_ENOMEM;
+ default: return PMU_EEVENT;
+ }
+}
+
+} /* namespace pmu */
+
+#endif /* __PMU_UTILS_H */
+
+/*
+ * vim: ts=8 sts=4 sw=4 expandtab
+ */
OpenPOWER on IntegriCloud