Yabin Cui | 60a0ea9 | 2015-07-22 20:30:43 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2015 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_THREAD_TREE_H_ |
| 18 | #define SIMPLE_PERF_THREAD_TREE_H_ |
| 19 | |
Yabin Cui | 60a0ea9 | 2015-07-22 20:30:43 -0700 | [diff] [blame] | 20 | #include <stdint.h> |
Yabin Cui | c848560 | 2015-08-20 15:04:39 -0700 | [diff] [blame^] | 21 | |
| 22 | #include <limits> |
| 23 | #include <memory> |
Yabin Cui | 60a0ea9 | 2015-07-22 20:30:43 -0700 | [diff] [blame] | 24 | #include <set> |
Yabin Cui | c848560 | 2015-08-20 15:04:39 -0700 | [diff] [blame^] | 25 | |
Yabin Cui | 60a0ea9 | 2015-07-22 20:30:43 -0700 | [diff] [blame] | 26 | #include "dso.h" |
| 27 | |
| 28 | struct MapEntry { |
| 29 | uint64_t start_addr; |
| 30 | uint64_t len; |
| 31 | uint64_t pgoff; |
| 32 | uint64_t time; // Map creation time. |
Yabin Cui | c848560 | 2015-08-20 15:04:39 -0700 | [diff] [blame^] | 33 | Dso* dso; |
Yabin Cui | 60a0ea9 | 2015-07-22 20:30:43 -0700 | [diff] [blame] | 34 | }; |
| 35 | |
| 36 | struct MapComparator { |
| 37 | bool operator()(const MapEntry* map1, const MapEntry* map2) const; |
| 38 | }; |
| 39 | |
| 40 | struct ThreadEntry { |
| 41 | int pid; |
| 42 | int tid; |
| 43 | const char* comm; // It always refers to the latest comm. |
| 44 | std::set<MapEntry*, MapComparator> maps; |
| 45 | }; |
| 46 | |
| 47 | class ThreadTree { |
| 48 | public: |
Yabin Cui | c848560 | 2015-08-20 15:04:39 -0700 | [diff] [blame^] | 49 | ThreadTree() : unknown_symbol_("unknown", 0, std::numeric_limits<unsigned long long>::max()) { |
| 50 | unknown_dso_ = Dso::CreateDso(DSO_ELF_FILE, "unknown"); |
Yabin Cui | 60a0ea9 | 2015-07-22 20:30:43 -0700 | [diff] [blame] | 51 | unknown_map_ = MapEntry{ |
Yabin Cui | c848560 | 2015-08-20 15:04:39 -0700 | [diff] [blame^] | 52 | 0, // start_addr |
| 53 | std::numeric_limits<unsigned long long>::max(), // len |
| 54 | 0, // pgoff |
| 55 | 0, // time |
| 56 | unknown_dso_.get(), // dso |
Yabin Cui | 60a0ea9 | 2015-07-22 20:30:43 -0700 | [diff] [blame] | 57 | }; |
Yabin Cui | 60a0ea9 | 2015-07-22 20:30:43 -0700 | [diff] [blame] | 58 | } |
| 59 | |
| 60 | void AddThread(int pid, int tid, const std::string& comm); |
| 61 | void ForkThread(int pid, int tid, int ppid, int ptid); |
| 62 | ThreadEntry* FindThreadOrNew(int pid, int tid); |
| 63 | void AddKernelMap(uint64_t start_addr, uint64_t len, uint64_t pgoff, uint64_t time, |
| 64 | const std::string& filename); |
| 65 | void AddThreadMap(int pid, int tid, uint64_t start_addr, uint64_t len, uint64_t pgoff, |
| 66 | uint64_t time, const std::string& filename); |
| 67 | const MapEntry* FindMap(const ThreadEntry* thread, uint64_t ip, bool in_kernel); |
Yabin Cui | c848560 | 2015-08-20 15:04:39 -0700 | [diff] [blame^] | 68 | const Symbol* FindSymbol(const MapEntry* map, uint64_t ip); |
Yabin Cui | 60a0ea9 | 2015-07-22 20:30:43 -0700 | [diff] [blame] | 69 | const MapEntry* UnknownMap() const { |
| 70 | return &unknown_map_; |
| 71 | } |
| 72 | |
| 73 | private: |
Yabin Cui | c848560 | 2015-08-20 15:04:39 -0700 | [diff] [blame^] | 74 | Dso* FindKernelDsoOrNew(const std::string& filename); |
| 75 | Dso* FindUserDsoOrNew(const std::string& filename); |
Yabin Cui | 60a0ea9 | 2015-07-22 20:30:43 -0700 | [diff] [blame] | 76 | |
| 77 | std::unordered_map<int, std::unique_ptr<ThreadEntry>> thread_tree_; |
| 78 | std::vector<std::unique_ptr<std::string>> thread_comm_storage_; |
| 79 | |
| 80 | std::set<MapEntry*, MapComparator> kernel_map_tree_; |
| 81 | std::vector<std::unique_ptr<MapEntry>> map_storage_; |
| 82 | MapEntry unknown_map_; |
| 83 | |
Yabin Cui | c848560 | 2015-08-20 15:04:39 -0700 | [diff] [blame^] | 84 | std::unique_ptr<Dso> kernel_dso_; |
| 85 | std::unordered_map<std::string, std::unique_ptr<Dso>> module_dso_tree_; |
| 86 | std::unordered_map<std::string, std::unique_ptr<Dso>> user_dso_tree_; |
| 87 | std::unique_ptr<Dso> unknown_dso_; |
| 88 | Symbol unknown_symbol_; |
Yabin Cui | 60a0ea9 | 2015-07-22 20:30:43 -0700 | [diff] [blame] | 89 | }; |
| 90 | |
Yabin Cui | 73d8078 | 2015-07-23 21:39:57 -0700 | [diff] [blame] | 91 | struct Record; |
| 92 | |
Yabin Cui | f825889 | 2015-08-03 11:01:22 -0700 | [diff] [blame] | 93 | void BuildThreadTree(const Record& record, ThreadTree* thread_tree); |
Yabin Cui | 73d8078 | 2015-07-23 21:39:57 -0700 | [diff] [blame] | 94 | |
Yabin Cui | 60a0ea9 | 2015-07-22 20:30:43 -0700 | [diff] [blame] | 95 | #endif // SIMPLE_PERF_THREAD_TREE_H_ |