1 /**
2  * Copyright (c) Glow Contributors. See CONTRIBUTORS file.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /**
18  * Contributed by Xperi Corporation on August 13, 2019
19  */
20 
21 #ifdef ENABLE_PERF_MONITORING
22 
23 #include <string.h>
24 #include <sys/ioctl.h>
25 
26 #include "x_perf_monitor.h"
27 
initPerfMonitoring(struct PerfData * pd)28 int initPerfMonitoring(struct PerfData *pd) {
29   int ret;
30 
31   memset(pd, 0x0, sizeof(struct PerfData));
32 
33   pd->pe.type = PERF_TYPE_HARDWARE;
34   pd->pe.size = sizeof(struct perf_event_attr);
35   pd->pe.config = PERF_COUNT_HW_CPU_CYCLES;
36   pd->pe.disabled = 1;
37   pd->pe.exclude_kernel = 1;
38   pd->pe.exclude_hv = 1;
39 
40   ret = syscall(__NR_perf_event_open, &(pd->pe), 0, -1, -1, 0);
41   pd->fd = ret;
42 
43   return ret;
44 }
45 
stopPerfMonitoring(struct PerfData * pd)46 int stopPerfMonitoring(struct PerfData *pd) {
47   if (pd->fd >= 0) {
48     close(pd->fd);
49   }
50 
51   return 0;
52 }
53 
pausePerfMonitoring(struct PerfData * pd)54 int pausePerfMonitoring(struct PerfData *pd) {
55   if (pd->fd >= 0) {
56     ioctl(pd->fd, PERF_EVENT_IOC_DISABLE, 0);
57   } else {
58     return pd->fd;
59   }
60 
61   return 0;
62 }
63 
resumePerfMonitoring(struct PerfData * pd)64 int resumePerfMonitoring(struct PerfData *pd) {
65   if (pd->fd >= 0) {
66     ioctl(pd->fd, PERF_EVENT_IOC_ENABLE, 0);
67   } else {
68     return pd->fd;
69   }
70 
71   return 0;
72 }
73 
resetPerfStatistics(struct PerfData * pd)74 int resetPerfStatistics(struct PerfData *pd) {
75   if (pd->fd >= 0) {
76     pd->ps.numCPUCycles = 0;
77     ioctl(pd->fd, PERF_EVENT_IOC_RESET, 0);
78   } else {
79     return pd->fd;
80   }
81 
82   return 0;
83 }
84 
readPerfStatistics(struct PerfData * pd)85 int readPerfStatistics(struct PerfData *pd) {
86   int ret = -1;
87 
88   if (pd->fd >= 0) {
89     ret = read(pd->fd, &(pd->ps.numCPUCycles), sizeof(pd->ps.numCPUCycles));
90   }
91 
92   return ret;
93 }
94 
95 #endif // ENABLE_PERF_MONITORING
96