]> git.sesse.net Git - ffmpeg/blobdiff - libavutil/timer.h
Merge commit '04f3bd349651694f30feeb8c4ed9bc58106fca54'
[ffmpeg] / libavutil / timer.h
index da0761b607c242cb5160076bbf41a608a60cb670..f7ab455df22fecae6c2af6e662e6e4503bd869d2 100644 (file)
 #ifndef AVUTIL_TIMER_H
 #define AVUTIL_TIMER_H
 
+#include "config.h"
+
+#if CONFIG_LINUX_PERF
+# ifndef _GNU_SOURCE
+#  define _GNU_SOURCE
+# endif
+# include <unistd.h> // read(3)
+# include <sys/ioctl.h>
+# include <asm/unistd.h>
+# include <linux/perf_event.h>
+#endif
+
 #include <stdlib.h>
 #include <stdint.h>
 #include <inttypes.h>
 
-#include "config.h"
-
 #if HAVE_MACH_MACH_TIME_H
 #include <mach/mach_time.h>
 #endif
         }                                                                 \
     }
 
-#ifdef AV_READ_TIME
+#if CONFIG_LINUX_PERF
+
+#define START_TIMER                                                         \
+    static int linux_perf_fd;                                               \
+    uint64_t tperf;                                                         \
+    if (!linux_perf_fd) {                                                   \
+        struct perf_event_attr attr = {                                     \
+            .type           = PERF_TYPE_HARDWARE,                           \
+            .size           = sizeof(struct perf_event_attr),               \
+            .config         = PERF_COUNT_HW_CPU_CYCLES,                     \
+            .disabled       = 1,                                            \
+            .exclude_kernel = 1,                                            \
+            .exclude_hv     = 1,                                            \
+        };                                                                  \
+        linux_perf_fd = syscall(__NR_perf_event_open, &attr,                \
+                                0, -1, -1, 0);                              \
+    }                                                                       \
+    if (linux_perf_fd == -1) {                                              \
+        av_log(NULL, AV_LOG_ERROR, "perf_event_open failed: %s\n",          \
+               av_err2str(AVERROR(errno)));                                 \
+    } else {                                                                \
+        ioctl(linux_perf_fd, PERF_EVENT_IOC_RESET, 0);                      \
+        ioctl(linux_perf_fd, PERF_EVENT_IOC_ENABLE, 0);                     \
+    }
+
+#define STOP_TIMER(id)                                                      \
+    ioctl(linux_perf_fd, PERF_EVENT_IOC_DISABLE, 0);                        \
+    read(linux_perf_fd, &tperf, sizeof(tperf));                             \
+    TIMER_REPORT(id, tperf)
+
+#elif defined(AV_READ_TIME)
 #define START_TIMER                             \
     uint64_t tend;                              \
     uint64_t tstart = AV_READ_TIME();           \