1 /* 2 * Copyright (C) 2016 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_COMPARATOR_H_ 18 #define SIMPLE_PERF_SAMPLE_COMPARATOR_H_ 19 20 #include <string.h> 21 22 #include <vector> 23 24 // The compare functions below are used to compare two samples by their item 25 // content. 26 27 template <typename T> 28 int Compare(const T& a, const T& b) { 29 if (a != b) { 30 return a < b ? -1 : 1; 31 } 32 return 0; 33 } 34 35 #define BUILD_COMPARE_VALUE_FUNCTION(function_name, compare_part) \ 36 template <typename EntryT> \ 37 int function_name(const EntryT* sample1, const EntryT* sample2) { \ 38 return Compare(sample1->compare_part, sample2->compare_part); \ 39 } 40 41 #define BUILD_COMPARE_VALUE_FUNCTION_REVERSE(function_name, compare_part) \ 42 template <typename EntryT> \ 43 int function_name(const EntryT* sample1, const EntryT* sample2) { \ 44 return Compare(sample2->compare_part, sample1->compare_part); \ 45 } 46 47 #define BUILD_COMPARE_STRING_FUNCTION(function_name, compare_part) \ 48 template <typename EntryT> \ 49 int function_name(const EntryT* sample1, const EntryT* sample2) { \ 50 return strcmp(sample1->compare_part, sample2->compare_part); \ 51 } 52 53 BUILD_COMPARE_VALUE_FUNCTION(ComparePid, pid); 54 BUILD_COMPARE_VALUE_FUNCTION(CompareTid, tid); 55 BUILD_COMPARE_VALUE_FUNCTION_REVERSE(CompareSampleCount, sample_count); 56 BUILD_COMPARE_STRING_FUNCTION(CompareComm, thread_comm); 57 BUILD_COMPARE_STRING_FUNCTION(CompareDso, map->dso->Path().c_str()); 58 BUILD_COMPARE_STRING_FUNCTION(CompareSymbol, symbol->DemangledName()); 59 BUILD_COMPARE_STRING_FUNCTION(CompareDsoFrom, 60 branch_from.map->dso->Path().c_str()); 61 BUILD_COMPARE_STRING_FUNCTION(CompareSymbolFrom, 62 branch_from.symbol->DemangledName()); 63 BUILD_COMPARE_VALUE_FUNCTION(CompareCallGraphDuplicated, callchain.duplicated); 64 65 template <typename EntryT> 66 int CompareTotalPeriod(const EntryT* sample1, const EntryT* sample2) { 67 uint64_t period1 = sample1->period + sample1->accumulated_period; 68 uint64_t period2 = sample2->period + sample2->accumulated_period; 69 return Compare(period2, period1); 70 } 71 72 template <typename EntryT> 73 int ComparePeriod(const EntryT* sample1, const EntryT* sample2) { 74 return Compare(sample2->period, sample1->period); 75 } 76 77 // SampleComparator is a class using a collection of compare functions to 78 // compare two samples. 79 80 template <typename EntryT> 81 class SampleComparator { 82 public: 83 typedef int (*compare_sample_func_t)(const EntryT*, const EntryT*); 84 85 void AddCompareFunction(compare_sample_func_t func) { 86 compare_v_.push_back(func); 87 } 88 89 void AddComparator(const SampleComparator<EntryT>& other) { 90 compare_v_.insert(compare_v_.end(), other.compare_v_.begin(), 91 other.compare_v_.end()); 92 } 93 94 bool operator()(const EntryT* sample1, const EntryT* sample2) const { 95 for (const auto& func : compare_v_) { 96 int ret = func(sample1, sample2); 97 if (ret != 0) { 98 return ret < 0; 99 } 100 } 101 return false; 102 } 103 104 bool IsSameSample(const EntryT* sample1, const EntryT* sample2) const { 105 for (const auto& func : compare_v_) { 106 if (func(sample1, sample2) != 0) { 107 return false; 108 } 109 } 110 return true; 111 } 112 113 bool empty() const { return compare_v_.empty(); } 114 115 private: 116 std::vector<compare_sample_func_t> compare_v_; 117 }; 118 119 #endif // SIMPLE_PERF_SAMPLE_COMPARATOR_H_ 120