xref: /aosp_15_r20/system/extras/simpleperf/event_fd.h (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
1*288bf522SAndroid Build Coastguard Worker /*
2*288bf522SAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
3*288bf522SAndroid Build Coastguard Worker  *
4*288bf522SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*288bf522SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*288bf522SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*288bf522SAndroid Build Coastguard Worker  *
8*288bf522SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*288bf522SAndroid Build Coastguard Worker  *
10*288bf522SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*288bf522SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*288bf522SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*288bf522SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*288bf522SAndroid Build Coastguard Worker  * limitations under the License.
15*288bf522SAndroid Build Coastguard Worker  */
16*288bf522SAndroid Build Coastguard Worker 
17*288bf522SAndroid Build Coastguard Worker #ifndef SIMPLE_PERF_EVENT_FD_H_
18*288bf522SAndroid Build Coastguard Worker #define SIMPLE_PERF_EVENT_FD_H_
19*288bf522SAndroid Build Coastguard Worker 
20*288bf522SAndroid Build Coastguard Worker #include <sys/types.h>
21*288bf522SAndroid Build Coastguard Worker 
22*288bf522SAndroid Build Coastguard Worker #include <memory>
23*288bf522SAndroid Build Coastguard Worker #include <string>
24*288bf522SAndroid Build Coastguard Worker #include <vector>
25*288bf522SAndroid Build Coastguard Worker 
26*288bf522SAndroid Build Coastguard Worker #include <android-base/macros.h>
27*288bf522SAndroid Build Coastguard Worker 
28*288bf522SAndroid Build Coastguard Worker #include "IOEventLoop.h"
29*288bf522SAndroid Build Coastguard Worker #include "perf_event.h"
30*288bf522SAndroid Build Coastguard Worker 
31*288bf522SAndroid Build Coastguard Worker namespace simpleperf {
32*288bf522SAndroid Build Coastguard Worker 
33*288bf522SAndroid Build Coastguard Worker struct PerfCounter {
34*288bf522SAndroid Build Coastguard Worker   uint64_t value;         // The value of the event specified by the perf_event_file.
35*288bf522SAndroid Build Coastguard Worker   uint64_t time_enabled;  // The enabled time.
36*288bf522SAndroid Build Coastguard Worker   uint64_t time_running;  // The running time.
37*288bf522SAndroid Build Coastguard Worker   uint64_t id;            // The id of the perf_event_file.
38*288bf522SAndroid Build Coastguard Worker };
39*288bf522SAndroid Build Coastguard Worker 
40*288bf522SAndroid Build Coastguard Worker // EventFd represents an opened perf_event_file.
41*288bf522SAndroid Build Coastguard Worker class EventFd {
42*288bf522SAndroid Build Coastguard Worker  public:
43*288bf522SAndroid Build Coastguard Worker   static std::unique_ptr<EventFd> OpenEventFile(const perf_event_attr& attr, pid_t tid, int cpu,
44*288bf522SAndroid Build Coastguard Worker                                                 EventFd* group_event_fd,
45*288bf522SAndroid Build Coastguard Worker                                                 const std::string& event_name,
46*288bf522SAndroid Build Coastguard Worker                                                 bool report_error = true);
47*288bf522SAndroid Build Coastguard Worker 
48*288bf522SAndroid Build Coastguard Worker   virtual ~EventFd();
49*288bf522SAndroid Build Coastguard Worker 
50*288bf522SAndroid Build Coastguard Worker   // Give information about this perf_event_file, like (event_name, tid, cpu).
51*288bf522SAndroid Build Coastguard Worker   std::string Name() const;
52*288bf522SAndroid Build Coastguard Worker 
53*288bf522SAndroid Build Coastguard Worker   uint64_t Id() const;
54*288bf522SAndroid Build Coastguard Worker 
ThreadId()55*288bf522SAndroid Build Coastguard Worker   pid_t ThreadId() const { return tid_; }
56*288bf522SAndroid Build Coastguard Worker 
Cpu()57*288bf522SAndroid Build Coastguard Worker   int Cpu() const { return cpu_; }
58*288bf522SAndroid Build Coastguard Worker 
attr()59*288bf522SAndroid Build Coastguard Worker   const perf_event_attr& attr() const { return attr_; }
60*288bf522SAndroid Build Coastguard Worker 
61*288bf522SAndroid Build Coastguard Worker   // It tells the kernel to start counting and recording events specified by
62*288bf522SAndroid Build Coastguard Worker   // this file.
63*288bf522SAndroid Build Coastguard Worker   bool SetEnableEvent(bool enable);
64*288bf522SAndroid Build Coastguard Worker   bool SetFilter(const std::string& filter);
65*288bf522SAndroid Build Coastguard Worker 
66*288bf522SAndroid Build Coastguard Worker   bool ReadCounter(PerfCounter* counter);
67*288bf522SAndroid Build Coastguard Worker 
68*288bf522SAndroid Build Coastguard Worker   // Create mapped buffer used to receive records sent by the kernel.
69*288bf522SAndroid Build Coastguard Worker   // mmap_pages should be power of 2.
70*288bf522SAndroid Build Coastguard Worker   virtual bool CreateMappedBuffer(size_t mmap_pages, bool report_error);
71*288bf522SAndroid Build Coastguard Worker 
72*288bf522SAndroid Build Coastguard Worker   // Share the mapped buffer used by event_fd. The two EventFds should monitor
73*288bf522SAndroid Build Coastguard Worker   // the same event on the same cpu, but have different thread ids.
74*288bf522SAndroid Build Coastguard Worker   bool ShareMappedBuffer(const EventFd& event_fd, bool report_error);
75*288bf522SAndroid Build Coastguard Worker 
HasMappedBuffer()76*288bf522SAndroid Build Coastguard Worker   bool HasMappedBuffer() const { return mmap_data_buffer_size_ != 0; }
GetMappedBuffer(size_t & buffer_size)77*288bf522SAndroid Build Coastguard Worker   char* GetMappedBuffer(size_t& buffer_size) {
78*288bf522SAndroid Build Coastguard Worker     buffer_size = mmap_data_buffer_size_;
79*288bf522SAndroid Build Coastguard Worker     return mmap_data_buffer_;
80*288bf522SAndroid Build Coastguard Worker   }
81*288bf522SAndroid Build Coastguard Worker 
82*288bf522SAndroid Build Coastguard Worker   virtual void DestroyMappedBuffer();
83*288bf522SAndroid Build Coastguard Worker 
84*288bf522SAndroid Build Coastguard Worker   // Return available data in the kernel buffer.
85*288bf522SAndroid Build Coastguard Worker   std::vector<char> GetAvailableMmapData();
86*288bf522SAndroid Build Coastguard Worker   // Return the size of available data in the buffer, and set data_pos to the first available data
87*288bf522SAndroid Build Coastguard Worker   // position in mmap_data_buffer_.
88*288bf522SAndroid Build Coastguard Worker   virtual size_t GetAvailableMmapDataSize(size_t& data_pos);
89*288bf522SAndroid Build Coastguard Worker   // Discard the size of the data we have read, so the kernel can reuse the space for new data.
90*288bf522SAndroid Build Coastguard Worker   virtual void DiscardMmapData(size_t discard_size);
91*288bf522SAndroid Build Coastguard Worker 
92*288bf522SAndroid Build Coastguard Worker   // Manage the aux buffer, which receive auxiliary data sent by the kernel.
93*288bf522SAndroid Build Coastguard Worker   // aux_buffer_size: should be power of two, and mod PAGE_SIZE is zero.
94*288bf522SAndroid Build Coastguard Worker   virtual bool CreateAuxBuffer(size_t aux_buffer_size, bool report_error);
HasAuxBuffer()95*288bf522SAndroid Build Coastguard Worker   bool HasAuxBuffer() const { return aux_buffer_size_ != 0; }
96*288bf522SAndroid Build Coastguard Worker   virtual void DestroyAuxBuffer();
97*288bf522SAndroid Build Coastguard Worker 
98*288bf522SAndroid Build Coastguard Worker   // Get available aux data, which can appear in one or two continuous buffers.
99*288bf522SAndroid Build Coastguard Worker   // buf1: return pointer to the first buffer
100*288bf522SAndroid Build Coastguard Worker   // size1: return data size in the first buffer
101*288bf522SAndroid Build Coastguard Worker   // buf2: return pointer to the second buffer
102*288bf522SAndroid Build Coastguard Worker   // size2: return data size in the second buffer
103*288bf522SAndroid Build Coastguard Worker   // Return value: return how many bytes of aux data has been read before.
104*288bf522SAndroid Build Coastguard Worker   virtual uint64_t GetAvailableAuxData(char** buf1, size_t* size1, char** buf2, size_t* size2);
105*288bf522SAndroid Build Coastguard Worker   virtual void DiscardAuxData(size_t discard_size);
106*288bf522SAndroid Build Coastguard Worker 
107*288bf522SAndroid Build Coastguard Worker   // [callback] is called when there is data available in the mapped buffer.
108*288bf522SAndroid Build Coastguard Worker   virtual bool StartPolling(IOEventLoop& loop, const std::function<bool()>& callback);
109*288bf522SAndroid Build Coastguard Worker   virtual bool StopPolling();
110*288bf522SAndroid Build Coastguard Worker 
111*288bf522SAndroid Build Coastguard Worker  protected:
EventFd(const perf_event_attr & attr,int perf_event_fd,const std::string & event_name,pid_t tid,int cpu)112*288bf522SAndroid Build Coastguard Worker   EventFd(const perf_event_attr& attr, int perf_event_fd, const std::string& event_name, pid_t tid,
113*288bf522SAndroid Build Coastguard Worker           int cpu)
114*288bf522SAndroid Build Coastguard Worker       : attr_(attr),
115*288bf522SAndroid Build Coastguard Worker         perf_event_fd_(perf_event_fd),
116*288bf522SAndroid Build Coastguard Worker         id_(0),
117*288bf522SAndroid Build Coastguard Worker         event_name_(event_name),
118*288bf522SAndroid Build Coastguard Worker         tid_(tid),
119*288bf522SAndroid Build Coastguard Worker         cpu_(cpu),
120*288bf522SAndroid Build Coastguard Worker         mmap_addr_(nullptr),
121*288bf522SAndroid Build Coastguard Worker         mmap_len_(0),
122*288bf522SAndroid Build Coastguard Worker         mmap_metadata_page_(nullptr),
123*288bf522SAndroid Build Coastguard Worker         mmap_data_buffer_(nullptr),
124*288bf522SAndroid Build Coastguard Worker         mmap_data_buffer_size_(0),
125*288bf522SAndroid Build Coastguard Worker         ioevent_ref_(nullptr),
126*288bf522SAndroid Build Coastguard Worker         last_counter_value_(0) {}
127*288bf522SAndroid Build Coastguard Worker 
128*288bf522SAndroid Build Coastguard Worker   bool InnerReadCounter(PerfCounter* counter) const;
129*288bf522SAndroid Build Coastguard Worker 
130*288bf522SAndroid Build Coastguard Worker   const perf_event_attr attr_;
131*288bf522SAndroid Build Coastguard Worker   int perf_event_fd_;
132*288bf522SAndroid Build Coastguard Worker   mutable uint64_t id_;
133*288bf522SAndroid Build Coastguard Worker   const std::string event_name_;
134*288bf522SAndroid Build Coastguard Worker   pid_t tid_;
135*288bf522SAndroid Build Coastguard Worker   int cpu_;
136*288bf522SAndroid Build Coastguard Worker 
137*288bf522SAndroid Build Coastguard Worker   void* mmap_addr_;
138*288bf522SAndroid Build Coastguard Worker   size_t mmap_len_;
139*288bf522SAndroid Build Coastguard Worker   // the first page of mapped area, whose content can be changed by the kernel at any time
140*288bf522SAndroid Build Coastguard Worker   volatile perf_event_mmap_page* mmap_metadata_page_;
141*288bf522SAndroid Build Coastguard Worker   // starting from the second page of mapped area, containing records written by the kernel
142*288bf522SAndroid Build Coastguard Worker   char* mmap_data_buffer_;
143*288bf522SAndroid Build Coastguard Worker   size_t mmap_data_buffer_size_;
144*288bf522SAndroid Build Coastguard Worker   // receiving auxiliary data (like instruction tracing data generated by etm) from the kernel
145*288bf522SAndroid Build Coastguard Worker   char* aux_buffer_ = nullptr;
146*288bf522SAndroid Build Coastguard Worker   size_t aux_buffer_size_ = 0;
147*288bf522SAndroid Build Coastguard Worker 
148*288bf522SAndroid Build Coastguard Worker   IOEventRef ioevent_ref_;
149*288bf522SAndroid Build Coastguard Worker 
150*288bf522SAndroid Build Coastguard Worker   // Used by atrace to generate value difference between two ReadCounter() calls.
151*288bf522SAndroid Build Coastguard Worker   uint64_t last_counter_value_;
152*288bf522SAndroid Build Coastguard Worker 
153*288bf522SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(EventFd);
154*288bf522SAndroid Build Coastguard Worker };
155*288bf522SAndroid Build Coastguard Worker 
156*288bf522SAndroid Build Coastguard Worker bool IsEventAttrSupported(const perf_event_attr& attr, const std::string& event_name);
157*288bf522SAndroid Build Coastguard Worker 
158*288bf522SAndroid Build Coastguard Worker }  // namespace simpleperf
159*288bf522SAndroid Build Coastguard Worker 
160*288bf522SAndroid Build Coastguard Worker #endif  // SIMPLE_PERF_EVENT_FD_H_
161