1// Copyright 2006 The Android Open Source Project
2
3#ifndef PARSE_OPTIONS_INL_H
4#define PARSE_OPTIONS_INL_H
5
6// Define a typedef for TraceReaderType and include "parse_options.h"
7// before including this header file in a C++ source file.
8//
9// For example:
10//
11// struct symbol {
12//   int  elapsed;
13// };
14//
15// typedef TraceReader<symbol> TraceReaderType;
16
17
18typedef TraceReaderType::symbol_type symbol_type;
19typedef TraceReaderType::region_type region_type;
20typedef TraceReaderType::ProcessState ProcessState;
21
22symbol_type *kernel_sym;
23symbol_type *library_sym;
24
25// Returns true if the given event is included (or not excluded)
26// from the list of valid events specified by the user on the
27// command line.
28inline bool IsValidEvent(BBEvent *event, symbol_type *sym)
29{
30  if (include_some_pids && pid_include_vector.GetBit(event->pid) == 0)
31      return false;
32  if (exclude_some_pids && pid_exclude_vector.GetBit(event->pid))
33      return false;
34  if (include_some_procedures) {
35    if (sym == NULL || included_procedures.Find(sym->name) == 0)
36      return false;
37  }
38  if (exclude_some_procedures) {
39    if (sym == NULL || excluded_procedures.Find(sym->name))
40      return false;
41  }
42  return true;
43}
44
45inline bool IsValidPid(int pid) {
46  if (include_some_pids && pid_include_vector.GetBit(pid) == 0)
47    return false;
48  if (exclude_some_pids && pid_exclude_vector.GetBit(pid))
49    return false;
50  return true;
51}
52
53inline symbol_type *GetSymbol(TraceReaderType *trace, int pid, uint32_t addr,
54                              uint64_t time)
55{
56  symbol_type *sym = trace->LookupFunction(pid, addr, time);
57
58  if (lump_kernel && (sym->region->flags & region_type::kIsKernelRegion)) {
59    if (kernel_sym == NULL) {
60      kernel_sym = sym;
61      sym->name = ":kernel";
62    } else {
63      sym = kernel_sym;
64    }
65  }
66
67  if (lump_libraries && (sym->region->flags & region_type::kIsLibraryRegion)) {
68    if (library_sym == NULL) {
69      library_sym = sym;
70      sym->name = ":libs";
71    } else {
72      sym = library_sym;
73    }
74  }
75
76  return sym;
77}
78
79inline bool IsIncludedProcedure(symbol_type *sym)
80{
81  if (include_kernel_syms && (sym->region->flags & region_type::kIsKernelRegion))
82    return true;
83  if (include_library_syms && (sym->region->flags & region_type::kIsLibraryRegion))
84    return true;
85  return included_procedures.Find(sym->name);
86}
87
88inline bool IsExcludedProcedure(symbol_type *sym)
89{
90  if (exclude_kernel_syms && (sym->region->flags & region_type::kIsKernelRegion))
91    return true;
92  if (exclude_library_syms && (sym->region->flags & region_type::kIsLibraryRegion))
93    return true;
94  return excluded_procedures.Find(sym->name);
95}
96
97// Returns true on end-of-file.
98inline bool GetNextValidEvent(TraceReaderType *trace,
99                              BBEvent *event,
100                              BBEvent *first_ignored_event,
101                              symbol_type **sym_ptr)
102{
103  symbol_type *sym = NULL;
104  first_ignored_event->time = 0;
105  if (trace->ReadBB(event))
106    return true;
107  bool recheck = true;
108  while (recheck) {
109    recheck = false;
110    if (include_some_pids) {
111      while (pid_include_vector.GetBit(event->pid) == 0) {
112        if (first_ignored_event->time == 0)
113          *first_ignored_event = *event;
114        if (trace->ReadBB(event))
115          return true;
116      }
117    } else if (exclude_some_pids) {
118      while (pid_exclude_vector.GetBit(event->pid)) {
119        if (first_ignored_event->time == 0)
120          *first_ignored_event = *event;
121        if (trace->ReadBB(event))
122          return true;
123      }
124    }
125
126    if (include_some_procedures) {
127      sym = GetSymbol(trace, event->pid, event->bb_addr, event->time);
128      while (!IsIncludedProcedure(sym)) {
129        if (first_ignored_event->time == 0)
130          *first_ignored_event = *event;
131        if (trace->ReadBB(event))
132          return true;
133        recheck = true;
134        sym = GetSymbol(trace, event->pid, event->bb_addr, event->time);
135      }
136    } else if (exclude_some_procedures) {
137      sym = GetSymbol(trace, event->pid, event->bb_addr, event->time);
138      while (IsExcludedProcedure(sym)) {
139        if (first_ignored_event->time == 0)
140          *first_ignored_event = *event;
141        if (trace->ReadBB(event))
142          return true;
143        recheck = true;
144        sym = GetSymbol(trace, event->pid, event->bb_addr, event->time);
145      }
146    }
147  }
148  if (sym == NULL)
149    sym = GetSymbol(trace, event->pid, event->bb_addr, event->time);
150
151  *sym_ptr = sym;
152  return false;
153}
154
155#endif  // PARSE_OPTIONS_INL_H
156