sample_tree.h revision 60a0ea96c0fb9e807c899759256df5e20bd904bd
1/* 2 * Copyright (C) 2015 The Android Open Source Project 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#ifndef SIMPLE_PERF_SAMPLE_TREE_H_ 18#define SIMPLE_PERF_SAMPLE_TREE_H_ 19 20#include <limits.h> 21#include <functional> 22#include <set> 23#include <string> 24#include <unordered_map> 25#include <vector> 26 27#include "callchain.h" 28#include "thread_tree.h" 29 30struct BranchFromEntry { 31 uint64_t ip; 32 const MapEntry* map; 33 const SymbolEntry* symbol; 34 uint64_t flags; 35 36 BranchFromEntry() : ip(0), map(nullptr), symbol(nullptr), flags(0) { 37 } 38}; 39 40struct SampleEntry { 41 uint64_t ip; 42 uint64_t time; 43 uint64_t period; 44 uint64_t accumulated_period; // Accumulated when appearing in other samples' callchain. 45 uint64_t sample_count; 46 const ThreadEntry* thread; 47 const char* thread_comm; // It refers to the thread comm when the sample happens. 48 const MapEntry* map; 49 const SymbolEntry* symbol; 50 BranchFromEntry branch_from; 51 CallChainRoot callchain; // A callchain tree representing all callchains in the sample records. 52 53 SampleEntry(uint64_t ip, uint64_t time, uint64_t period, uint64_t accumulated_period, 54 uint64_t sample_count, const ThreadEntry* thread, const MapEntry* map, 55 const SymbolEntry* symbol) 56 : ip(ip), 57 time(time), 58 period(period), 59 accumulated_period(accumulated_period), 60 sample_count(sample_count), 61 thread(thread), 62 thread_comm(thread->comm), 63 map(map), 64 symbol(symbol) { 65 } 66 67 // The data member 'callchain' can only move, not copy. 68 SampleEntry(SampleEntry&&) = default; 69 SampleEntry(SampleEntry&) = delete; 70}; 71 72typedef std::function<int(const SampleEntry&, const SampleEntry&)> compare_sample_func_t; 73 74class SampleTree { 75 public: 76 SampleTree(ThreadTree* thread_tree, compare_sample_func_t sample_compare_function) 77 : thread_tree_(thread_tree), 78 sample_comparator_(sample_compare_function), 79 sample_tree_(sample_comparator_), 80 sorted_sample_comparator_(sample_compare_function), 81 sorted_sample_tree_(sorted_sample_comparator_), 82 total_samples_(0), 83 total_period_(0) { 84 } 85 86 SampleEntry* AddSample(int pid, int tid, uint64_t ip, uint64_t time, uint64_t period, 87 bool in_kernel); 88 void AddBranchSample(int pid, int tid, uint64_t from_ip, uint64_t to_ip, uint64_t branch_flags, 89 uint64_t time, uint64_t period); 90 SampleEntry* AddCallChainSample(int pid, int tid, uint64_t ip, uint64_t time, uint64_t period, 91 bool in_kernel, const std::vector<SampleEntry*>& callchain); 92 void InsertCallChainForSample(SampleEntry* sample, const std::vector<SampleEntry*>& callchain, 93 uint64_t period); 94 void VisitAllSamples(std::function<void(const SampleEntry&)> callback); 95 96 uint64_t TotalSamples() const { 97 return total_samples_; 98 } 99 100 uint64_t TotalPeriod() const { 101 return total_period_; 102 } 103 104 private: 105 SampleEntry* InsertSample(SampleEntry& value); 106 SampleEntry* AllocateSample(SampleEntry& value); 107 108 struct SampleComparator { 109 bool operator()(SampleEntry* sample1, SampleEntry* sample2) const { 110 return compare_function(*sample1, *sample2) < 0; 111 } 112 SampleComparator(compare_sample_func_t compare_function) : compare_function(compare_function) { 113 } 114 115 compare_sample_func_t compare_function; 116 }; 117 118 struct SortedSampleComparator { 119 bool operator()(SampleEntry* sample1, SampleEntry* sample2) const { 120 uint64_t period1 = sample1->period + sample1->accumulated_period; 121 uint64_t period2 = sample2->period + sample2->accumulated_period; 122 if (period1 != period2) { 123 return period1 > period2; 124 } 125 return compare_function(*sample1, *sample2) < 0; 126 } 127 SortedSampleComparator(compare_sample_func_t compare_function) 128 : compare_function(compare_function) { 129 } 130 131 compare_sample_func_t compare_function; 132 }; 133 134 ThreadTree* thread_tree_; 135 SampleComparator sample_comparator_; 136 std::set<SampleEntry*, SampleComparator> sample_tree_; 137 SortedSampleComparator sorted_sample_comparator_; 138 std::set<SampleEntry*, SortedSampleComparator> sorted_sample_tree_; 139 std::vector<std::unique_ptr<SampleEntry>> sample_storage_; 140 141 uint64_t total_samples_; 142 uint64_t total_period_; 143}; 144 145#endif // SIMPLE_PERF_SAMPLE_TREE_H_ 146