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