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>
Compare(const T & a,const T & b)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, thread->pid);
54 BUILD_COMPARE_VALUE_FUNCTION(CompareTid, thread->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>
CompareTotalPeriod(const EntryT * sample1,const EntryT * sample2)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>
ComparePeriod(const EntryT * sample1,const EntryT * sample2)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
AddCompareFunction(compare_sample_func_t func)85 void AddCompareFunction(compare_sample_func_t func) {
86 compare_v_.push_back(func);
87 }
88
AddComparator(const SampleComparator<EntryT> & other)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
operator()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
IsSameSample(const EntryT * sample1,const EntryT * sample2)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
empty()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