1 /* 2 * Copyright (C) 2018 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 SRC_TRACE_PROCESSOR_PROCESS_TRACKER_H_ 18 #define SRC_TRACE_PROCESSOR_PROCESS_TRACKER_H_ 19 20 #include <tuple> 21 22 #include "perfetto/base/string_view.h" 23 #include "src/trace_processor/trace_processor_context.h" 24 #include "src/trace_processor/trace_storage.h" 25 26 namespace perfetto { 27 namespace trace_processor { 28 29 class ProcessTracker { 30 public: 31 explicit ProcessTracker(TraceProcessorContext*); 32 ProcessTracker(const ProcessTracker&) = delete; 33 ProcessTracker& operator=(const ProcessTracker&) = delete; 34 virtual ~ProcessTracker(); 35 36 using UniqueProcessIterator = 37 std::multimap<uint32_t, UniquePid>::const_iterator; 38 using UniqueProcessBounds = 39 std::pair<UniqueProcessIterator, UniqueProcessIterator>; 40 41 using UniqueThreadIterator = 42 std::multimap<uint32_t, UniqueTid>::const_iterator; 43 using UniqueThreadBounds = 44 std::pair<UniqueThreadIterator, UniqueThreadIterator>; 45 46 // TODO(b/110409911): Invalidation of process and threads is yet to be 47 // implemented. This will include passing timestamps into the below methods 48 // to ensure the correct upid/utid is found. 49 50 // Called when a task_newtask is observed. This force the tracker to start 51 // a new UTID for the thread, which is needed for TID-recycling resolution. 52 UniqueTid StartNewThread(int64_t timestamp, 53 uint32_t tid, 54 StringId thread_name_id); 55 56 // Returns the thread utid (or creates a new entry if not present) 57 UniqueTid GetOrCreateThread(uint32_t tid); 58 59 // Called when a sched switch event is seen in the trace. Retrieves the 60 // UniqueTid that matches the tid or assigns a new UniqueTid and stores 61 // the thread_name_id. 62 UniqueTid UpdateThreadName(uint32_t tid, StringId thread_name_id); 63 64 // Called when a thread is seen the process tree. Retrieves the matching utid 65 // for the tid and the matching upid for the tgid and stores both. 66 // Virtual for testing. 67 virtual UniqueTid UpdateThread(uint32_t tid, uint32_t tgid); 68 69 // Called when a task_newtask without the CLONE_THREAD flag is observed. 70 // This force the tracker to start both a new UTID and a new UPID. 71 UniquePid StartNewProcess(int64_t timestamp, uint32_t pid); 72 73 // Called when a process is seen in a process tree. Retrieves the UniquePid 74 // for that pid or assigns a new one. 75 // Virtual for testing. 76 virtual UniquePid UpdateProcess(uint32_t pid, 77 base::Optional<uint32_t> ppid, 78 base::StringView name); 79 80 // Called when a process is seen in a process tree. Retrieves the UniquePid 81 // for that pid or assigns a new one. 82 // Virtual for testing. 83 virtual UniquePid GetOrCreateProcess(uint32_t pid); 84 85 // Returns the bounds of a range that includes all UniquePids that have the 86 // requested pid. UpidsForPid(uint32_t pid)87 UniqueProcessBounds UpidsForPid(uint32_t pid) { 88 return pids_.equal_range(pid); 89 } 90 91 // Returns the bounds of a range that includes all UniqueTids that have the 92 // requested tid. UtidsForTid(uint32_t tid)93 UniqueThreadBounds UtidsForTid(uint32_t tid) { 94 return tids_.equal_range(tid); 95 } 96 97 // Marks the two threads as belonging to the same process, even if we don't 98 // know which one yet. If one of the two threads is later mapped to a process, 99 // the other will be mapped to the same process. The order of the two threads 100 // is irrelevant, Associate(A, B) has the same effect of Associate(B, A). 101 void AssociateThreads(UniqueTid, UniqueTid); 102 103 private: 104 // Called whenever we discover that the passed thread belongs to the passed 105 // process. The |pending_assocs_| vector is scanned to see if there are any 106 // other threads associated to the passed thread. 107 void ResolvePendingAssociations(UniqueTid, UniquePid); 108 109 std::pair<UniquePid, TraceStorage::Process*> GetOrCreateProcessPtr( 110 uint32_t pid); 111 112 TraceProcessorContext* const context_; 113 114 // Each tid can have multiple UniqueTid entries, a new UniqueTid is assigned 115 // each time a thread is seen in the trace. 116 std::multimap<uint32_t /* tid */, UniqueTid> tids_; 117 118 // Each pid can have multiple UniquePid entries, a new UniquePid is assigned 119 // each time a process is seen in the trace. 120 std::map<uint32_t /* pid (aka tgid) */, UniquePid> pids_; 121 122 // Pending thread associations. The meaning of a pair<ThreadA, ThreadB> in 123 // this vector is: we know that A and B belong to the same process, but we 124 // don't know yet which process. A and A are idempotent, as in, pair<A,B> is 125 // equivalent to pair<B,A>. 126 std::vector<std::pair<UniqueTid, UniqueTid>> pending_assocs_; 127 }; 128 129 } // namespace trace_processor 130 } // namespace perfetto 131 132 #endif // SRC_TRACE_PROCESSOR_PROCESS_TRACKER_H_ 133