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
64 template <typename EntryT>
CompareTotalPeriod(const EntryT * sample1,const EntryT * sample2)65 int CompareTotalPeriod(const EntryT* sample1, const EntryT* sample2) {
66 uint64_t period1 = sample1->period + sample1->accumulated_period;
67 uint64_t period2 = sample2->period + sample2->accumulated_period;
68 return Compare(period2, period1);
69 }
70
71 // SampleComparator is a class using a collection of compare functions to
72 // compare two samples.
73
74 template <typename EntryT>
75 class SampleComparator {
76 public:
77 typedef int (*compare_sample_func_t)(const EntryT*, const EntryT*);
78
AddCompareFunction(compare_sample_func_t func)79 void AddCompareFunction(compare_sample_func_t func) {
80 compare_v_.push_back(func);
81 }
82
AddComparator(const SampleComparator<EntryT> & other)83 void AddComparator(const SampleComparator<EntryT>& other) {
84 compare_v_.insert(compare_v_.end(), other.compare_v_.begin(),
85 other.compare_v_.end());
86 }
87
operator()88 bool operator()(const EntryT* sample1, const EntryT* sample2) const {
89 for (const auto& func : compare_v_) {
90 int ret = func(sample1, sample2);
91 if (ret != 0) {
92 return ret < 0;
93 }
94 }
95 return false;
96 }
97
IsSameSample(const EntryT * sample1,const EntryT * sample2)98 bool IsSameSample(const EntryT* sample1, const EntryT* sample2) const {
99 for (const auto& func : compare_v_) {
100 if (func(sample1, sample2) != 0) {
101 return false;
102 }
103 }
104 return true;
105 }
106
empty()107 bool empty() const { return compare_v_.empty(); }
108
109 private:
110 std::vector<compare_sample_func_t> compare_v_;
111 };
112
113 #endif // SIMPLE_PERF_SAMPLE_COMPARATOR_H_
114