runtime/nanoscope_sampler.h (51 lines of code) (raw):

/* * Copyright (C) 2018 Uber Technologies, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ART_RUNTIME_NANOSCOPE_SAMPLER_H_ #define ART_RUNTIME_NANOSCOPE_SAMPLER_H_ #include "runtime.h" #include <sys/mman.h> #include <sys/syscall.h> #if defined(__ANDROID__) #include <linux/perf_event.h> #include <sys/ioctl.h> #endif #define SIGTIMER (SIGPROF) namespace art{ // Right now we have 3 counters: # of major page faults, # of minor page // faults, # of context switches. enum CounterType { COUNTER_TYPE_MAJOR_PAGE_FAULTS = 0, COUNTER_TYPE_MINOR_PAGE_FAULTS, COUNTER_TYPE_CONTEXT_SWITCHES, // =============================== COUNTER_TYPE_LIMIT // total number of counters }; // Data structures defined to read perf_event counters in sighandler struct read_format { uint64_t nr; struct { uint64_t value; uint64_t id; } values[COUNTER_TYPE_LIMIT]; }; const unsigned long PERF_PAGE_SIZE = sysconf(_SC_PAGESIZE); enum SampleMode { kSampleDisabled, // Sampling disabled kSamplePerf, // perf_timer mode, use perf_event as sampling timer kSampleCpu // cpu_timer mpde, use timer_settime as sampling timer }; class NanoscopeSampler{ public: static void StartSampling(Thread* t, SampleMode sample_mode); static void StopSampling(); private: // Thread with sampling enabled. Use static field so we can access it in signal handler static Thread* sampling_thread_; // Use perf_event to generate sampling signal (perf_timer mode) or use timer_settime (cpu_timer mode) or sampling disabled static SampleMode sample_mode_; #if defined(__ANDROID__) // Sampling interval in ns static int64_t sample_interval_; // fd of perf_event counter that acts as a timer. Only in perf_timer mode static int perf_timer_fd_; // mmap-ed page used by perf_event counter that acts as a timer. Only in perf_timer mode static struct perf_event_mmap_page* perf_timer_page_; // id of timer_settime. Only in cpu_timer mode static timer_t timer_id_; // fds of perf_event counters used to gather sampling data. static int sample_fd_[COUNTER_TYPE_LIMIT]; // Set up signal handler for SIGPROF static void signal_handler(int sigo ATTRIBUTE_UNUSED, siginfo_t *siginfo ATTRIBUTE_UNUSED, void *ucontext ATTRIBUTE_UNUSED); // Install the correct sighandler static void install_sig_handler(); // Set up perf_event counters used to gather sampling data static void set_up_sample_counter(CounterType counter_type, int groupfd); #endif // Set up the sampling signal timer based on the timer mode static void set_up_timer(); }; } #endif // ART_RUNTIME_NANOSCOPE_SAMPLER_H_