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