FFmpeg
Loading...
Searching...
No Matches
linux.c
Go to the documentation of this file.
1/*
2 * Copyright © 2025, Niklas Haas
3 * Copyright © 2018, VideoLAN and dav1d authors
4 * Copyright © 2018, Two Orioles, LLC
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice, this
11 * list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following disclaimer in the documentation
15 * and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include "checkasm_config.h"
30
31#if HAVE_LINUX_PERF
32
33 #ifndef _GNU_SOURCE
34 #define _GNU_SOURCE
35 #endif
36
37 #include <linux/perf_event.h>
38 #include <sys/ioctl.h>
39 #include <sys/syscall.h>
40 #include <unistd.h>
41
42 #if HAVE_PTHREAD_SETAFFINITY_NP
43 #include <pthread.h>
44 #endif
45
46 #include "internal.h"
47
48static int perf_sysfd = -1;
49
50/* The pinned CPU index, or -1 unless the thread is pinned to one CPU */
51static int get_pinned_cpu(void)
52{
53#if HAVE_PTHREAD_SETAFFINITY_NP && defined(CPU_SET)
54 cpu_set_t mask;
55 int cpu = -1;
56
57 if (pthread_getaffinity_np(pthread_self(), sizeof(mask), &mask))
58 return -1;
59
60 for (int i = 0; i < CPU_SETSIZE; i++) {
61 if (!CPU_ISSET(i, &mask))
62 continue;
63 if (cpu >= 0)
64 return -1;
65 cpu = i;
66 }
67
68 return cpu;
69#else
70 return -1;
71#endif
72}
73
74static uint64_t perf_start(void)
75{
76 ioctl(perf_sysfd, PERF_EVENT_IOC_RESET, 0);
77 ioctl(perf_sysfd, PERF_EVENT_IOC_ENABLE, 0);
78 return 0;
79}
80
81static uint64_t perf_stop(uint64_t t)
82{
83 ioctl(perf_sysfd, PERF_EVENT_IOC_DISABLE, 0);
84 long ret = read(perf_sysfd, &t, sizeof(t));
85 (void) ret;
86 return t;
87}
88
90{
91 struct perf_event_attr attr = {
92 .type = PERF_TYPE_HARDWARE,
93 .size = sizeof(struct perf_event_attr),
94 .config = PERF_COUNT_HW_CPU_CYCLES,
95 .disabled = 1, // start counting only on demand
96 .exclude_kernel = 1,
97 .exclude_hv = 1,
98#if !ARCH_X86
99 .exclude_guest = 1,
100#endif
101 };
102
103 if (perf_sysfd == -1) {
104 perf_sysfd = (int) syscall(SYS_perf_event_open, &attr, /*pid*/ 0,
105 get_pinned_cpu(), /*group_fd*/ -1,
106 /*flags*/ 0);
107 if (perf_sysfd == -1) {
108 perror("perf_event_open");
109 return 1;
110 }
111 }
112
113 perf->start = perf_start;
114 perf->stop = perf_stop;
115 perf->name = "linux (perf)";
116 perf->unit = "tick";
118}
119
120#endif /* HAVE_LINUX_PERF */
static uint32_t BS_FUNC read(BSCTX *bc, unsigned int n)
Return n bits from the buffer, n has to be in the 0-32 range.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
const CheckasmCpuInfo * cpu
Definition checkasm.c:82
static const uint16_t mask[17]
Definition lzw.c:38
uint64_t(* start)(void)
Start timing measurement.
Definition test.h:534
const char * unit
Unit of measurement (e.g., "ns", "cycles")
Definition test.h:547
const char * name
Name of the timing mechanism (e.g., "clock_gettime")
Definition test.h:544
uint64_t(* stop)(uint64_t start_time)
Stop timing measurement.
Definition test.h:541
int checkasm_perf_init_linux(CheckasmPerf *perf)
int checkasm_perf_validate_start_stop(const CheckasmPerf *perf)
Definition perf.c:150
#define COLD
Definition internal.h:45