• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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